• MyBatis-plus组件学习


    1 认识MyBatis-Plus

    MyBatis-Plus ( MP)是一个 MyBatis 的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。

    1.1 基本使用 

    1)创建数据库

    1. DROP TABLE IF EXISTS shuser;
    2. CREATE TABLE shuser
    3. (
    4. uid INT(4) NOT NULL COMMENT '主键ID',
    5. username VARCHAR(30) NOT NULL COMMENT '用户名',
    6. password VARCHAR(30) NOT NULL COMMENT '密码',
    7. rid INT(4) NOT NULL COMMENT '角色ID',
    8. createtime DATE COMMENT '创建时间',
    9. uodatetime DATE COMMENT '修改时间',
    10. PRIMARY KEY (uid)
    11. );

    2)配置

    pom.xml

    1. <dependencies>
    2. <dependency>
    3. <groupId>org.springframework.bootgroupId>
    4. <artifactId>spring-boot-starterartifactId>
    5. dependency>
    6. <dependency>
    7. <groupId>org.springframework.bootgroupId>
    8. <artifactId>spring-boot-starter-testartifactId>
    9. <scope>testscope>
    10. dependency>
    11. <dependency>
    12. <groupId>com.baomidougroupId>
    13. <artifactId>mybatis-plus-boot-starterartifactId>
    14. <version>最新版本version>
    15. dependency>
    16. <dependency>
    17. <groupId>com.h2databasegroupId>
    18. <artifactId>h2artifactId>
    19. <scope>runtimescope>
    20. dependency>
    21. dependencies>

    application.yml 

    1. # DataSource Config
    2. spring:
    3. datasource:
    4. driver-class-name: org.h2.Driver
    5. schema: classpath:db/schema-h2.sql
    6. data: classpath:db/data-h2.sql
    7. url: jdbc:h2:mem:test
    8. username: root
    9. password: test

    3) 在 Spring Boot 启动类中添加 @MapperScan 注解,扫描 Mapper 文件夹:

    4)编码

    编写实体类 shUser.java

    1. @Data
    2. @AllArgsConstructor
    3. public class shUser {
    4. private String uid;
    5. private String username;
    6. private String password;
    7. private String rid;
    8. private String createtime;
    9. private String updatetime;
    10. }

    编写 Mapper 包下的 UserMapper接口

    1. @Mapper
    2. public interface UserMapper extends BaseMapper {
    3. }

     5)测试

     

    1.2 注解
     

    注解包源码

    1)@TableName 表名注解

    1. @TableName("sh_user")
    2. public class shUser {
    3. private String uid;
    4. private String username;
    5. private String password;
    6. private String rid;
    7. private String createtime;
    8. private String updatetime;
    9. }

    2)@TableId主键注解

    1. @TableName("sh_user")
    2. public class shUser {
    3. @TableId
    4. private String uid;
    5. private String username;
    6. private String password;
    7. private String rid;
    8. private String createtime;
    9. private String updatetime;
    10. }

     3)@TableField字段注解

    1. @TableName("sh_user")
    2. public class shUser {
    3. @TableId
    4. private String uid;
    5. @TableField("username")
    6. private String username;
    7. private String password;
    8. private String rid;
    9. private String createtime;
    10. private String updatetime;
    11. }

     2 查询

    2.1 Service CRUD 接口

    (1)自定义IBaseService继承IService

    1. public interface UserService extends IService {
    2. }
    1. @Service
    2. public class UserServiceImpl extends ServiceImpl implements UserService {
    3. }

    (2)注解配置:

    (3)测试:

    (4)插入:

    1. // 插入一条记录(选择字段,策略插入)
    2. boolean save(T entity);
    3. // 插入(批量)
    4. boolean saveBatch(Collection entityList);
    5. // 插入(批量)
    6. boolean saveBatch(Collection entityList, int batchSize)
    7. // TableId 注解存在更新记录,否插入一条记录
    8. boolean saveOrUpdate(T entity);
    9. // 根据updateWrapper尝试更新,否继续执行saveOrUpdate(T)方法
    10. boolean saveOrUpdate(T entity, Wrapper updateWrapper);
    11. // 批量修改插入
    12. boolean saveOrUpdateBatch(Collection entityList);
    13. // 批量修改插入
    14. boolean saveOrUpdateBatch(Collection entityList, int batchSize);

    (5)更新:

    1. // 根据 UpdateWrapper 条件,更新记录 需要设置sqlset
    2. boolean update(Wrapper updateWrapper);
    3. // 根据 whereWrapper 条件,更新记录
    4. boolean update(T updateEntity, Wrapper whereWrapper);
    5. // 根据 ID 选择修改
    6. boolean updateById(T entity);
    7. // 根据ID 批量更新
    8. boolean updateBatchById(Collection entityList);
    9. // 根据ID 批量更新
    10. boolean updateBatchById(Collection entityList, int batchSize);

    (6)删除:

    1. // 根据 entity 条件,删除记录
    2. boolean remove(Wrapper queryWrapper);
    3. // 根据 ID 删除
    4. boolean removeById(Serializable id);
    5. // 根据 columnMap 条件,删除记录
    6. boolean removeByMap(Map columnMap);
    7. // 删除(根据ID 批量删除)
    8. boolean removeByIds(Collection idList);

    (7) 查询:

    1. // 根据 ID 查询
    2. T getById(Serializable id);
    3. // 根据 Wrapper,查询一条记录。结果集,如果是多个会抛出异常,随机取一条加上限制条件 wrapper.last("LIMIT 1")
    4. T getOne(Wrapper queryWrapper);
    5. // 根据 Wrapper,查询一条记录
    6. T getOne(Wrapper queryWrapper, boolean throwEx);
    7. // 根据 Wrapper,查询一条记录
    8. Map getMap(Wrapper queryWrapper);
    9. // 根据 Wrapper,查询一条记录
    10. V getObj(Wrapper queryWrapper, Functionsuper Object, V> mapper);
    11. // 查询所有
    12. List list();
    13. // 查询列表
    14. List list(Wrapper queryWrapper);
    15. // 查询(根据ID 批量查询)
    16. Collection listByIds(Collection idList);
    17. // 查询(根据 columnMap 条件)
    18. Collection listByMap(Map columnMap);
    19. // 查询所有列表
    20. List> listMaps();
    21. // 查询列表
    22. List> listMaps(Wrapper queryWrapper);
    23. // 查询全部记录
    24. List listObjs();
    25. // 查询全部记录
    26. List listObjs(Functionsuper Object, V> mapper);
    27. // 根据 Wrapper 条件,查询全部记录
    28. List listObjs(Wrapper queryWrapper);
    29. // 根据 Wrapper 条件,查询全部记录
    30. List listObjs(Wrapper queryWrapper, Functionsuper Object, V> mapper);
    31. 结果:

      (8)分页查询:

      1. // 无条件分页查询
      2. IPage page(IPage page);
      3. // 条件分页查询
      4. IPage page(IPage page, Wrapper queryWrapper);
      5. // 无条件分页查询
      6. IPage> pageMaps(IPage page);
      7. // 条件分页查询
      8. IPage> pageMaps(IPage page, Wrapper queryWrapper);

      (9)总数查询:

      1. // 查询总记录数
      2. int count();
      3. // 根据 Wrapper 条件,查询总记录数
      4. int count(Wrapper queryWrapper);

       2.2 Mapper CURD 接口

      1)自定义Mapper接口继承BaseMapper

      1. @Mapper
      2. public interface UserMapper extends BaseMapper {
      3. }

      2)增删改查

      1. 1)插入
      2. // 插入一条记录
      3. int insert(T entity);
      4. 2)删除
      5. // 根据 entity 条件,删除记录
      6. int delete(@Param(Constants.WRAPPER) Wrapper wrapper);
      7. // 删除(根据ID 批量删除)
      8. int deleteBatchIds(@Param(Constants.COLLECTION) Collection idList);
      9. // 根据 ID 删除
      10. int deleteById(Serializable id);
      11. // 根据 columnMap 条件,删除记录
      12. int deleteByMap(@Param(Constants.COLUMN_MAP) Map columnMap);
      13. 3)更新
      14. // 根据 whereWrapper 条件,更新记录
      15. int update(@Param(Constants.ENTITY) T updateEntity, @Param(Constants.WRAPPER) Wrapper whereWrapper);
      16. // 根据 ID 修改
      17. int updateById(@Param(Constants.ENTITY) T entity);
      18. 4)查询
      19. // 根据 ID 查询
      20. T selectById(Serializable id);
      21. // 根据 entity 条件,查询一条记录
      22. T selectOne(@Param(Constants.WRAPPER) Wrapper queryWrapper);
      23. // 查询(根据ID 批量查询)
      24. List selectBatchIds(@Param(Constants.COLLECTION) Collection idList);
      25. // 根据 entity 条件,查询全部记录
      26. List selectList(@Param(Constants.WRAPPER) Wrapper queryWrapper);
      27. // 查询(根据 columnMap 条件)
      28. List selectByMap(@Param(Constants.COLUMN_MAP) Map columnMap);
      29. // 根据 Wrapper 条件,查询全部记录
      30. List> selectMaps(@Param(Constants.WRAPPER) Wrapper queryWrapper);
      31. // 根据 Wrapper 条件,查询全部记录。注意: 只返回第一个字段的值
      32. List selectObjs(@Param(Constants.WRAPPER) Wrapper queryWrapper);
      33. // 根据 entity 条件,查询全部记录(并翻页)
      34. IPage selectPage(IPage page, @Param(Constants.WRAPPER) Wrapper queryWrapper);
      35. // 根据 Wrapper 条件,查询全部记录(并翻页)
      36. IPage> selectMapsPage(IPage page, @Param(Constants.WRAPPER) Wrapper queryWrapper);
      37. // 根据 Wrapper 条件,查询总记录数
      38. Integer selectCount(@Param(Constants.WRAPPER) Wrapper queryWrapper);
      39. 2.3 Wrapper条件构造器

        1. Wrapper 条件构造抽象类
        2. -- AbstractWrapper 查询条件封装,用于生成 sql 中的 where 语句。
        3. -- QueryWrapper Entity 对象封装操作类,用于查询。
        4. -- UpdateWrapper Update 条件封装操作类,用于更新。
        5. -- AbstractLambdaWrapper 使用 Lambda 表达式封装 wrapper
        6. -- LambdaQueryWrapper 使用 Lambda 语法封装条件,用于查询。
        7. -- LambdaUpdateWrapper 使用 Lambda 语法封装条件,用于更新。

         常用查询:

        1)   比较大小类

            eq(R column, Object val); // 等价于 =
            ne(R column, Object val); // 等价于 <>
            gt(R column, Object val); // 等价于 >
            ge(R column, Object val); // 等价于 >=
            lt(R column, Object val); // 等价于 <
            le(R column, Object val); // 等价于 <=

        2)范围

           between(R column, Object val1, Object val2); // 等价于 between a and b
           notBetween(R column, Object val1, Object val2); // 等价于 not between a and b
           in(R column, Object... values); // 等价于 字段 IN (v0, v1, ...)
           notIn(R column, Object... values); // 等价于 字段 NOT IN (v0, v1, ...)
           inSql(R column, Object... values); // 等价于 字段 IN (sql 语句)
           notInSql(R column, Object... values); // 等价于 字段 NOT IN (sql 语句)

        3)模糊匹配

            like(R column, Object val); // 等价于 LIKE '%值%'
            notLike(R column, Object val); // 等价于 NOT LIKE '%值%'
            likeLeft(R column, Object val); // 等价于 LIKE '%值'
            likeRight(R column, Object val); // 等价于 LIKE '值%'

        4)空值比较

            isNull(R column); // 等价于 IS NULL
            isNotNull(R column); // 等价于 IS NOT NULL

        5)分组、排序

            groupBy(R... columns); // 等价于 GROUP BY 字段, ...
            orderByAsc(R... columns); // 等价于 ORDER BY 字段, ... ASC
            orderByDesc(R... columns); // 等价于 ORDER BY 字段, ... DESC
            having(String sqlHaving, Object... params); // 等价于 HAVING ( sql语句 )

        6)拼接、嵌套

           or(); // 等价于 a or b
           or(Consumer consumer); // 等价于 or(a or/and b),or 嵌套
           and(Consumer consumer); // 等价于 and(a or/and b),and 嵌套
           nested(Consumer consumer); // 等价于 (a or/and b),普通嵌套
           apply(String applySql, Object... params); // 拼接sql(若不使用 params 参数,可能存在 sql 注入)
           last(String lastSql); // 无视优化规则直接拼接到 sql 的最后,可能存若在 sql 注入。
           exists(String existsSql); // 拼接 exists 语句

        queryWrapper select条件查询:

         UpdateWrapper set、setSql(设置SQL语句)更新: 

         3 扩展

        3.1 安全保护

        Mybatis-Plus 3.3.2版本:

        1)获取密钥

        1. String randomKey= AES.generateRandomKey();
        2. //使用随机密钥加密需要加密的数据,列如数据库url,username,password
        3. String url = "jdbc:mysql://localhost:3306/mybatisplus?characterEncoding=utf8&useSSL=false&serverTimezone=GMT%2B8";
        4. String username = "root";
        5. String password = "root";
        6. String aesUrl = AES.encrypt(url, randomKey);
        7. String aesUsername = AES.encrypt(username, randomKey);
        8. String aesPassword = AES.encrypt(password, randomKey);
        9. System.out.println("url:"+aesUrl);
        10. System.out.println("username:"+aesUsername);
        11. System.out.println("password:"+aesPassword);

        2)配置

        1. spring:
        2. datasource:
        3. url: mpw:qRhvCwF4GOqjessEB3G+a5okP+uXXr96wcucn2Pev6Bf1oEMZ1gVpPPhdDmjQqoM
        4. password: mpw:Hzy5iliJbwDHhjLs1L0j6w==
        5. username: mpw:Xb+EgsyuYRXw7U7sBJjBpA==

        3)启动

        / Jar 启动参数( idea 设置 Program arguments , 服务器可以设置为启动环境变量 )
        --mpw.key=key

        4)其他防护

        注解 @FieldEncrypt 字段加密

        1. @FieldEncrypt
        2. private String password;

        注解 @FieldSensitive 字段脱敏,内置 手机号、邮箱、银行卡号 等 9 种常用脱敏规则

        自定义脱敏

        1. @FieldSensitive(type = "testStrategy")
        2. private String username;
        3. @FieldSensitive(type = SensitiveType.mobile)
        4. private String mobile;
        5. @Configuration
        6. public class SensitiveStrategyConfig {
        7. /**
        8. * 注入脱敏策略
        9. */
        10. @Bean
        11. public ISensitiveStrategy sensitiveStrategy() {
        12. // 自定义 testStrategy 类型脱敏处理
        13. return new SensitiveStrategy().addStrategy("testStrategy", t -> t + "***test***");
        14. }
        15. }

        3.2 多数据源

        1. mybatis-mate:
        2. sharding:
        3. health: true # 健康检测
        4. primary: mysql # 默认选择数据源
        5. datasource:
        6. mysql: # 数据库组
        7. - key: node1
        8. ...
        9. - key: node2
        10. cluster: slave # 从库读写分离时候负责 sql 查询操作,主库 master 默认可以不写
        11. ...
        12. postgres:
        13. - key: node1 # 数据节点
        14. ...
        1. @Mapper
        2. @Sharding("mysql")
        3. public interface UserMapper extends BaseMapper {
        4. @Sharding("postgres")
        5. Long selectByUsername(String username);
        6. }

      40. 相关阅读:
        【C语言】库宏offsetof
        2020年12月大学英语六级作文(二)
        Shell系统学习之子Shell与进程处理
        CodeForces每日好题10.14
        对数据安全建设的思路ing
        Ubuntu使用System.Drawing.dll报错DllNotFoundException: libgdiplus.so.0
        本地部署 EVE: Unveiling Encoder-Free Vision-Language Models
        唐诗的四个阶段
        kubernetes(k8s)滚动发布,不宕机实战
        递推算法及解题套路
      41. 原文地址:https://blog.csdn.net/xlsj228/article/details/122844892