整合JDBC
- 导入依赖:
spring-boot-starter-jdbc
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-jdbc</artifactId> </dependency>
- 导入依赖:
mysql -connector-j
<dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId> </dependency
- 配置文件
spring:datasource:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/ryusername: rootpassword: roothikari:maximum-pool-size: 10minimum-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语句以及其执行时间
导入依赖
<dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5.4</version>
</dependency><dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId>
</dependency>
MybatisX 插件
Mapper接口方法
使用Mybatis-Plus,mapper会继承
BaseMapper
接口,封装了最常见的CURD方法
-
添加方法
- 插入一条新数据,忽略非空字段
int insert(T entity)
- 插入一条新数据,忽略非空字段
-
删除方法
-
根据主键删除
int deleteById(Serializable id)
-
根据主键批量删除
int deleteBatchIds(Collection<? extends Serializable> idList)
-
根据字段条件删除
int deleteByMap(Map<String, Object> columnMap)
-
-
更新方法
-
根据主键更新
int updateById(@Param("et") T entity)
-
根据条件更新
int update(@Param("et") T entity, @Param("ew") Wrapper<T> updateWrapper)
-
-
查询方法
-
根据主键查询
T selectById(Serializable id)
-
根据主键批量查询
List<T> selectBatchIds(Collection<? extends Serializable> idList)
-
根据 Map 条件查询
List<T> selectByMap(Map<String, Object> columnMap)
-
根据条件查询列表
List<T> selectList(@Param("ew") Wrapper<T> queryWrapper)
-
分页查询
IPage<T> selectPage(IPage<T> page, @Param("ew") Wrapper<T> 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<T> entityList)
-
-
删除方法
-
根据主键删除
boolean removeById(Serializable id)
-
根据主键批量删除
boolean removeBatchIds(Collection<? extends Serializable> idList)
-
根据Map条件删除
boolean removeByMap(Map<String, Object> columnMap)
-
-
更新方法
-
根据主键更新
boolean updateById(T entity)
-
根据条件更新
boolean update(T entity, Wrapper<T> updateWrapper)
-
批量更新记录,支持根据主键更新多个实体
boolean updateBatchById(Collection<T> entityList)
-
-
查询方法
-
根据主键查询单条记录
T getById(Serializable id)
-
根据主键批量查询多个主键对应的记录
List<T> listByIds(Collection<? extends Serializable> idList)
-
根据 Map 条件查询
List<T> listByMap(Map<String, Object> columnMap)
-
根据条件查询列表
List<T> list(Wrapper<T> queryWrapper)
-
分页查询
IPage<T> page(IPage<T> page, Wrapper<T> 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
<dependency><groupId>com.github.gavlyukovskiy</groupId><artifactId>p6spy-spring-boot-starter</artifactId><version>1.10.0</version>
</dependency>
application.yaml
spring:datasource:driver-class-name: com.p6spy.engine.spy.P6SpyDriverurl: 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.yamlmybatis-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 {// 其他字段... @TableLogicprivate 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 {@Overridepublic void insertFill(MetaObject metaObject) {log.info("开始插入填充...");this.strictInsertFill(metaObject, "createTime", LocalDateTime.class, LocalDateTime.now());}@Overridepublic 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方式
<bean id="optimisticLockerInnerInterceptor" class="com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor"/><bean id="mybatisPlusInterceptor" class="com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor"><property name="interceptors"><list><ref bean="optimisticLockerInnerInterceptor"/></list></property> </bean>
-
注解方式
@Configuration @MapperScan("按需修改") public class MybatisPlusConfig {@Beanpublic MybatisPlusInterceptor mybatisPlusInterceptor() {MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());return interceptor;} }
-
-
在实体类字段上添加 @Version 注解
import com.baomidou.mybatisplus.annotation.Version;public class YourEntity {@Versionprivate Integer version;// 其他字段... }