整合JDBC
-
导入依赖:
spring-boot-starter-jdbc
```
org.springframework.boot
spring-boot-starter-jdbc
``` -
导入依赖:
mysql -connector-j
```
```
com.mysql
mysql-connector-j
-
配置文件
```
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/ry
username: root
password: root
hikari:
maximum-pool-size: 10
minimum-idle: 5
```
整合 Mybatis-Plus
Mybatis-Plus与Mybatis的区别
Mybatis-Plus是一个基于Mybatis的增强工具库,旨在简化开发并提高效率
-
CURD操作: Mybatis-Plus通过继承
BaseMapper
接口,提供了一系列内置的快捷方法,使得CURD更加简单,无需编写重复的SQL语句 -
代码生成器: Mybatis-Plus提供了代码生成器功能,可以根据数据库表结构自动生成实体类、Mapper接口以及XML映射文件,减少了手动编写的工作量。
-
通用方法封装: Mybatis-Plus封装了许多常用方法,如:条件构造器、排序、分页查询等,简化了开发过程,提高了效率
-
分页插件: Mybatis-Plus内置了分页插件,支持各种数据库的分页查询
-
注解支持: Mybatis-Plus引入了更多的注解支持,使得开发者可以通过注解来配置实体与数据库表之间的映射关系,减少了XML配置文件的编写
-
性能分析: Mybatis-Plus内置了性能分析插件,可输出SQL语句以及其执行时间
导入依赖
```
com.baomidou
mybatis-plus-boot-starter
3.5.4
com.mysql
mysql-connector-j
```
MybatisX 插件
Mapper接口方法
使用Mybatis-Plus,mapper会继承
BaseMapper
接口,封装了最常见的CURD方法
-
添加方法
- 插入一条新数据,忽略非空字段
int insert(T entity)
-
删除方法
-
根据主键删除
int deleteById(Serializable id)
-
根据主键批量删除
int deleteBatchIds(Collection extends Serializable> idList)
-
根据字段条件删除
int deleteByMap(Map
columnMap)
- 插入一条新数据,忽略非空字段
-
更新方法
-
根据主键更新
int updateById(@Param("et") T entity)
-
根据条件更新
int update(@Param("et") T entity, @Param("ew") Wrapper
updateWrapper)
-
-
查询方法
-
根据主键查询
T selectById(Serializable id)
-
根据主键批量查询
List
selectBatchIds(Collection extends Serializable> idList) -
根据 Map 条件查询
List
selectByMap(Map columnMap) -
根据条件查询列表
List
selectList(@Param("ew") Wrapper queryWrapper) -
分页查询
IPage
selectPage(IPage page, @Param("ew") Wrapper queryWrapper)
-
说明:
T 是实体类泛型,代表数据库表的映射对象
Serializable id 是实体类的主键类型
Wrapper 是条件构造器,用于动态生成 SQL 条件
IPage 是分页参数接口,结合分页插件实现分页查询
Wrapper
条件构造器 ,用于构建复杂的数据库查询条件
主要的Wrapper类及其功能
-
AbstractWrapper: 用于查询条件封装,生成 sql 的 where 条件
-
QueryWrapper: Entity 对象封装操作类,不是用lambda语法
-
UpdateWrapper: Update 条件封装,用于Entity对象更新操作
-
LamdbaQueryWrapper: 通过 Lambda 表达式来引用实体类的属性
-
LamdbaUpdateWrapper: 通过Lambda 表达式的更新条件构造器
Service接口方法
使用Mybatis-Plus,Service会继承
IService
接口,封装了对BaseMapper
的进一步抽象(IService内部调用BaseMapper的方法)
-
添加方法
-
保存一条记录,忽略非空字段
boolean save(T entity)
-
批量插入记录,提高插入效率
boolean saveBatch(Collection
entityList)
-
-
删除方法
-
根据主键删除
boolean removeById(Serializable id)
-
根据主键批量删除
boolean removeBatchIds(Collection extends Serializable> idList)
-
根据Map条件删除
boolean removeByMap(Map
columnMap)
-
-
更新方法
-
根据主键更新
boolean updateById(T entity)
-
根据条件更新
boolean update(T entity, Wrapper
updateWrapper) -
批量更新记录,支持根据主键更新多个实体
boolean updateBatchById(Collection
entityList)
-
-
查询方法
-
根据主键查询单条记录
T getById(Serializable id)
-
根据主键批量查询多个主键对应的记录
List
listByIds(Collection extends Serializable> idList) -
根据 Map 条件查询
List
listByMap(Map columnMap) -
根据条件查询列表
List
list(Wrapper queryWrapper) -
分页查询
IPage
page(IPage page, Wrapper queryWrapper)
-
分页
Mybatis-Plus中有自带的分页插件PaginationInnerInterceptor
,支持多种数据库
3.5.7版本的mybatis-plus-boot-starter 不用导入分页插件也可以使用.启动器版本做了调整。
3.5.9 起, PaginationInnerInterceptor 已分离出来。如需使用,则需单独引入 mybatisplus-jsqlparser 依赖 。
属性介绍
属性名 | 类型 | 默认值 | 描述 |
---|---|---|---|
overflow | boolean | false | 溢出总页数后是否进行处理 |
maxLimit | Long | 单页分页条数限制 | |
dbType | DbType | 数据库类型 | |
dialect | IDialect | 方言实现类 |
自定义分页
Page 类继承了 IPage 类,实现了简单分页模型。如果你需要实现自己的分页模型,可以继承 Page 类或实现 IPage 类
属性名 | 类型 | 默认值 | 描述 |
---|---|---|---|
records | List | emptyList | 查询数据列表 |
total | Long | 0 | 查询列表总记录数 |
size | Long | 10 | 每页显示条数,默认 10 |
current | Long | 1 | 当前页 |
orders | List | emptyList | 排序字段信息 |
optimizeCountSql | boolean | true | 自动优化 COUNT SQL |
optimizeJoinOfCountSql | boolean | true | 自动优化 COUNT SQL 是否把 join 查询部分移除 |
searchCount | boolean | true | 是否进行 count 查询 |
maxLimit | Long | 单页分页条数限制 | |
countId | String | XML 自定义 count 查询的 statementId |
SQL检测工具(p6spy)
p6spy 是一个针对数据库访问进行拦截和记录的工具,它通过代理JDBC驱动程序来工作
功能
-
慢SQL检测: 通过配置
outagedetection
和outagedetectioninterval
,p6spy可以记录执行时间超过设定阈值的SQL语句 -
自定义日志格式: 通过
logMessageFormat
,你可以自定义SQL日志的输出格式,包括时间戳、执行时间、SQL语句等 -
日志输出控制:
appender
配置项允许你选择日志输出到控制台、文件或日志系统
配置
pom.xml
```
com.github.gavlyukovskiy
p6spy-spring-boot-starter
1.10.0
```
application.yaml
```
spring:
datasource:
driver-class-name: com.p6spy.engine.spy.P6SpyDriver
url: jdbc:p6spy:h2:mem:test
# 其他数据库配置...
```
spy.properties
```
# 模块列表,根据版本选择合适的配置
modulelist=com.baomidou.mybatisplus.extension.p6spy.MybatisPlusLogFactory,com.p6spy.engine.outage.P6OutageFactory
# 自定义日志格式
logMessageFormat=com.baomidou.mybatisplus.extension.p6spy.P6SpyLogger
# 日志输出到控制台
appender=com.baomidou.mybatisplus.extension.p6spy.StdoutLogger
# 取消JDBC驱动注册
deregisterdrivers=true
# 使用前缀
useprefix=true
# 排除的日志类别
excludecategories=info,debug,result,commit,resultset
# 日期格式
dateformat=yyyy-MM-dd HH:mm:ss
# 实际驱动列表
# driverlist=org.h2.Driver
# 开启慢SQL记录
outagedetection=true
# 慢SQL记录标准(单位:秒)
outagedetectioninterval=2
# 过滤 flw_ 开头的表 SQL 打印
filter=true
exclude=flw_*
```
注意:
driver-class-name应配置为p6spy提供的驱动类。
url前缀应为jdbc:p6spy,后跟实际的数据库连接地址。
如果打印的SQL为null,请在excludecategories中增加commit。
如果批量操作不打印SQL,请去除excludecategories中的batch。
对于批量操作打印重复的问题,请使用MybatisPlusLogFactory(3.2.1新增)。
该插件可能会带来性能损耗,不建议在生产环境中使用。
逻辑删除
通过在数据库中标记记录为“已删除”而非物理删除,来保留数据的历史痕迹,同时确保查询结果的整洁性
工作原理
-
插入: 逻辑删除字段的值不受限制。
-
查找: 自动添加条件,过滤掉标记为已删除的记录。
-
更新: 防止更新已删除的记录。
-
删除: 将删除操作转换为更新操作,标记记录为已删除。
支持的数据类型
逻辑删除字段支持所有数据类型,但推荐使用 Integer、Boolean 或 LocalDateTime。 如果使用 datetime 类型
使用方法
-
配置全局逻辑删除属性
application.yaml```
mybatis-plus:
global-config:
db-config:
logic-delete-field: deleted # 全局逻辑删除字段名
logic-delete-value: 1 # 逻辑已删除值
logic-not-delete-value: 0 # 逻辑未删除值
``` -
在实体类中使用 @TableLogic 注解
```
import com.baomidou.mybatisplus.annotation.TableLogic;
public class User {
// 其他字段...@TableLogic private Integer deleted;
}
```
自动填充字段
在插入或更新数据时自动填充某些字段,如创建时间、更新时间等,通过实现
com.baomidou.mybatisplus.core.handlers.MetaObjectHandler
接口来实现
使用
-
定义实体类
在实体类中,使用@TableField
注解标记需要自动填充的字段,并指定填充的策略```
public class User {
@TableField(fill = FieldFill.INSERT)
private String createTime;@TableField(fill = FieldFill.UPDATE) private String updateTime; // 其他字段...
}
``` -
实现 MetaObjectHandler
创建一个类来实现 MetaObjectHandler 接口,并重写 insertFill 和 updateFill 方法```
@Slf4j
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {@Override public void insertFill(MetaObject metaObject) { log.info("开始插入填充..."); this.strictInsertFill(metaObject, "createTime", LocalDateTime.class, LocalDateTime.now()); } @Override public void updateFill(MetaObject metaObject) { log.info("开始更新填充..."); this.strictUpdateFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now()); }
}
``` -
配置自动填充处理器
确保自定义的MyMetaObjectHandler
类被Spring管理,可以通过@Component
或@Bean
注解来实现
注意:
自动填充是直接给实体类的属性设置值。
如果属性没有值,入库时会是 null。
MetaObjectHandler 提供的默认方法策略是:如果属性有值则不覆盖,如果填充值为 null 则不填充。
字段必须声明 @TableField 注解,并设置 fill 属性来选择填充策略。
填充处理器需要在 Spring Boot 中声明为 @Component 或 @Bean。
在 update(T entity, Wrapper updateWrapper) 时,entity 不能为空,否则自动填充失效。
在 update(Wrapper updateWrapper) 时不会自动填充,需要手动赋值字段条件。
乐观锁
MyBatis-Plus 提供了
OptimisticLockerInnerInterceptor
插件,使得在应用中实现乐观锁变得简单
关于乐观锁可以看 Java并发 —— 线程并发(二)
实现原理
-
读取记录时,获取当前的版本号(version)。
-
在更新记录时,将这个版本号一同传递。
-
执行更新操作时,设置 version = newVersion 的条件为 version = oldVersion。
-
如果版本号不匹配,则更新失败。
实现
-
配置插件
-
Spring XML方式
```
``` -
注解方式
```
@Configuration
@MapperScan("按需修改")
public class MybatisPlusConfig {@Bean public MybatisPlusInterceptor mybatisPlusInterceptor() { MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor()); return interceptor; }
}
```
-
-
在实体类字段上添加 @Version 注解
```
import com.baomidou.mybatisplus.annotation.Version;
public class YourEntity {
@Version
private Integer version;
// 其他字段...
}
```