• MyBatisPlus-条件构造器/分页/多数据源/MyBatisX插件(生成代码)


    目录

    一、条件构造器

    1.1 wapper介绍

    1.2 QueryWrapper

    1.3 UpdateWrapper

    1.4 LambdaQueryWrapper

    1.5 LambdaUpdateWrapper

    二、分页插件

    2.1 使用BaseMapper中的分页方法

    2.2 在自定义mapper方法中使用分页

    三、多数据源

    四、MyBatisX插件


    一、条件构造器

    1.1 wapper介绍

            Wrapper : 条件构造抽象类,最顶端父类

                    AbstractWrapper : 用于查询条件封装,生成 sql 的 where 条件

                    QueryWrapper 查询条件封装

                    UpdateWrapper Update条件封装

                    AbstractLambdaWrapper : 使用Lambda 语法

                            LambdaQueryWrapper :基于Lambda语法的查询Wrapper                         

                            LambdaUpdateWrapper : 基于Lambda语法的 更新Wrapper

    1.2 QueryWrapper

    1. @Test
    2. void test1(){
    3. //查询名字包括a、年龄介于18、30之间、邮箱非空的记录
    4. //SELECT id,name,age,email,is_deleted FROM user WHERE is_deleted=0 AND (name LIKE ? AND age BETWEEN ? AND ? AND email IS NOT NULL)
    5. QueryWrapper wrapper = new QueryWrapper<>();
    6. wrapper.like("name","a").between("age",18,30).isNotNull("email");
    7. List users = userMapper.selectList(wrapper);
    8. users.forEach(System.out::println);
    9. }
    10. @Test
    11. void test2(){
    12. //查询记录,按年龄降序、id升序排列
    13. //SELECT id,name,age,email,is_deleted FROM user WHERE is_deleted=0 ORDER BY age DESC,id ASC
    14. QueryWrapper wrapper = new QueryWrapper<>();
    15. wrapper.orderByDesc("age").orderByAsc("id");
    16. List users = userMapper.selectList(wrapper);
    17. users.forEach(System.out::println);
    18. }
    19. @Test
    20. void test3(){
    21. //删除邮箱为空的记录
    22. //UPDATE user SET is_deleted=1 WHERE is_deleted=0 AND (email IS NULL)
    23. QueryWrapper wrapper = new QueryWrapper<>();
    24. wrapper.isNull("email");
    25. userMapper.delete(wrapper);
    26. }
    27. @Test
    28. void test4(){
    29. //修改年龄大于18,名字包含a,或邮箱非空的记录
    30. //UPDATE user SET name=?, email=? WHERE is_deleted=0 AND (age > ? AND name LIKE ? OR email IS NULL)
    31. QueryWrapper wrapper = new QueryWrapper<>();
    32. wrapper.gt("age",18)
    33. .like("name","a")
    34. .or()
    35. .isNull("email");
    36. User user=new User();
    37. user.setName("kunkun");
    38. user.setEmail("ikun@qq.com");
    39. userMapper.update(user,wrapper);
    40. }
    41. @Test
    42. void test5(){
    43. //修改名字包含a,且(年龄大于18或邮箱为空)的记录
    44. //UPDATE user SET name=?, email=? WHERE is_deleted=0 AND (name LIKE ? AND (age > ? OR email IS NULL))
    45. QueryWrapper wrapper = new QueryWrapper<>();
    46. wrapper.like("name","a")
    47. .and(i->i.gt("age",18).or().isNull("email"));
    48. User user=new User();
    49. user.setName("kunkun");
    50. user.setEmail("ikun@qq.com");
    51. userMapper.update(user,wrapper);
    52. }
    53. @Test
    54. void test6(){
    55. //查询所有记录的部分字段
    56. //SELECT name,age,email FROM user WHERE is_deleted=0
    57. QueryWrapper wrapper = new QueryWrapper<>();
    58. wrapper.select("name","age","email");
    59. List> list = userMapper.selectMaps(wrapper);
    60. list.forEach(System.out::println);
    61. }
    62. @Test
    63. void test7(){
    64. //查询id小于等于100的所有记录(子查询)
    65. //SELECT id,name,age,email,is_deleted FROM user WHERE is_deleted=0 AND (id IN (select id from user where id<=100))
    66. QueryWrapper wrapper = new QueryWrapper<>();
    67. wrapper.inSql("id","select id from user where id<=100");
    68. List> list = userMapper.selectMaps(wrapper);
    69. list.forEach(System.out::println);
    70. }

            在真正开发的过程中,组装条件是常见的功能,而这些条件数据来源于用户输入,是可选的,因 此我们在组装这些条件时,必须先判断用户是否选择了这些条件,若选择则需要组装该条件,若没有选择则一定不能组装,以免影响SQL执行的结果。我们可以使用带condition参数的重载方法构建查询条件

    1. @Test
    2. public void test08UseCondition() {
    3. //定义查询条件,有可能为null(用户未输入或未选择)
    4. String username = null;
    5. Integer ageBegin = 10;
    6. Integer ageEnd = 24;
    7. QueryWrapper queryWrapper = new QueryWrapper<>();
    8. //StringUtils.isNotBlank()判断某字符串是否不为空且长度不为0且不由空白符(whitespace)构成
    9. queryWrapper.like(StringUtils.isNotBlank(username), "username", "a")
    10. .ge(ageBegin != null, "age", ageBegin)
    11. .le(ageEnd != null, "age", ageEnd);
    12. //SELECT id,username AS name,age,email,is_deleted FROM t_user WHERE (age >=? AND age <= ?)
    13. List users = userMapper.selectList(queryWrapper);
    14. users.forEach(System.out::println);
    15. }

    1.3 UpdateWrapper

    1. @Test
    2. void test8(){
    3. //更新名字包含a,且(年龄大于20或邮箱为空)的记录
    4. //UPDATE user SET name=?,email=? WHERE is_deleted=0 AND (name LIKE ? AND (age > ? OR email IS NULL))
    5. UpdateWrapper wrapper = new UpdateWrapper<>();
    6. wrapper.like("name","a")
    7. .and(i->i.gt("age",20).or().isNull("email"))
    8. .set("name","haha")
    9. .set("email","haha@qq.com");
    10. userMapper.update(null,wrapper);
    11. }
    12. @Test
    13. void test9(){
    14. //查询名字包含a,且年龄小于等于20的记录
    15. //SELECT id,name,age,email,is_deleted FROM user WHERE is_deleted=0 AND (name LIKE ? AND age <= ?)
    16. String name="zp";
    17. Integer ageBegin=null;
    18. Integer ageEnd=30;
    19. UpdateWrapper wrapper = new UpdateWrapper<>();
    20. wrapper.like(StringUtils.isNotBlank(name),"name",name)
    21. .ge(ageBegin!=null,"age",ageBegin)
    22. .le(ageEnd!=null,"age",ageEnd);
    23. userMapper.selectList(wrapper);
    24. }

    1.4 LambdaQueryWrapper

    1. @Test
    2. void test10(){
    3. //查询名字包含a,且年龄小于等于20的记录
    4. //SELECT id,name,age,email,is_deleted FROM user WHERE is_deleted=0 AND (name LIKE ? AND age <= ?)
    5. String name="zp";
    6. Integer ageBegin=null;
    7. Integer ageEnd=30;
    8. LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>();
    9. wrapper.like(StringUtils.isNotBlank(name),User::getName,name)
    10. .ge(ageBegin!=null,User::getAge,ageBegin)
    11. .le(ageEnd!=null,User::getAge,ageEnd);
    12. userMapper.selectList(wrapper);
    13. }

    1.5 LambdaUpdateWrapper

    1. @Test
    2. void test11(){
    3. //更新名字包含a,且(年龄大于20或邮箱为空)的记录
    4. //UPDATE user SET name=?,email=? WHERE is_deleted=0 AND (name LIKE ? AND (age > ? OR email IS NULL))
    5. LambdaUpdateWrapper wrapper = new LambdaUpdateWrapper<>();
    6. wrapper.like(User::getName,"a")
    7. .and(i->i.gt(User::getAge,20).or().isNull(User::getEmail))
    8. .set(User::getName,"haha")
    9. .set(User::getEmail,"haha@qq.com");
    10. userMapper.update(null,wrapper);
    11. }

    二、分页插件

            MyBatis Plus自带分页插件,只要简单的配置即可实现分页功能

    2.1 使用BaseMapper中的分页方法

            创建配置类

    1. @Configuration
    2. public class MyBatisPlusConfig {
    3. @Bean
    4. public MybatisPlusInterceptor mybatisPlusInterceptor(){
    5. MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
    6. interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
    7. return interceptor;
    8. }
    9. }

            测试:

    1. @Test
    2. void testPage(){
    3. //SELECT id,name,age,email,is_deleted FROM user WHERE is_deleted=0 LIMIT ?
    4. Page page = new Page<>(1, 3);//当前页码:1 每页的记录数:3
    5. userMapper.selectPage(page,null);
    6. System.out.println(page); //page对象
    7. System.out.println(page.getRecords()); //所有的记录
    8. System.out.println(page.getPages()); //总页数
    9. System.out.println(page.getTotal()); //总记录数
    10. System.out.println(page.hasNext()); //是否有下一页
    11. System.out.println(page.hasPrevious()); //是否有上一页
    12. }
    13. //测试结果:
    14. com.baomidou.mybatisplus.extension.plugins.pagination.Page@4527f70a
    15. [User(id=3, name=zp, age=19, email=zp@qq.com, isDeleted=0), User(id=4, name=kunkun, age=21, email=ikun@qq.com, isDeleted=0), User(id=5, name=Billie, age=24, email=test5@baomidou.com, isDeleted=0)]
    16. 3
    17. 7
    18. true
    19. false

    2.2 在自定义mapper方法中使用分页

            方法返回值必须是Page类型且指定泛型参数@param标注且第一个参数Page类型

    1. @Repository
    2. public interface UserMapper extends BaseMapper {
    3. Page selectPageVo(@Param("page") Page page,@Param("age") Integer age);
    4. }
    1. mapper
    2. PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
    3. "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    4. <mapper namespace="com.mybatisplus.mapper.UserMapper">
    5. <select id="selectPageVo" resultType="com.mybatisplus.pojo.User">
    6. select id,name,age,email from user where age>#{age}
    7. select>
    8. mapper>
    1. @Test
    2. void testPage1(){
    3. //select id,name,age,email from user where age>? LIMIT ?
    4. Page page = new Page<>(1, 3);//当前页码:1 每页的记录数:3
    5. userMapper.selectPageVo(page,20); //查询年龄大于20的记录
    6. System.out.println(page); //page对象
    7. System.out.println(page.getRecords()); //所有的记录
    8. System.out.println(page.getPages()); //总页数
    9. System.out.println(page.getTotal()); //总记录数
    10. System.out.println(page.hasNext()); //是否有下一页
    11. System.out.println(page.hasPrevious()); //是否有上一页
    12. }
    13. //测试结果:
    14. com.baomidou.mybatisplus.extension.plugins.pagination.Page@4bc33720
    15. [User(id=4, name=kunkun, age=21, email=ikun@qq.com, isDeleted=null), User(id=5, name=Billie, age=24, email=test5@baomidou.com, isDeleted=null), User(id=1556111099474116610, name=wzz, age=28, email=1@qq.com, isDeleted=null)]
    16. 2
    17. 4
    18. true
    19. false

    三、多数据源

             适用于多种场景:纯粹多库、 读写分离、 一主多从、 混合模式等

            假如有的放在数据库1中,有的放在数据库2中,该如何处理?

            1.引入依赖

    1. <dependency>
    2. <groupId>com.baomidougroupId>
    3. <artifactId>dynamic-datasource-spring-boot-starterartifactId>
    4. <version>3.5.0version>
    5. dependency>

            2.配置多数据源

    1. spring:
    2. # 配置数据源信息
    3. datasource:
    4. dynamic:
    5. # 设置默认的数据源或者数据源组,默认值即为master
    6. primary: master
    7. # 严格匹配数据源,默认false.true未匹配到指定数据源时抛异常,false使用默认数据源
    8. strict: false
    9. datasource:
    10. #主数据库
    11. master:
    12. url: jdbc:mysql://localhost:3306/mybatis_plus?characterEncoding=utf-8&useSSL=false
    13. driver-class-name: com.mysql.cj.jdbc.Driver
    14. username: root
    15. password: 123456
    16. //从数据库1
    17. slave_1:
    18. url: jdbc:mysql://localhost:3306/mybatis_plus_1?characterEncoding=utf-8&useSSL=false
    19. driver-class-name: com.mysql.cj.jdbc.Driver
    20. username: root
    21. password: 123456

            3.在方法上标注@DB注解,指明使用哪个数据库

    1. @DS("master") //指定所操作的数据源-master
    2. @Service
    3. public class UserServiceImpl extends ServiceImpl implements
    4. UserService {
    5. }
    6. @DS("slave_1") //指定所操作的数据源-slave_1
    7. @Service
    8. public class ProductServiceImpl extends ServiceImpl
    9. implements ProductService {
    10. }

    四、MyBatisX插件

            MyBatis-Plus为我们提供了强大的mapper和service模板,能够大大的提高开发效率。但是在真正开发过程中,MyBatis-Plus并不能为我们解决所有问题,例如一些复杂的SQL多表联查,我们就需要自己去编写代码和SQL语句,我们该如何快速的解决这个问题呢?这个时候可以使用MyBatisX插件

            1.首先要安装在ideaMyBatisX插件

            2.在 idea 配置 Database 数据源

            3.在需要生成相关pojomapperservice数据库表上点右键使用生成功能

             4. 设置生成策略,如字段前后缀、命名方法、包的路径

             5.生成相关文件

             6.在mapper中键入关键词,可自动提示sql语句模板,根据代码提示生成sql语句

            自动生成的方法: 

    1. public interface UserMapper extends BaseMapper {
    2. List selectAllById(@Param("id") Long id);
    3. }

            自动生成的sql语句:

    1. mapper
    2. PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
    3. "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    4. <mapper namespace="com.mybatisplus.mapper.UserMapper">
    5. <resultMap id="BaseResultMap" type="com.mybatisplus.domain.User">
    6. <id property="id" column="id" jdbcType="BIGINT"/>
    7. <result property="name" column="name" jdbcType="VARCHAR"/>
    8. <result property="age" column="age" jdbcType="INTEGER"/>
    9. <result property="email" column="email" jdbcType="VARCHAR"/>
    10. <result property="isDeleted" column="is_deleted" jdbcType="INTEGER"/>
    11. resultMap>
    12. <sql id="Base_Column_List">
    13. id,name,age,
    14. email,is_deleted
    15. sql>
    16. <select id="selectAllById" resultMap="BaseResultMap"> //为我们自动生成的
    17. select
    18. <include refid="Base_Column_List"/>
    19. from user
    20. where
    21. id = #{id,jdbcType=NUMERIC}
    22. select>
    23. mapper>

  • 相关阅读:
    模拟shell小程序
    SSM+教育培训管理系统 毕业设计-附源码141053
    在字节跳动,一个更好的企业级SparkSQL Server这么做
    【优化调度】基于NSGAII算法的车辆充电调度策略研究含Matlab代码
    这个用Python写的开源爬虫网站 让你秒搜所有豆瓣好书(附零基础学习资料)
    【Java刷题进阶】基础入门篇⑨
    Python编程 字符串组成方式
    Linux make编译
    【计算机网络】第三章课后习题答案
    【iOS】class的底层结构总结
  • 原文地址:https://blog.csdn.net/weixin_62427168/article/details/126235517