mybatis-plus

  1. 使用mybatis-plus一般用于做单表的增删改查,如果希望去做多表的连查,也可以自定义方法,自定义SQL去执行。
  2. [MyBatis-Plus (opens new window)](https://github.com/baomidou/mybatis-plus)(简称 MP)是一个 [MyBatis (opens new window)](http://www.mybatis.org/mybatis-3/)的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。
  3. 对于单表的增删改查,mybatis-plus封装了对应的方法,直接调用即可实现对应的功能,无需编写SQL语句。

自动填充

1、导入依赖

  1. <dependencies>
  2. <dependency>
  3. <groupId>org.springframework</groupId>
  4. <artifactId>spring-jdbc</artifactId>
  5. <version>5.2.8.RELEASE</version>
  6. </dependency>
  7. <dependency>
  8. <groupId>org.springframework</groupId>
  9. <artifactId>spring-context</artifactId>
  10. <version>5.2.8.RELEASE</version>
  11. </dependency>
  12. <dependency>
  13. <groupId>com.alibaba</groupId>
  14. <artifactId>druid</artifactId>
  15. <version>1.1.22</version>
  16. </dependency>
  17. <dependency>
  18. <groupId>mysql</groupId>
  19. <artifactId>mysql-connector-java</artifactId>
  20. <version>5.1.43</version>
  21. </dependency>
  22. <dependency>
  23. <groupId>org.projectlombok</groupId>
  24. <artifactId>lombok</artifactId>
  25. <version>1.18.18</version>
  26. </dependency>
  27. <dependency>
  28. <groupId>com.baomidou</groupId>
  29. <artifactId>mybatis-plus</artifactId>
  30. <version>3.0.5</version>
  31. </dependency>
  32. <dependency>
  33. <groupId>junit</groupId>
  34. <artifactId>junit</artifactId>
  35. <version>4.12</version>
  36. </dependency>
  37. </dependencies>

2、创建mapper层接口,接口需要继承BaseMapper接口,BaseMapper接口的泛型指定了当前mapper处理的数据类型

  1. public interface UserMapper extends BaseMapper<User> {
  2. }

3、编写实体类User

  1. @Data
  2. @TableName("t_user")//如果表名与类名不一致,使用@TableName指定当前实体类映射的数据库表名
  3. public class User {
  4. @TableId(type = IdType.AUTO)//指定主键生成策略
  5. private Long id;
  6. private String name;
  7. private Integer age;
  8. private String email;
  9. @TableField(fill = FieldFill.INSERT)//指定自动填充策略
  10. private Date gmtCreate;
  11. @TableField(fill = FieldFill.INSERT_UPDATE)
  12. private Date gmtModified;
  13. }

4、mybatisplus通过MetaObjectHandler来处理自动填充,需要实现MetaObjectHandler接口

  1. public class AutoFillUtil implements MetaObjectHandler {
  2. /**
  3. * 新增时自动填充
  4. * @param metaObject
  5. */
  6. @Override
  7. public void insertFill(MetaObject metaObject) {
  8. this.setFieldValByName("gmtCreate",new Date(),metaObject);
  9. this.setFieldValByName("gmtModified",new Date(),metaObject);
  10. }
  11. /**
  12. * 修改时自动填充
  13. * @param metaObject
  14. */
  15. @Override
  16. public void updateFill(MetaObject metaObject) {
  17. this.setFieldValByName("gmtModified",new Date(),metaObject);
  18. }
  19. }

5、编写spring的配置文件

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xmlns:context="http://www.springframework.org/schema/context"
  5. xsi:schemaLocation="http://www.springframework.org/schema/beans
  6. http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
  7. <context:component-scan base-package="com.woniuxy"/>
  8. <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
  9. <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
  10. <property name="url" value="jdbc:mysql:///mybatisplus?characterEncoding=utf-8&amp;useSSL=false"/>
  11. <property name="username" value="root"/>
  12. <property name="password" value="root"/>
  13. </bean>
  14. <!-- 配置mybatisplus的sqlsessionfactorybean -->
  15. <bean id="sqlSessionFactory" class="com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean">
  16. <property name="dataSource" ref="dataSource"/>
  17. <!--指定mybatisplus的全局配置-->
  18. <property name="globalConfig" ref="globalConfig"/>
  19. </bean>
  20. <!--进行mybatisplus全局配置-->
  21. <bean id="globalConfig" class="com.baomidou.mybatisplus.core.config.GlobalConfig">
  22. <!--配置metaObjectHandler,用于实现自动填充-->
  23. <property name="metaObjectHandler">
  24. <bean class="com.woniuxy.utils.AutoFillUtil"/>
  25. </property>
  26. </bean>
  27. <bean id="mapperScannerConfigurer" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
  28. <property name="basePackage" value="com.woniuxy.mapper"/>
  29. </bean>
  30. </beans>

6、测试

  1. public class MybatisPlusTest {
  2. private UserMapper userMapper;
  3. @Before
  4. public void init(){
  5. ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
  6. userMapper=applicationContext.getBean("userMapper",UserMapper.class);
  7. }
  8. @Test
  9. public void test(){
  10. List<User> users = userMapper.selectList(null);//查询所有
  11. System.out.println(users);
  12. }
  13. @Test
  14. public void testAdd(){
  15. User entity = new User();
  16. entity.setName("王五");
  17. entity.setAge(35);
  18. entity.setEmail("3@3.3");
  19. System.out.println(entity);
  20. userMapper.insert(entity);//执行新增
  21. System.out.println(entity);
  22. }
  23. }

乐观锁

  1. 乐观锁 : 对一切操作保持乐观,它总是认为不会出现问题,无论干什么不去上锁!如果出现了问题,

再次更新值测试 。

  1. 悲观锁:对一切操作保持悲观,它总是认为会出现问题,无论干什么都会上锁!再去操作!
  2. 乐观锁实现方式:

1.数据库表中应该有version字段,用于记录当前数据的版本

2.从数据库中取出记录时,获取当前 version

3.更新时,带上获得的version

4.执行更新时, set version = newVersion where version = oldVersion ,如果version不对,就更新失败。

实现步骤:

1、修改数据库表,增加version字段

2、修改实体类,增加version属性,且在属性上加@Version注解

3、修改spring配置文件,在MybatisSqlSessionFactoryBean的plugins中增加加上乐观锁插件。

  1. <!-- 配置mybatisplus的sqlsessionfactorybean -->
  2. <bean id="sqlSessionFactory" class="com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean">
  3. <property name="dataSource" ref="dataSource"/>
  4. <!--指定mybatisplus的全局配置-->
  5. <property name="globalConfig" ref="globalConfig"/>
  6. <!--配置乐观锁插件-->
  7. <property name="plugins">
  8. <array>
  9. <bean class="com.baomidou.mybatisplus.extension.plugins.OptimisticLockerInterceptor"/>
  10. </array>
  11. </property>
  12. <!-- 配置mybatis的日志记录,输出在控制台 -->
  13. <property name="configuration">
  14. <bean class="com.baomidou.mybatisplus.core.MybatisConfiguration">
  15. <property name="logImpl" value="org.apache.ibatis.logging.stdout.StdOutImpl"/>
  16. </bean>
  17. </property>
  18. </bean>

3、测试

  1. /**
  2. * 测试乐观锁
  3. */
  4. @Test
  5. public void testUpdate(){
  6. //线程1:想把ID为6的人改成张三丰
  7. User user1 = userMapper.selectById(6L);//根据id查询记录
  8. user1.setName("张三丰");
  9. //线程2插队了:把ID为6的人改成张无忌
  10. User user2=userMapper.selectById(6L);
  11. user2.setName("张无忌");
  12. //线程2插队成功,执行了修改
  13. userMapper.updateById(user2);//根据ID修改数据库记录。
  14. userMapper.updateById(user1);//线程1开始执行修改
  15. }

逻辑删除

  1. 逻辑删除:如果配置了逻辑删除,则此时的删除操作都不会真正去执行delete语句,而是执行update
  2. 注意:逻辑删除操作在mybatisplus高版本中,已被移除。

实现步骤

1、数据库表中添加字段deleted 默认值给个0,表示未删除状态,

2、在实体类中添加属性deleted,属性上加@TableLogic注解,表示启用逻辑删除

3、修改spring配置文件,在globalConfig配置sqlInjector,值使用LogicSqlInjector

  1. <bean id="globalConfig" class="com.baomidou.mybatisplus.core.config.GlobalConfig">
  2. <!--配置metaObjectHandler,用于实现自动填充-->
  3. <property name="metaObjectHandler">
  4. <bean class="com.woniuxy.utils.AutoFillUtil"/>
  5. </property>
  6. <!--配置逻辑删除-->
  7. <property name="sqlInjector">
  8. <bean class="com.baomidou.mybatisplus.extension.injector.LogicSqlInjector"/>
  9. </property>
  10. </bean>

4、测试

  1. /**
  2. * 测试逻辑删除
  3. */
  4. @Test
  5. public void testLogicDelete(){
  6. userMapper.deleteById(1402517259338924034L);
  7. }

分页插件

  1. 配置分页插件:mybatis-plus自带分页插件,不需要单独导入外部依赖。

实现步骤

1、配置分页插件

  1. <!-- 配置mybatisplus的sqlsessionfactorybean -->
  2. <bean id="sqlSessionFactory" class="com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean">
  3. <property name="dataSource" ref="dataSource"/>
  4. <!--指定mybatisplus的全局配置-->
  5. <property name="globalConfig" ref="globalConfig"/>
  6. <!--配置插件-->
  7. <property name="plugins">
  8. <array>
  9. <!--分页插件-->
  10. <bean class="com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor"/>
  11. <!--乐观锁插件-->
  12. <bean class="com.baomidou.mybatisplus.extension.plugins.OptimisticLockerInterceptor"/>
  13. </array>
  14. </property>
  15. <!-- 配置mybatis在控制台输出SQL -->
  16. <property name="configuration">
  17. <bean class="com.baomidou.mybatisplus.core.MybatisConfiguration">
  18. <property name="logImpl" value="org.apache.ibatis.logging.stdout.StdOutImpl"/>
  19. </bean>
  20. </property>
  21. </bean>

2、创建page对象,用于封装分页查询后得到的结果,并设置分页查询的条件,调用selectPage方法完成分页查询

  1. /**
  2. * 测试分页查询
  3. */
  4. @Test
  5. public void testPageQuery(){
  6. //创建page对象,该对象创建时可以设置分页条件,
  7. // 最终使用该对象来接收分页查询后得到的结果
  8. Page<User> userPage = new Page<>(2,3);
  9. //调用分页查询方法
  10. userMapper.selectPage(userPage,null);
  11. System.out.println(userPage.getTotal());//获取总记录数
  12. System.out.println(userPage.getCurrent());//获取当前页码
  13. System.out.println(userPage.getSize());//获取每页记录数
  14. List<User> records = userPage.getRecords();//获取分页查询后的数据
  15. records.forEach(System.out::println);
  16. }

自动代码生成

导入依赖

  1. <dependencies>
  2. <!--mybatisplus自动代码生成时,需要基于velocity模板进行生成-->
  3. <dependency>
  4. <groupId>org.apache.velocity</groupId>
  5. <artifactId>velocity</artifactId>
  6. <version>1.7</version>
  7. </dependency>
  8. <!-- mp生成实体类时使用swagger2的注解,需要引入对应依赖 -->
  9. <dependency>
  10. <groupId>io.springfox</groupId>
  11. <artifactId>springfox-swagger2</artifactId>
  12. <version>2.9.2</version>
  13. </dependency>
  14. <dependency>
  15. <groupId>io.springfox</groupId>
  16. <artifactId>springfox-swagger-ui</artifactId>
  17. <version>2.9.2</version>
  18. </dependency>
  19. <dependency>
  20. <groupId>com.baomidou</groupId>
  21. <artifactId>mybatis-plus</artifactId>
  22. <version>3.0.5</version>
  23. </dependency>
  24. <dependency>
  25. <groupId>com.alibaba</groupId>
  26. <artifactId>druid</artifactId>
  27. <version>1.1.22</version>
  28. </dependency>
  29. <dependency>
  30. <groupId>mysql</groupId>
  31. <artifactId>mysql-connector-java</artifactId>
  32. <version>5.1.43</version>
  33. </dependency>
  34. <dependency>
  35. <groupId>org.springframework</groupId>
  36. <artifactId>spring-context</artifactId>
  37. <version>5.2.8.RELEASE</version>
  38. </dependency>
  39. <dependency>
  40. <groupId>org.springframework</groupId>
  41. <artifactId>spring-jdbc</artifactId>
  42. <version>5.2.8.RELEASE</version>
  43. </dependency>
  44. <dependency>
  45. <groupId>org.projectlombok</groupId>
  46. <artifactId>lombok</artifactId>
  47. <version>1.18.18</version>
  48. </dependency>
  49. <dependency>
  50. <groupId>junit</groupId>
  51. <artifactId>junit</artifactId>
  52. <version>4.12</version>
  53. </dependency>
  54. </dependencies>

编写自动代码生成的工具类,进行相应的配置

  1. /**
  2. * 代码自动生成器
  3. */
  4. public class MybatisPlusAutoCode {
  5. public static void main(String[] args) {
  6. //构建代码自动生成器对象
  7. AutoGenerator autoGenerator = new AutoGenerator();
  8. //配置自动生成策略
  9. // 1、全局配置:
  10. //https://baomidou.com/config/generator-config.html#%E5%85%A8%E5%B1%80%E7%AD%96%E7%95%A5-globalconfig-%E9%85%8D%E7%BD%AE
  11. GlobalConfig gc = new GlobalConfig();
  12. String projectPath = System.getProperty("user.dir"); //获取当前项目所在目录
  13. gc.setOutputDir(projectPath+"/20210610/src/main/java"); //自定义代码生成后的存放目录
  14. gc.setAuthor("hujianying"); //设置项目作者
  15. gc.setOpen(false); //代码生成后是否打开文件夹
  16. gc.setFileOverride(false); //是否覆盖
  17. gc.setServiceName("%sService"); //去Service的I前缀
  18. gc.setIdType(IdType.ID_WORKER); //自定义主键生成策略
  19. gc.setDateType(DateType.ONLY_DATE); //自定义日期类型
  20. gc.setSwagger2(true); //实体使用swagger2注解
  21. autoGenerator.setGlobalConfig(gc); //添加全局配置
  22. //2、设置数据源:
  23. // https://baomidou.com/config/generator-config.html#%E6%95%B0%E6%8D%AE%E6%BA%90-datasourceconfig-%E9%85%8D%E7%BD%AE
  24. DataSourceConfig dsc = new DataSourceConfig();
  25. dsc.setUrl("jdbc:mysql://localhost:3306/mall?characterEncoding=utf-8");
  26. dsc.setDriverName("com.mysql.jdbc.Driver");
  27. dsc.setUsername("root");
  28. dsc.setPassword("root");
  29. dsc.setDbType(DbType.MYSQL); //指定数据库类型
  30. autoGenerator.setDataSource(dsc); //添加数据源配置
  31. //3、包名配置:
  32. // https://baomidou.com/config/generator-config.html#%E5%8C%85%E5%90%8D%E9%85%8D%E7%BD%AE
  33. PackageConfig pc = new PackageConfig();
  34. //pc.setModuleName("rbac"); //指定生成的模块名称
  35. pc.setParent("com.woniuxy"); //设置模块中的父目录名
  36. pc.setEntity("model"); //设置实体类目录名
  37. pc.setMapper("mapper"); //设置mapper目录名
  38. pc.setService("service"); //设置service目录名
  39. pc.setController("controller"); //设置controller目录名
  40. autoGenerator.setPackageInfo(pc);
  41. //4、数据库表配置:
  42. // https://baomidou.com/config/generator-config.html#%E6%95%B0%E6%8D%AE%E5%BA%93%E8%A1%A8%E9%85%8D%E7%BD%AE
  43. StrategyConfig strategy = new StrategyConfig();
  44. // 设置要生成的实体类对应映射的表名
  45. strategy.setInclude("t_goods","t_cart","t_user","t_order","t_order_item");
  46. strategy.setTablePrefix("t_"); //去除表名前缀
  47. //设置表名生成策略,下划线转驼峰
  48. strategy.setNaming(NamingStrategy.underline_to_camel);
  49. //设置列名生成策略,下划线转驼峰
  50. strategy.setColumnNaming(NamingStrategy.underline_to_camel);
  51. strategy.setEntityLombokModel(true); //自动lombok;
  52. //strategy.setLogicDeleteFieldName("deleted"); //设置使用逻辑删除策略的属性名
  53. // 自动填充配置 TableFill
  54. //TableFill gmtCreate = new TableFill("gmt_create", FieldFill.INSERT);
  55. //TableFill gmtModified = new TableFill("gmt_modified", FieldFill.INSERT_UPDATE);
  56. //ArrayList<TableFill> tableFills = new ArrayList<>();
  57. //tableFills.add(gmtCreate);
  58. //tableFills.add(gmtModified);
  59. //strategy.setTableFillList(tableFills);
  60. //strategy.setVersionFieldName("version"); // 乐观锁
  61. strategy.setRestControllerStyle(true); //生成 @RestController 控制器
  62. strategy.setControllerMappingHyphenStyle(true); //驼峰转连字符--->localhost:8080/hello_id_2
  63. autoGenerator.setStrategy(strategy);
  64. //执行自动生成
  65. autoGenerator.execute();
  66. }
  67. }