• 【编程不良人】Mybatis-Plus整合SpringBoot学习笔记


    1. Mybatis-Plus简介

    配套视频:【编程不良人】Mybatis-Plus整合SpringBoot实战教程,提高的你开发效率,后端人员必备!_哔哩哔哩_bilibili

    官网:MyBatis-Plus

    2. MyBatis-Plus环境搭建

    配套视频:2.环境搭建&helloworld_哔哩哔哩_bilibili

    2.1 创建SpringBoot项目并在pom.xml中引入依赖

     
     
         com.baomidou
         mybatis-plus-boot-starter
         3.2.0
     
     ​
     
     
         com.alibaba
         druid
         1.1.19
     

           注意:不需要再引入mybatis的相关依赖,只引入mybatis-plus这一个即可,当然数据库相关的驱动还需要显式引入。

    2.2 启动类/入口类添加@Mapper注解扫描dao包

     package com.study;
     ​
     import org.mybatis.spring.annotation.MapperScan;
     import org.springframework.boot.SpringApplication;
     import org.springframework.boot.autoconfigure.SpringBootApplication;
     ​
     @SpringBootApplication
     @MapperScan("com.study.dao")//这种方式比@Mapper注解扫描更灵活
     public class SpringbootMybatisplusApplication {
         public static void main(String[] args) {
             SpringApplication.run(SpringbootMybatisplusApplication.class, args);
         }
     }

    2.3 application.properties编写mybatis-plus及日志相关配置

     # 配置mybatis-plus,mapper文件位置、实体类别名设置均可省略不写
     spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
     spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
     spring.datasource.url=jdbc:mysql://localhost:3306/mybatis-plus?characterEncoding=UTF-8
     spring.datasource.username=root
     spring.datasource.password=root
     ​
     # 日志配置
     logging.level.root=info
     logging.level.com.study.dao=debug

    2.4 创建数据库及表结构

     DROP TABLE IF EXISTS `user`;
     CREATE TABLE `user` (
       `id` int(11) NOT NULL AUTO_INCREMENT,
       `name` varchar(255) DEFAULT NULL,
       `age` int(11) DEFAULT NULL,
         `bir` timestamp null default null,
       PRIMARY KEY (`id`)
     ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
     ​
     SET FOREIGN_KEY_CHECKS = 1;
     ​
     INSERT INTO `user` VALUES (1,'小崔',27,'2022-08-01');

    2.5 开发实体类

    • User.java

     package com.study.entity;
     ​
     import lombok.AllArgsConstructor;
     import lombok.Data;
     import lombok.NoArgsConstructor;
     import lombok.ToString;
     import lombok.experimental.Accessors;
     ​
     import java.util.Date;
     ​
     /**
      * @ClassName User
      * @Description TODO
      * @Author Jiangnan Cui
      * @Date 2022/8/13 23:08
      * @Version 1.0
      */
     @Data //getter、setter
     @AllArgsConstructor //有参构造
     @NoArgsConstructor //无参构造
     @ToString //toString
     @Accessors(chain = true)//开启链式调用
     public class User {
         private String id;
         private String name;
         private Integer age;
         private Date bir;
     }

    2.6 开发dao接口(即mapper通用实现,无需再写XxxMapper.xml对应实现)

    • IUserDao.java

     package com.study.dao;
     ​
     import com.baomidou.mybatisplus.core.mapper.BaseMapper;
     import com.study.entity.User;
     ​
     /**
      * @ClassName IUserDao
      * @Description TODO
      * @Author Jiangnan Cui
      * @Date 2022/8/13 23:12
      * @Version 1.0
      */
     //使用mybatis-plus去增强接口,BaseMapper中提供了各种CRUD方法
     public interface IUserDao extends BaseMapper {
     }
     ​

    2.7 测试

    • IUserDaoTest

     package com.study.test;
     ​
     import com.study.dao.IUserDao;
     import com.study.entity.User;
     import org.junit.jupiter.api.Test;
     import org.springframework.beans.factory.annotation.Autowired;
     import org.springframework.boot.test.context.SpringBootTest;
     ​
     import java.util.List;
     ​
     /**
      * @ClassName IUserDaoTest
      * @Description TODO
      * @Author Jiangnan Cui
      * @Date 2022/8/13 23:15
      * @Version 1.0
      */
     @SpringBootTest
     public class IUserDaoTest {
         @Autowired
         private IUserDao userDao;
         /**
          * @MethodName findAllTest
          * @Description 测试查询所有   
          * @Author Jiangnan Cui
          * @Date 23:44 2022/8/13
          */
         @Test
         public void findAllTest(){
             List users = userDao.selectList(null);
             users.forEach(user-> System.out.println("user = " + user));
         }
     }

    运行结果:

     2022-08-13 23:30:42.647  INFO 21744 --- [           main] com.study.test.IUserDaoTest              : Started IUserDaoTest in 1.849 seconds (JVM running for 2.58)
     2022-08-13 23:30:42.946  INFO 21744 --- [           main] com.alibaba.druid.pool.DruidDataSource   : {dataSource-1} inited
     2022-08-13 23:30:43.105 DEBUG 21744 --- [           main] com.study.dao.IUserDao.selectList        : ==>  Preparing: SELECT id,name,bir,age FROM user 
     2022-08-13 23:30:43.125 DEBUG 21744 --- [           main] com.study.dao.IUserDao.selectList        : ==> Parameters: 
     2022-08-13 23:30:43.147 DEBUG 21744 --- [           main] com.study.dao.IUserDao.selectList        : <==      Total: 1
     user = User(id=1, name=小崔, age=27, bir=Mon Aug 01 00:00:00 CST 2022)

    3. 常用注解

    配套视频:3.常用的注解_哔哩哔哩_bilibili

    注解链接:注解 | MyBatis-Plus

    3.1 @TableName注解

     描述: 用来将实体对象与数据库表名完成映射
     ​
     修饰范围: 用在类上
     ​
     常见属性:
         value: String类型,指定映射的表名
         resultMap: String类型,用来指定XML配置中resultMap的id值
     ​
     举例:数据库中表t_user与实体类User
         @Data //getter、setter
         @AllArgsConstructor //有参构造
         @NoArgsConstructor //无参构造
         @ToString //toString
         @Accessors(chain = true)//开启链式调用
         @TableName(value = "t_user") //默认将类名作为表名
         public class User {
             private String id;
             private String name;
             private Integer age;
         }

    3.2 @TableId注解

     描述:主键注解
     ​
     修饰范围: 用在属性上
     ​
     常见属性:
         value: String类型,指定实体类中与表中对应的主键列名
         type: 枚举类型,指定主键生成类型
     ​
     举例:id作为自增主键
         @Data //getter、setter
         @AllArgsConstructor //有参构造
         @NoArgsConstructor //无参构造
         @ToString //toString
         @Accessors(chain = true)//开启链式调用
         @TableName(value = "t_user") //默认将类名作为表名
         public class User {
             @TableId(value = "id",type = IdType.AUTO)
             private String id;
             private String name;
             private Integer age;
             private Date bir;
         }

    3.3 @TableFileld注解

     描述:字段注解(非主键)
     ​
     修饰范围: 用在属性上
     ​
     常用属性:
         value:  String类型, 用来指定对应的数据库表中的字段名
         el:String类型,映射为原生#{...}逻辑,相当于写在xml里的#{}部分,3.0版本不存在
         exist:boolean类型,是否为数据库表字段 true代表是数据库字段,false代表不是
         
     举例:
         @Data //getter、setter
         @AllArgsConstructor //有参构造
         @NoArgsConstructor //无参构造
         @ToString //toString
         @Accessors(chain = true)//开启链式调用
         @TableName(value = "t_user") //默认将类名作为表名
         public class User {
             
             @TableId(value = "id",type = IdType.AUTO)
             private String id;
     ​
             @TableField(value = "username")//将数据库表中字段与实体类字段进行映射
             private String name;
            
             private Integer age;
             private Date bir;
     ​
             @TableField(exist = false)//不映射数据库表中的任何字段
             private String aaa;
         }
     ​
     补充:
         select:表示是否查询该字段
         fill:表示是否自动填充,将对象存入数据库的时候,由 MyBatis 
         Plus:自动给某些字段赋值,create_time、update_time
     ​
     1、给表添加 create_time、update_time 字段
     ​
     2、实体类中添加成员变量
     import com.baomidou.mybatisplus.annotation.FieldFill;
     import com.baomidou.mybatisplus.annotation.TableField;
     import com.baomidou.mybatisplus.annotation.TableId;
     import com.baomidou.mybatisplus.annotation.TableName;
     import lombok.Data;
     import java.util.Date;
     ​
     @Data
     @TableName(value = "user")
     public class User {
         @TableId
         private String id;
         @TableField(value = "name",select = false)
         private String title;
         private Integer age;
         @TableField(exist = false)
         private String gender;
         @TableField(fill = FieldFill.INSERT)
         private Date createTime;
         @TableField(fill = FieldFill.INSERT_UPDATE)
         private Date updateTime;
     }
     ​
     3、创建自动填充处理器
     import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
     import org.apache.ibatis.reflection.MetaObject;
     import org.springframework.stereotype.Component;
     import java.util.Date;
     ​
     @Component
     public class MyMetaObjectHandler implements MetaObjectHandler {
         @Override
         public void insertFill(MetaObject metaObject) {
             this.setFieldValByName("createTime",new Date(),metaObject);
             this.setFieldValByName("updateTime",new Date(),metaObject);
         }
     ​
         @Override
         public void updateFill(MetaObject metaObject) {
             this.setFieldValByName("updateTime",new Date(),metaObject);
         }
     }
     ​

    其余注解参考:注解 | MyBatis-Plus

    也可参考:从前慢- Mybatis-Plus_unique_perfect的博客-CSDN博客_mybatis plus unique

    4. 常见方法的使用(CRUD)

    配套视频:4.常见方法的使用_哔哩哔哩_bilibili

    • IUserDaoTest.java

     package com.study.test;
     ​
     import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
     import com.study.dao.IUserDao;
     import com.study.entity.User;
     import org.junit.jupiter.api.Test;
     import org.springframework.beans.factory.annotation.Autowired;
     import org.springframework.boot.test.context.SpringBootTest;
     ​
     import java.util.Date;
     import java.util.List;
     ​
     /**
      * @ClassName IUserDaoTest
      * @Description TODO
      * @Author Jiangnan Cui
      * @Date 2022/8/13 23:15
      * @Version 1.0
      */
     @SpringBootTest
     public class IUserDaoTest {
         @Autowired
         private IUserDao userDao;
         /**
          * @MethodName findAllTest
          * @Description 测试查询所有
          * @Author Jiangnan Cui
          * @Date 23:44 2022/8/13
          */
         @Test
         public void findAllTest(){
             List users = userDao.selectList(null);
             users.forEach(user-> System.out.println("user = " + user));
         }
     ​
         /**
          * @MethodName findByIdTest
          * @Description 根据主键id查询一个
          * @Author Jiangnan Cui
          * @Date 0:29 2022/8/14
          */
         @Test
         public void findByIdTest(){
             User user = userDao.selectById(2);
             System.out.println("user = " + user);
         }
         
         /**
          * @MethodName findTest
          * @Description 条件查询  
          * @Author Jiangnan Cui
          * @Date 0:30 2022/8/14
          */
         @Test
         public void findTest(){
             QueryWrapper queryWrapper = new QueryWrapper<>();
             //queryWrapper.eq("age",28);//设置等值查询
             //queryWrapper.lt("age",28);//设置小于查询
             //queryWrapper.gt("age",28);//设置大于查询
             //queryWrapper.ge("age",28);//设置大于等于查询
             queryWrapper.le("age",28);//设置小于等于查询
             List users = userDao.selectList(queryWrapper);
             users.forEach(user -> System.out.println("user = " + user));
         }
     ​
         /**
          * @MethodName findLikeTest
          * @Description 模糊查询
          * @Author Jiangnan Cui
          * @Date 0:43 2022/8/14
          */
         @Test
         public void findLikeTest(){
             QueryWrapper queryWrapper = new QueryWrapper<>();
             //queryWrapper.like("name","崔");//like: %?% 中间包含
             //queryWrapper.likeLeft("name","王");//likeLeft: %? 以xxx结尾
             queryWrapper.likeRight("name","老");//likeRight: ?% 以xxx开头
             List users = userDao.selectList(queryWrapper);
             for (User user : users) {
                 System.out.println("user = " + user);
             }
         }
     ​
         /**
          * @MethodName addTest
          * @Description 新增用户
          * @Author Jiangnan Cui
          * @Date 0:57 2022/8/14
          */
         @Test
         public void addTest(){
             User user = new User();
             user.setName("王二小").setAge(18).setBir(new Date());
             userDao.insert(user);
         }
     ​
         /**
          * @MethodName updateByIdTest
          * @Description 基于主键id进行修改
          * @Author Jiangnan Cui
          * @Date 0:58 2022/8/14
          */
         @Test
         public void updateByIdTest(){
             User user = userDao.selectById(3);
             user.setName("大漂亮");
             userDao.updateById(user);
         }
     ​
         /**
          * @MethodName updateBatchTest
          * @Description 批量修改
          * @Author Jiangnan Cui
          * @Date 1:01 2022/8/14
          */
         @Test
         public void updateBatchTest(){
             User user = new User();
             user.setName("大聪明");
             QueryWrapper updateWrapper = new QueryWrapper<>();
             updateWrapper.eq("age",28);//将年龄为28岁的名字修改为大聪明
             userDao.update(user,updateWrapper);
         }
     ​
         /**
          * @MethodName deleteByIdTest
          * @Description 基于主键id进行删除
          * @Author Jiangnan Cui
          * @Date 1:10 2022/8/14
          */
         @Test
         public void deleteByIdTest(){
             userDao.deleteById(6);
         }
     ​
         /**
          * @MethodName deleteTest
          * @Description 基于条件删除
          * @Author Jiangnan Cui
          * @Date 1:11 2022/8/14
          */
         @Test
         public void deleteTest(){
             QueryWrapper queryWrapper = new QueryWrapper<>();
             queryWrapper.eq("age",28);
             userDao.delete(queryWrapper);
         }
         
     }
     ​

    5. 分页查询

    配套视频:5.分页查询_哔哩哔哩_bilibili

    官方参考链接:分页插件 | MyBatis-Plus

    5.1 预先配置

    注意:

    1. 使用分页查询必须设置mybatis-plus提供的分页插件进行分页结果拦截,才能实现分页效果。

    2. 目前分页查询仅仅支持单表查询,不能在表连接时使用分页插件,表连接时需要在XxxDao接口中写方法,在XxxDaoMapper.xml中写对应实现。

    • MybatisPlusConfig.java

     package com.study.config;
     ​
     import com.baomidou.mybatisplus.annotation.DbType;
     import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
     import org.mybatis.spring.annotation.MapperScan;
     import org.springframework.context.annotation.Bean;
     import org.springframework.context.annotation.Configuration;
     import org.springframework.transaction.annotation.EnableTransactionManagement;
     ​
     /**
      * @ClassName MybatisPlusConfig
      * @Description TODO
      * @Author Jiangnan Cui
      * @Date 2022/8/14 10:23
      * @Version 1.0
      */
     @EnableTransactionManagement //开启事务管理
     @Configuration
     @MapperScan("com.study.dao")//扫描dao接口所在包
     public class MybatisPlusConfig {
         //分页的拦截器对象
         @Bean
         public PaginationInterceptor paginationInterceptor() {
             PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
             return paginationInterceptor;
         }
     }

    5.2 无条件分页查询

     /**
      * @MethodName pageTest
      * @Description 无条件分页查询
      * @Author Jiangnan Cui
      * @Date 10:16 2022/8/14
      */
     @Test
     public void pageTest(){
         //参数1:表示当前页数,默认显示第1页   
         //参数2:表示每页显示记录数,默认显示10条
         IPage page = new Page<>(1,2);
         IPage userIPage = userDao.selectPage(page, null);
         long total = userIPage.getTotal();
         System.out.println("总记录数 = " + total);
         for (User record : userIPage.getRecords()) {
             System.out.println("record = " + record);
         }
     }

    5.3 有条件分页查询

     /**
      * @MethodName pageConditionTest
      * @Description 有条件查询
      * @Author Jiangnan Cui
      * @Date 10:33 2022/8/14
      */
     @Test
     public void pageConditionTest(){
         //先定义分页条件
         QueryWrapper queryWrapper = new QueryWrapper<>();
         queryWrapper.eq("age",69);
         //再分页显示
         IPage page = new Page<>(1,2);
         IPage userIPage = userDao.selectPage(page, queryWrapper);
         long total = userIPage.getTotal();
         System.out.println("total = " + total);
         userIPage.getRecords().forEach(user-> System.out.println("user = " + user));
     }

    6. 多数据源配置实现读写分离

    配套视频:6.多数据源配置实现读写分离_哔哩哔哩_bilibili

           为了确保数据库产品的稳定性,很多数据库拥有双机热备功能。 也就是,第一台数据库服务器,是对外提供增删改业务的生产服务器; 第二台数据库服务器,主要进行读的操作。

    6.1 pom.xml引入dynamic-datasource-spring-boot-starter依赖

     
     
         com.baomidou
         dynamic-datasource-spring-boot-starter
         3.0.0
     

    6.2 application.properties配置数据源

     ## 配置mybatis-plus,mapper文件位置、实体类别名设置均可省略不写
     #spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
     #spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
     #spring.datasource.url=jdbc:mysql://localhost:3306/mybatis-plus?characterEncoding=UTF-8
     #spring.datasource.username=root
     #spring.datasource.password=root
     ​
     # 一主一从举例
     # 指定默认数据源
     spring.datasource.primary=master  
     ​
     # 主数据源 master,默认执行增删改操作
     spring.datasource.dynamic.datasource.master.driver-class-name=com.mysql.jdbc.Driver
     spring.datasource.dynamic.datasource.master.url=jdbc:mysql://localhost:3306/mybatis-plus?characterEncoding=UTF-8
     spring.datasource.dynamic.datasource.master.username=root
     spring.datasource.dynamic.datasource.master.password=root
     ​
     # 从数据源 salve_1,执行查询操作
     spring.datasource.dynamic.datasource.slave_1.driver-class-name=com.mysql.jdbc.Driver
     spring.datasource.dynamic.datasource.slave_1.url=jdbc:mysql://localhost:3306/mybatis-plus-1?characterEncoding=UTF-8
     spring.datasource.dynamic.datasource.slave_1.username=root
     spring.datasource.dynamic.datasource.slave_1.password=root

    6.3 创建多个数据库模拟不同的mysql服务

    注意:测试时可新建一个名为mybatis-plus-1的数据库,将mybatis-plus中的表复制过去,进行测试。

    DS注解

     作用: 用来切换数据源的注解 
     修饰范围: 方法上和类上均可使用,同时存在时方法注解优先于类上注解(局部优先)。
     Value属性: 切换数据源名称

    开发业务层

    • IUserService.java

     package com.study.service;
     ​
     import com.study.entity.User;
     ​
     import java.util.List;
     ​
     /**
      * @ClassName IUserService
      * @Description TODO
      * @Author Jiangnan Cui
      * @Date 2022/8/14 10:59
      * @Version 1.0
      */
     public interface IUserService {
         /**
          * @MethodName findAll
          * @Description 查询所有
          * @return: java.util.List
          * @Author Jiangnan Cui
          * @Date 11:00 2022/8/14
          */
         List findAll();
     ​
         /**
          * @MethodName save
          * @Description 新增用户
          * @param: user
          * @Author Jiangnan Cui
          * @Date 11:00 2022/8/14
          */
         void save(User user);
     }
     ​
    • IUserServiceImpl.java 实现类

     package com.study.service;
     ​
     import com.baomidou.dynamic.datasource.annotation.DS;
     import com.study.dao.IUserDao;
     import com.study.entity.User;
     import org.springframework.beans.factory.annotation.Autowired;
     import org.springframework.stereotype.Service;
     import org.springframework.transaction.annotation.Transactional;
     ​
     import java.util.List;
     ​
     /**
      * @ClassName IUserServiceImpl
      * @Description TODO
      * @Author Jiangnan Cui
      * @Date 2022/8/14 11:01
      * @Version 1.0
      */
     @Service
     @Transactional
     public class IUserServiceImpl implements IUserService{
         @Autowired
         private IUserDao userDao;
     ​
         @Override
         @DS("slave_1") //指定从数据源执行查询操作
         public List findAll() {
             return userDao.selectList(null);
         }
     ​
         @Override //默认主数据源执行增删改操作
         public void save(User user) {
             userDao.insert(user);
         }
     }

    测试

    • IUserServiceTest.java

     package com.study.test;
     ​
     import com.study.entity.User;
     import com.study.service.IUserService;
     import org.junit.jupiter.api.Test;
     import org.springframework.beans.factory.annotation.Autowired;
     import org.springframework.boot.test.context.SpringBootTest;
     ​
     import java.util.Date;
     import java.util.List;
     ​
     /**
      * @ClassName IUserServiceTest
      * @Description TODO
      * @Author Jiangnan Cui
      * @Date 2022/8/14 11:04
      * @Version 1.0
      */
     @SpringBootTest
     public class IUserServiceTest {
         @Autowired
         private IUserService userService;
     ​
         /**
          * @MethodName findAllTest
          * @Description 测试查询所有   
          * @Author Jiangnan Cui
          * @Date 11:21 2022/8/14
          */
         @Test
         public void findAllTest(){
             List users = userService.findAll();
             for (User user : users) {
                 System.out.println("user = " + user);
             }
         }
     ​
         /**
          * @MethodName saveTest
          * @Description 测试新增用户   
          * @Author Jiangnan Cui
          * @Date 11:21 2022/8/14
          */
         @Test
         public void saveTest(){
             User user = new User();
             user.setName("小灰灰").setAge(5).setBir(new Date());
             userService.save(user);
         }
     }

           通过结果可以发现,从数据源可以执行查询操作,新增用户的数据出现在主数据源,但主从数据未同步,此处还需要配置,后续会逐渐完善,因此此处只是演示主从机工作过程,并不涉及主从同步。

    6.4 项目最终结构

    ​​​​​​​

     

    7. 补充

    以下摘自:从前慢- Mybatis-Plus_unique_perfect的博客-CSDN博客_mybatis plus unique

    7.1 查询方法

     /**
      * @MethodName testSelectBatchIds
      * @Description 根据多个id进行批量查询,返回list查
      * @Author Jiangnan Cui
      * @Date 11:31 2022/8/14
      */
     @Test
     public void testSelectBatchIds(){
         //根据多个id进行批量查询
         List users = userDao.selectBatchIds(Arrays.asList(1, 4, 7));
         users.forEach(user-> System.out.println("user = " + user));
     }
     ​
     /**
      * @MethodName testSelectByMap
      * @Description 按照map进行多条件查询
      * 注意:Map只能做等值判断,逻辑判断需要使用Wrapper来处理
      * @Author Jiangnan Cui
      * @Date 11:38 2022/8/14
      */
     @Test
     public void testSelectByMap(){
         Map map = new HashMap<>();
         map.put("id",4);
         map.put("age",29);
         List users = userDao.selectByMap(map);
         for (User user : users) {
             System.out.println("user = " + user);
         }
     }

    7.2 自定义SQL(多表关联查询)

     package com.yao.mybatisplus.entity;
     ​
     import lombok.Data;
     ​
     @Data
     public class ProductVO {
         private Integer category;
         private Integer count;
         private String description;
         private Integer userId;
         private String userName;
     }
     ​
     ​
     package com.yao.mybatisplus.mapper;
     ​
     import com.baomidou.mybatisplus.core.mapper.BaseMapper;
     import com.southwind.mybatisplus.entity.ProductVO;
     import com.southwind.mybatisplus.entity.User;
     import org.apache.ibatis.annotations.Select;
     ​
     import java.util.List;
     ​
     public interface UserMapper extends BaseMapper {
         @Select("select p.*,u.name userName from product p,user u where p.user_id = u.id and u.id = #{id}")
         List productList(Integer id);
     }

    7.3 执行 SQL 分析打印

     添加依赖
     p6spy 依赖引入
     
       p6spy
       p6spy
       最新版本
     
     ​
     application.yml 配置:
     spring:
       datasource:
         driver-class-name: com.p6spy.engine.spy.P6SpyDriver  # com.mysql.cj.jdbc.Driver
         url: jdbc:p6spy:h2:mem:test # 把jdbc改为jdbc:p6spy
         ...
     ​
     spy.properties 配置:
     #3.2.1以上使用
     modulelist=com.baomidou.mybatisplus.extension.p6spy.MybatisPlusLogFactory,com.p6spy.engine.outage.P6OutageFactory
     #3.2.1以下使用或者不配置
     #modulelist=com.p6spy.engine.logging.P6LogFactory,com.p6spy.engine.outage.P6OutageFactory
     # 自定义日志打印
     logMessageFormat=com.baomidou.mybatisplus.extension.p6spy.P6SpyLogger
     #日志输出到控制台
     appender=com.baomidou.mybatisplus.extension.p6spy.StdoutLogger
     # 使用日志系统记录 sql
     #appender=com.p6spy.engine.spy.appender.Slf4JLogger
     # 设置 p6spy driver 代理
     deregisterdrivers=true
     # 取消JDBC URL前缀
     useprefix=true
     # 配置记录 Log 例外,可去掉的结果集有error,info,batch,debug,statement,commit,rollback,result,resultset.
     excludecategories=info,debug,result,commit,resultset
     # 日期格式
     dateformat=yyyy-MM-dd HH:mm:ss
     # 实际驱动可多个
     #driverlist=org.h2.Driver
     # 是否开启慢SQL记录
     outagedetection=true
     # 慢SQL记录标准 2 秒
     outagedetectioninterval=2

    7.4 MyBatisPlus代码自动生成

    • 引入依赖

     
         com.baomidou
         mybatis-plus-generator
         3.4.1
     
     ​
     
         org.apache.velocity
         velocity-engine-core
         latest-velocity-version
     

    注意:根据数据表自动生成实体类、Mapper、Service、ServiceImpl、Controller。

    MyBatis-Plus 从 3.0.3 之后移除了代码生成器与模板引擎的默认依赖,需要手动添加相关依赖。

    • 启动类

     import com.baomidou.mybatisplus.annotation.DbType;
     import com.baomidou.mybatisplus.generator.AutoGenerator;
     import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
     import com.baomidou.mybatisplus.generator.config.GlobalConfig;
     import com.baomidou.mybatisplus.generator.config.PackageConfig;
     import com.baomidou.mybatisplus.generator.config.StrategyConfig;
     import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
     ​
     public class Main {
         public static void main(String[] args) {
             //创建generator对象
             AutoGenerator autoGenerator = new AutoGenerator();
             
             //数据源
             DataSourceConfig dataSourceConfig = new DataSourceConfig();
             dataSourceConfig.setDbType(DbType.MYSQL);
             dataSourceConfig.setUrl("jdbc:mysql://ip:3306/db?useUnicode=true&characterEncoding=UTF-8");
             dataSourceConfig.setUsername("root");
             dataSourceConfig.setPassword("root");
             dataSourceConfig.setDriverName("com.mysql.cj.jdbc.Driver");
             autoGenerator.setDataSource(dataSourceConfig);
             
             //全局配置
             GlobalConfig globalConfig = new GlobalConfig();
             globalConfig.setOutputDir(System.getProperty("user.dir")+"/src/main/java");
             globalConfig.setOpen(false);
             globalConfig.setAuthor("southwind");  // 作者
             globalConfig.setServiceName("%sService");  
             autoGenerator.setGlobalConfig(globalConfig);
             
             //包信息
             PackageConfig packageConfig = new PackageConfig();
             packageConfig.setParent("com.yao.mybatisplus");
             packageConfig.setModuleName("generator");
             packageConfig.setController("controller");
             packageConfig.setService("service");
             packageConfig.setServiceImpl("service.impl");
             packageConfig.setMapper("mapper");
             packageConfig.setEntity("entity");
             autoGenerator.setPackageInfo(packageConfig);
             
             //配置策略
             StrategyConfig strategyConfig = new StrategyConfig();
             strategyConfig.setEntityLombokModel(true);
             strategyConfig.setNaming(NamingStrategy.underline_to_camel);
             strategyConfig.setColumnNaming(NamingStrategy.underline_to_camel);
             autoGenerator.setStrategy(strategyConfig);
     ​
             autoGenerator.execute();
         }
     }

    7.5 数据安全保护

     密钥加密:
     // 生成 16 位随机 AES 密钥
     String randomKey = AES.generateRandomKey();
     ​
     // 随机密钥加密
     String url = AES.encrypt("jdbc:mysql://ip:3306/db?useUnicode=true&characterEncoding=UTF-8", randomKey);
     String username = AES.encrypt("root", randomKey);
     String password = AES.encrypt("root", randomKey);
     ​
     url: mpw:+url
     username: mpw:+username
     password: mpw:+password
     ​
     // 加密配置 mpw: 开头紧接加密内容( 非数据库配置专用 YML 中其它配置也是可以使用的 )
     spring:
       datasource:
         url: mpw:qRhvCwF4GOqjessEB3G+a5okP+uXXr96wcucn2Pev6Bf1oEMZ1gVpPPhdDmjQqoM
         password: mpw:Hzy5iliJbwDHhjLs1L0j6w==
         username: mpw:Xb+EgsyuYRXw7U7sBJjBpA==
     ​
     ​
     // Jar 启动参数( idea 设置 Program arguments , 服务器可以设置为启动环境变量 )
     java -jar xxxx.jar --mpw.key=randomKey
     ​
    

    完结 

  • 相关阅读:
    二叉树练习
    阿里云国际版无法连接和访问Windows服务器中的FTP服务
    iMazing2023iOS系统设备数据传输与备份工具使用教程
    swagger工具编写接口文档
    Spring Cloud 微服务2
    如何从零开始设计一个亿级系统架构?总结万字的完整思路
    Linux命令(104)之date
    Centos7在线安装Docker引擎与卸载
    Git安装、原理、常用命令、版本控制、如何上传普通文件到仓库以及如何修改IDEA中Terminal为git窗口
    基于MATLABsimulink的《电路原理》课程仿真实验平台开发
  • 原文地址:https://blog.csdn.net/xiaocui1995/article/details/126326889