一:简介

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

官网传送门====>https://mp.baomidou.com
个人git传送门====>https://gitee.com/remember0324/mybatisPlus

二:ORM框架

ORM(Object Relational Mapping)框架采用元数据来描述对象与关系映射的细节,元数据一般采用XML格式,并且存放在专门的对象一映射文件中。只要提供了持久化类与表的映射关系,ORM框架在运行时就能参照映射文件的信息,把对象持久化到数据库中。

三:MP与JPA对比

在使用的角度来说少写一句sql就少写一句,在单表操做过程中两者都基本都是能满足这个特点。关于学习难度来说其实两者差不多,没有另外拔高知识点,只是在底层原理不同。

四:构建项目

前提准备

创建数据库:mp 数据表:tb_user

创建表
  1. CREATE TABLE `tb_user` (
  2. `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
  3. `user_name` varchar(20) DEFAULT NULL COMMENT '用户名',
  4. `password` varchar(20) DEFAULT NULL COMMENT '密码',
  5. `name` varchar(30) DEFAULT NULL COMMENT '姓名',
  6. `age` int(11) DEFAULT NULL COMMENT '年龄',
  7. `email` varchar(50) DEFAULT NULL COMMENT '邮箱',
  8. `version` int(10) DEFAULT '1',
  9. `deleted` int(1) DEFAULT '0' COMMENT '1代表删除,0代表未删除',
  10. `sex` int(1) DEFAULT '1' COMMENT '1-男,2-女',
  11. PRIMARY KEY (`id`)
  12. ) ENGINE=InnoDB DEFAULT CHARSET=utf8

我使用的是IDEA工具
Lombok
springBoot:2.2.4
mybatisPlus:3.1.1
mysql:8.1.19

pom文件
  1. <dependencies>
  2. <dependency>
  3. <groupId>com.baomidou</groupId>
  4. <artifactId>mybatis-plus-boot-starter</artifactId>
  5. <version>3.1.1</version>
  6. </dependency>
  7. <dependency>
  8. <groupId>mysql</groupId>
  9. <artifactId>mysql-connector-java</artifactId>
  10. <version>8.0.19</version>
  11. </dependency>
  12. <dependency>
  13. <groupId>org.springframework.boot</groupId>
  14. <artifactId>spring-boot-starter-web</artifactId>
  15. <exclusions>
  16. <exclusion>
  17. <groupId>org.springframework.boot</groupId>
  18. <artifactId>spring-boot-starter-logging</artifactId>
  19. </exclusion>
  20. </exclusions>
  21. </dependency>
  22. <dependency>
  23. <groupId>org.projectlombok</groupId>
  24. <artifactId>lombok</artifactId>
  25. <optional>true</optional>
  26. </dependency>
  27. <dependency>
  28. <groupId>org.springframework.boot</groupId>
  29. <artifactId>spring-boot-starter-test</artifactId>
  30. <scope>test</scope>
  31. <exclusions>
  32. <exclusion>
  33. <groupId>org.junit.vintage</groupId>
  34. <artifactId>junit-vintage-engine</artifactId>
  35. </exclusion>
  36. </exclusions>
  37. </dependency>
  38. <dependency>
  39. <groupId>junit</groupId>
  40. <artifactId>junit</artifactId>
  41. <scope>test</scope>
  42. </dependency>
  43. <dependency>
  44. <groupId>org.slf4j</groupId>
  45. <artifactId>slf4j-log4j12</artifactId>
  46. </dependency>
  47. <dependency>
  48. <groupId>org.apache.commons</groupId>
  49. <artifactId>commons-lang3</artifactId>
  50. <version>3.8.1</version>
  51. </dependency>
  52. <dependency>
  53. <groupId>com.baomidou</groupId>
  54. <artifactId>mybatis-plus-extension</artifactId>
  55. <version>3.1.1</version>
  56. </dependency>
  57. <!--代码生成器-->
  58. <dependency>
  59. <groupId>com.baomidou</groupId>
  60. <artifactId>mybatis-plus-generator</artifactId>
  61. <version>3.1.1</version>
  62. </dependency>
  63. <dependency>
  64. <groupId>org.springframework.boot</groupId>
  65. <artifactId>spring-boot-starter-freemarker</artifactId>
  66. </dependency>
  67. </dependencies>
  68. <build>
  69. <plugins>
  70. <plugin>
  71. <groupId>org.springframework.boot</groupId>
  72. <artifactId>spring-boot-maven-plugin</artifactId>
  73. </plugin>
  74. </plugins>
  75. </build>

yml文件
  1. spring:
  2. application:
  3. name: mybatisPlusSpringBoot
  4. datasource:
  5. driver-class-name: com.mysql.cj.jdbc.Driver
  6. url: jdbc:mysql://127.0.0.1:3306/mp?serverTimezone=UTC&useSSL=false&useUnicode=true&characterEncoding=utf8
  7. username: root
  8. password: root
  9. mybatis-plus:
  10. configuration:
  11. log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
  12. #关闭自动驼峰映射,该参数不能和mybatis-plus: config-location同时存在:
  13. # map-underscore-to-camel-case: false
  14. #全局地开启或关闭配置文件中的所有映射器已经配置的任何缓存,默认为 true。
  15. #cache-enabled: false
  16. #配置自定义的mapper文件 (多表查询适用)
  17. mapper-locations: classpath*:mybatis/*.xml
  18. #配置实体对象扫描包===在mapper.xml中简化使用
  19. type-aliases-package: com.hhz.mp.pojo
  20. #配置全局主键生成策略
  21. # global-config:
  22. # db-config:
  23. # id-type: auto
  24. #配置全局表名前缀
  25. # global-config:
  26. # db-config:
  27. # table-prefix: tb_
  28. #乐观锁配置
  29. global-config:
  30. db-config:
  31. # 逻辑已删除值(默认为 1)
  32. logic-delete-value: 1
  33. # 逻辑未删除值(默认为 0)
  34. logic-not-delete-value: 0
  35. # 枚举包扫描
  36. type-enums-package: com.hhz.mp.enums

创建实体类
  1. @Data
  2. @NoArgsConstructor
  3. @AllArgsConstructor
  4. @EqualsAndHashCode(callSuper = true)
  5. @TableName("tb_user")
  6. public class User extends Model<User> {
  7. //设置按照数据库自增长
  8. @TableId(type = IdType.AUTO)
  9. private Long id;
  10. //下划线可自动转驼峰命名 这里可以不写
  11. @TableField(value = "user_name")
  12. private String userName;
  13. //查询时不返回该字段的值
  14. //fill =FieldFill.INSERT 对插入密码的时候可以进行填充
  15. @TableField(select = false, fill = FieldFill.INSERT)
  16. private String password;
  17. private String name;
  18. private Integer age;
  19. //字段名与数据库名不一致
  20. @TableField(value = "email")
  21. private String mail;
  22. //忽略在数据库的字段
  23. @TableField(exist = false)
  24. private String address;
  25. //添加版本信息__乐观锁
  26. @Version
  27. private Integer version;
  28. //逻辑删除
  29. @TableLogic
  30. private Integer deleted;
  31. //配置枚举值
  32. private SexEnum sex;
  33. public User(String userName, Integer age) {
  34. this.userName = userName;
  35. this.age = age;
  36. }
  37. public User(String userName, String password, String name, Integer age, String mail) {
  38. this.userName = userName;
  39. this.password = password;
  40. this.name = name;
  41. this.age = age;
  42. this.mail = mail;
  43. }
  44. public User(Long id) {
  45. this.id = id;
  46. }
  47. public User(Long id, String userName, String password, String name, Integer age, String mail) {
  48. this.id = id;
  49. this.userName = userName;
  50. this.password = password;
  51. this.name = name;
  52. this.age = age;
  53. this.mail = mail;
  54. }
  55. }

创建dao层
  1. @Repository
  2. public interface UserMapper extends BaseMapper<User> {
  3. }

创建一个测试类
  1. @Slf4j
  2. @RunWith(SpringJUnit4ClassRunner.class)
  3. @SpringBootTest
  4. public class MyApplicationTest {
  5. @Autowired
  6. private UserMapper userMapper;
  7. }

五:正式开始

5.1 基础增删改

如果id未设置自增长默认是推特的 雪花算法

mysql设置主键类型
  1. @TableId(type = IdType.AUTO)

oracle设置主键类型

yml文件中

  1. mybatis-plus:
  2. global-config:
  3. #主键类型 0:"数据库ID自增", 1:"用户输入ID",2:"全局唯一ID (数字类型唯一ID)", 3:"全局唯一ID UUID";
  4. id-type: 1
  5. # Sequence序列接口实现类配置
  6. key-generator: com.baomidou.mybatisplus.incrementer.OracleKeyGenerator

实体类上设置

  1. @KeySequence(value = "序列名称",clazz = 主键类型.class)

主键上设置

  1. @TableId(type=IdType.INPUT)

新增

  1. @Test
  2. public void testInsert() {
  3. User user = new User("guanyu", "222", "关羽", 42, "guanyu@shu.com");
  4. int insert = userMapper.insert(user);
  5. Long id = user.getId();
  6. //改变的记录数
  7. System.err.println("change:" + insert);
  8. //id未设置增长策略结果:1233004593171144706
  9. System.err.println("id:" + id);
  10. }

根据id新增

  1. @Test
  2. public void testupdateById() {
  3. User user = new User(9L, "zhuge", "111", "诸葛", 36, "zhuge@shu.com");
  4. int update = userMapper.updateById(user);
  5. //改变的行数
  6. System.err.println(update);
  7. }

根据id删除

  1. @Test
  2. public void testdeleteById() {
  3. int result = userMapper.deleteById(9L);
  4. System.out.println(result);
  5. }

构造map条件删除

  1. @Test
  2. public void testdeleteByMap() {
  3. //DELETE FROM tb_user WHERE name = ?
  4. HashMap<String, Object> map = new HashMap<>();
  5. map.put("name", "关羽");
  6. int result = userMapper.deleteByMap(map);
  7. System.err.println(result);
  8. }

构造wrapper条件删除

  1. @Test
  2. public void testdelete() {
  3. //第一种办法
  4. //DELETE FROM tb_user WHERE (password = ? AND age <= ?)
  5. QueryWrapper<User> wrapper1 = new QueryWrapper<>();
  6. wrapper1.eq("password", "123").le("age", 21);
  7. //第二种办法:直接面向对象 但是大于小于不好使用 单个删除建议使用方法二
  8. //DELETE FROM tb_user WHERE password=? AND age=?
  9. User user = new User();
  10. user.setPassword("123");
  11. user.setAge(21);
  12. QueryWrapper<User> wrapper2 = new QueryWrapper<>(user);
  13. int result = userMapper.delete(wrapper2);
  14. System.err.println(result);
  15. }

批量删除

  1. @Test
  2. public void testdeleteBatchIds() {
  3. //根据id批量删除
  4. //DELETE FROM tb_user WHERE id IN ( ? , ? )
  5. List<Long> longs = Arrays.asList(6L, 7L);
  6. userMapper.deleteBatchIds(longs);
  7. }

根据id更新

  1. @Test
  2. public void testupdateById() {
  3. User user = new User(9L, "zhuge", "111", "诸葛", 36, "zhuge@shu.com");
  4. int update = userMapper.updateById(user);
  5. //改变的行数
  6. System.err.println(update);
  7. }

根据条件更新====QueryWrapper

  1. @Test
  2. public void testupdate() {
  3. User user = new User();
  4. //设置参数
  5. user.setAge(29);
  6. QueryWrapper<User> wrapper = new QueryWrapper<>();
  7. //构建where条件user_name为zhuge的
  8. wrapper.eq("user_name", "zhuge");
  9. // UPDATE tb_user SET age=? WHERE user_name = ?
  10. int update = userMapper.update(user, wrapper);
  11. //改变的行数
  12. System.err.println(update);
  13. }

根据条件更新2====UpdateWrapper

  1. @Test
  2. public void testupdate2() {
  3. UpdateWrapper<User> wrapper = new UpdateWrapper<>();
  4. //构建where条件 user_name为zhuge并且 设置修改的参数
  5. wrapper.set("password", "abc456").eq("user_name", "zhuge");
  6. //UPDATE tb_user SET password = ? WHERE AND user_name = ?
  7. int update = userMapper.update(null, wrapper);
  8. System.err.println(update);
  9. }

5.2 mybatisPlus的查询

根据id查询

  1. @Test
  2. public void testselectById() {
  3. User user = userMapper.selectById(3L);
  4. System.err.println(user);
  5. }

查询所有

  1. @Test
  2. public void testSelect() {
  3. List<User> userList = userMapper.selectList(null);
  4. for (User user : userList) {
  5. System.out.println(user);
  6. }
  7. }

根据多个id批量查询

  1. @Test
  2. public void testSelectOne() {
  3. List<Long> longs = Arrays.asList(4L, 5L);
  4. List<User> users = userMapper.selectBatchIds(longs);
  5. users.forEach(System.out::println);
  6. }

根据条件查询一个

  1. @Test
  2. public void testSelectBatchIds() {
  3. //没有数据返回null 多条数据报错
  4. QueryWrapper<User> wrapper = new QueryWrapper<>();
  5. wrapper.eq("name", "张三");
  6. User user = userMapper.selectOne(wrapper);
  7. System.err.println(user);
  8. }

查询记录数

  1. @Test
  2. public void testSelectCount() {
  3. //所有记录数 wrapper 设为空即可
  4. //Integer integer = userMapper.selectCount(null);
  5. //查询年龄大于25岁的有多少人
  6. QueryWrapper<User> wrapper = new QueryWrapper<>();
  7. wrapper.gt("age", 25);
  8. Integer integer = userMapper.selectCount(wrapper);
  9. System.err.println(integer);
  10. }

分页查询

前题注入分页插件
  1. @Bean
  2. public PaginationInterceptor paginationInterceptor() {
  3. PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
  4. //注入sql分析插件(生产环境最好不用) 阻止全表更新
  5. List<ISqlParser> sqlParserList = new ArrayList<>();
  6. sqlParserList.add(new BlockAttackSqlParser());
  7. paginationInterceptor.setSqlParserList(sqlParserList);
  8. return paginationInterceptor;
  9. }

分页查询

  1. @Test
  2. public void testSelectPage() {
  3. //SELECT id, email AS mail, name, user_name, age FROM tb_user WHERE (age > ?) ORDER BY age ASC LIMIT ?,?
  4. //查询年龄大于20岁的第二页的数据
  5. QueryWrapper<User> wrapper = new QueryWrapper<>();
  6. wrapper.gt("age", 20).orderByAsc("age");
  7. //查询第二页数据 每页三条 current:0和1都是只第一页
  8. Page<User> page = new Page<>(2L, 3L);
  9. IPage<User> userIPage = userMapper.selectPage(page, wrapper);
  10. System.err.println("总记录:" + userIPage.getRecords().toString());
  11. System.err.println("总页数:" + userIPage.getPages());
  12. System.err.println("总条数:" + userIPage.getTotal());
  13. System.err.println("当前页:" + userIPage.getCurrent());
  14. System.err.println("页大小:" + userIPage.getSize());
  15. }
  1. 总记录:[User(id=3, userName=wangwu, password=null, name=王五, age=28, mail=test3@itcast.cn, address=null, version=1, deleted=0, sex=男), User(id=11, userName=sunce, password=null, name=孙策, age=28, mail=null, address=null, version=1, deleted=0, sex=男), User(id=20, userName=null, password=null, name=小乔, age=28, mail=null, address=null, version=1, deleted=0, sex=女)]
  2. 总页数:4
  3. 总条数:12
  4. 当前页:2
  5. 页大小:3

分页查询 只要记录 不需要记录数

  1. @Test
  2. public void testSelectPage2() {
  3. //查询年龄大于20岁的第二页的数据
  4. QueryWrapper<User> wrapper = new QueryWrapper<>();
  5. wrapper.gt("age", 20).orderByAsc("age");
  6. //查询第二页数据 每页三条 不查询总记录数
  7. //Page(long current, long size, boolean isSearchCount)
  8. Page<User> page = new Page<>(2L, 3L, false);
  9. IPage<User> userIPage = userMapper.selectPage(page, wrapper);
  10. System.err.println("总记录:" + userIPage.getRecords().toString());
  11. System.err.println("总页数:" + userIPage.getPages());
  12. System.err.println("总条数:" + userIPage.getTotal());
  13. System.err.println("当前页:" + userIPage.getCurrent());
  14. System.err.println("页大小:" + userIPage.getSize());
  15. }
  1. 总记录:[User(id=3, userName=wangwu, password=null, name=王五, age=28, mail=test3@itcast.cn, address=null, version=1, deleted=0, sex=男), User(id=11, userName=sunce, password=null, name=孙策, age=28, mail=null, address=null, version=1, deleted=0, sex=男), User(id=20, userName=null, password=null, name=小乔, age=28, mail=null, address=null, version=1, deleted=0, sex=女)]
  2. 总页数:0
  3. 总条数:0
  4. 当前页:2
  5. 页大小:3

自定义mapper.xml的使用

在yml文件中添加

  1. #配置自定义的mapper文件 (多表查询适用)
  2. mapper-locations: classpath*:mybatis/*.xml
  3. #配置实体对象扫描包===>在mapper.xml中简化使用
  4. type-aliases-package: com.hhz.mp.pojo

在resources中建,mybatis文件夹再在下面建立userMapper.xml

  1. <?xml version="1.0" encoding="UTF-8" ?>
  2. <!DOCTYPE mapper
  3. PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  4. "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  5. <mapper namespace="com.hhz.mp.mapper.UserMapper">
  6. <!--com.hhz.mp.pojo.User-->
  7. <select id="getById" resultType="User">
  8. select * from tb_user where id = #{id}
  9. </select>
  10. <select id="selectPageUser" resultType="User">
  11. select * from tb_user ${ew.customSqlSegment}
  12. </select>
  13. </mapper>

//在mapper.xml中写SQL
User getById(Long id);

  1. //自定义sql
  2. @Select("select * from tb_user ${ew.customSqlSegment}")
  3. List<User> selectAll(@Param(Constants.WRAPPER) Wrapper<User> wrapper);
  4. //自定义分页 在mapper.xml中写SQL
  5. IPage<User> selectPageUser(Page<User> page, @Param(Constants.WRAPPER) Wrapper<User> wrapper);

根据id查询

  1. @Test
  2. public void testSelectMapper() {
  3. User user = userMapper.getById(2L);
  4. System.out.println(user);
  5. }

自定义sql的使用

  1. @Test
  2. public void selectMy() {
  3. //SELECT * FROM tb_user WHERE age > ?
  4. QueryWrapper<User> wrapper = new QueryWrapper<>();
  5. wrapper.gt("age", 30);
  6. List<User> userList = userMapper.selectAll(wrapper);
  7. for (User user : userList) {
  8. System.out.println(user);
  9. }
  10. }

自定义分页

  1. @Test
  2. public void selectPageUser() {
  3. Page<User> page = new Page<>(1, 3);
  4. QueryWrapper<User> wrapper = new QueryWrapper<>();
  5. wrapper.gt("age", 25);
  6. IPage<User> userIPage = userMapper.selectPageUser(page, wrapper);
  7. System.err.println("总记录:" + userIPage.getRecords().toString());
  8. System.err.println("总条数:" + userIPage.getTotal());
  9. }

5.3 wrapper 条件构造器

allEq(Map params) 根据map给定字段的条件查询

  1. @Test
  2. public void testllEq() {
  3. //SELECT id, email AS mail, name, user_name, age FROM tb_user WHERE (password IS NULL AND user_name = ? AND age = ?)
  4. QueryWrapper<User> wrapper = new QueryWrapper<>();
  5. Map<String, Object> map = new HashMap<>();
  6. map.put("age", 24);
  7. map.put("user_name", "sunqi");
  8. map.put("password", null);
  9. wrapper.allEq(map);
  10. List<User> users = userMapper.selectList(wrapper);
  11. users.forEach(System.err::println);
  12. }

allEq(Map params, boolean null2IsNull) 根据map给定字段的条件查询 过滤字段为空的数据

  1. @Test
  2. public void testAllEq2() {
  3. //SELECT id, email AS mail, name, user_name, age FROM tb_user WHERE (user_name = ? AND age = ?)
  4. QueryWrapper<User> wrapper = new QueryWrapper<>();
  5. Map<String, Object> map = new HashMap<>();
  6. map.put("age", 24);
  7. map.put("user_name", "sunqi");
  8. map.put("password", null);
  9. wrapper.allEq(map, false);
  10. List<User> users = userMapper.selectList(wrapper);
  11. users.forEach(System.err::println);
  12. }
  1. @Test
  2. public void testAllEq3() {
  3. QueryWrapper<User> wrapper = new QueryWrapper<>();
  4. Map<String, Object> map = new HashMap<>();
  5. map.put("age", 24);
  6. map.put("user_name", "sunqi");
  7. map.put("password", null);
  8. wrapper.allEq((k, v) -> k.equals("age") || k.equals("name") || k.equals("password"), map, false);
  9. List<User> users = userMapper.selectList(wrapper);
  10. users.forEach(System.err::println);
  11. }

eq 等于
ge 大于等于
in 在范围内
gt 大于
lt 小于
le 小于等于
between 两个之间
isNotNULL 非空

  1. @Test
  2. public void testEq() {
  3. QueryWrapper<User> wrapper = new QueryWrapper<>();
  4. //SELECT id, email AS mail, name, user_name, age FROM tb_user WHERE (password = ? AND age >= ? AND name IN (?, ?, ?))
  5. wrapper.eq("password", "123456")
  6. .ge("age", 20)
  7. .in("name", "李四", "王五", "赵六");
  8. List<User> users = this.userMapper.selectList(wrapper);
  9. users.forEach(System.err::println);
  10. }

模糊查询like

  1. /**
  2. * 模糊查询
  3. * like(R column, Object val) LIKE '%值%'
  4. * like(boolean condition, R column, Object val)
  5. * likeLeft(boolean condition, R column, Object val) LIKE '%值'
  6. * likeRight(boolean condition, R column, Object val) LIKE '值%'
  7. */
  8. @Test
  9. public void testLike() {
  10. QueryWrapper<User> wrapper = new QueryWrapper<>();
  11. // wrapper.like("name", "孙");
  12. User user = new User();
  13. user.setName("孙");
  14. //condition 条件判断 如果为false 该条就会被忽略
  15. wrapper.like(StringUtils.isNotBlank(user.getName()), "name", "孙");
  16. List<User> userList = userMapper.selectList(wrapper);
  17. userList.forEach(System.err::println);
  18. }

排序

  1. /**
  2. * orderByAsc 默认顺序
  3. * orderByDesc 倒序
  4. */
  5. @Test
  6. public void testOrderBy() {
  7. QueryWrapper<User> wrapper = new QueryWrapper<>();
  8. //先按年龄倒序排序 年龄一致按照user_name
  9. wrapper.orderByDesc("age", "user_name");
  10. List<User> userList = userMapper.selectList(wrapper);
  11. userList.forEach(System.err::println);
  12. }

or 逻辑关联

  1. /**
  2. * Or 逻辑关联
  3. * 查找姓名为孙权或者年龄为20的人
  4. * SELECT id, email AS mail, name, user_name, age FROM tb_user WHERE (name = ? OR age = ?)
  5. */
  6. @Test
  7. public void testOr() {
  8. QueryWrapper<User> wrapper = new QueryWrapper<>();
  9. //先按年龄倒序排序 年龄一致按照user_name
  10. wrapper.eq("name", "孙权").or().eq("age", "20");
  11. List<User> userList = userMapper.selectList(wrapper);
  12. userList.forEach(System.err::println);
  13. }

条件逻辑关联

  1. /**
  2. * or(Function<Param, Param> func) 逻辑关联
  3. * 查找姓氏为李 或者 年龄28到30的女性
  4. * SELECT id, user_name, name, age, email AS mail, version, deleted, sex FROM tb_user WHERE deleted = 0 AND name LIKE ? OR (age BETWEEN ? AND ? AND sex = ?)
  5. */
  6. @Test
  7. public void testOr2() {
  8. QueryWrapper<User> wrapper = new QueryWrapper<>();
  9. //先按年龄倒序排序 年龄一致按照user_name
  10. wrapper.likeRight("name", "李").or(wrap -> wrap.between("age", 28, 30).eq("sex", SexEnum.WOMAN));
  11. List<User> userList = userMapper.selectList(wrapper);
  12. userList.forEach(System.err::println);
  13. }

select 选择需要的字段

  1. /**
  2. * select 选择需要的字段
  3. * SELECT name, age FROM tb_user
  4. */
  5. @Test
  6. public void testSelect() {
  7. QueryWrapper<User> wrapper = new QueryWrapper<>();
  8. //先按年龄倒序排序 年龄一致按照user_name
  9. wrapper.select("name", "age");
  10. List<User> userList = userMapper.selectList(wrapper);
  11. userList.forEach(System.err::println);
  12. }

select 排除字段

  1. /**
  2. * select 排除字段 deleted version email
  3. * SELECT id, user_name, password, name, age, sex FROM tb_user WHERE deleted = 0
  4. */
  5. @Test
  6. public void testSelect2() {
  7. QueryWrapper<User> wrapper = new QueryWrapper<>();
  8. //先按年龄倒序排序 年龄一致按照user_name
  9. wrapper.select(User.class, t -> !t.getColumn().equals("deleted") &&
  10. !t.getColumn().equals("version") &&
  11. !t.getColumn().equals("email")
  12. );
  13. List<User> userList = userMapper.selectList(wrapper);
  14. userList.forEach(System.err::println);
  15. }

apply 拼接 sql

  1. /**
  2. * apply
  3. * SELECT id, user_name, name, age, email AS mail, version, deleted, sex FROM tb_user WHERE deleted = 0 AND age BETWEEN ? AND ?
  4. * <p>
  5. * apply("date_format(dateColumn,'%Y-%m-%d') = {0}", "2008-08-08")--->date_format(dateColumn,'%Y-%m-%d') = '2008-08-08'")
  6. */
  7. @Test
  8. public void testApply() {
  9. QueryWrapper<User> wrapper = new QueryWrapper<>();
  10. //拼接sql, 可以直接在applySql中输入值,但是有注入风险 ,用{}方式会更好
  11. //wrapper.between("age", 30, 42);
  12. //wrapper.apply("age between 30 and 42");
  13. wrapper.apply("age between {0} and {1}", 30, 42);
  14. List<User> userList = userMapper.selectList(wrapper);
  15. userList.forEach(System.err::println);
  16. }

in

  1. /**
  2. * in
  3. * SELECT id, user_name, name, age, email AS mail, version, deleted, sex FROM tb_user WHERE deleted = 0 AND age IN (?, ?, ?)
  4. */
  5. @Test
  6. public void testIn() {
  7. QueryWrapper<User> wrapper = new QueryWrapper<>();
  8. wrapper.in("age", 20, 30, 40);
  9. List<User> userList = userMapper.selectList(wrapper);
  10. userList.forEach(System.err::println);
  11. }

inSql 子查询

  1. /**
  2. * inSql 子查询
  3. * 查询性别为女性并且和年龄和孙姓的有一样的
  4. * SELECT id, user_name, name, age, email AS mail, version, deleted, sex FROM tb_user WHERE deleted = 0 AND sex = ? AND age IN (SELECT age FROM tb_user WHERE name LIKE '孙%')
  5. */
  6. @Test
  7. public void testInSQL() {
  8. QueryWrapper<User> wrapper = new QueryWrapper<>();
  9. wrapper.eq("sex", SexEnum.WOMAN).inSql("age", "select age from tb_user where name like '孙%'");
  10. List<User> userList = userMapper.selectList(wrapper);
  11. userList.forEach(System.err::println);
  12. }

having

  1. /**
  2. * having
  3. */
  4. @Test
  5. public void testHaving() {
  6. QueryWrapper<User> wrapper = new QueryWrapper<>();
  7. wrapper.groupBy("id").having("age > {0}", 30);
  8. List<User> userList = userMapper.selectList(wrapper);
  9. userList.forEach(System.err::println);
  10. }

nested(Function func) 嵌套语句

  1. /**
  2. * nested(Function<Param, Param> func) 嵌套语句
  3. * 查询 姓名为李开头或者是女性 或 密码是888888的人
  4. * SELECT id, user_name, nme, age, email AS mail, version, deleted, sex FROM tb_user WHERE deleted = 0 AND (name LIKE ? OR (sex <> ?)) OR password = ?
  5. */
  6. @Test
  7. public void testNested() {
  8. QueryWrapper<User> wrapper = new QueryWrapper<>();
  9. wrapper.nested(wr -> wr.likeRight("name", "李").or(w -> w.ne("sex", SexEnum.MAN))).or().eq("password", "888888");
  10. List<User> userList = userMapper.selectList(wrapper);
  11. userList.forEach(System.err::println);
  12. }

last 在最后拼接语句

  1. /**
  2. * last 在最后拼接语句
  3. * SELECT id, user_name, name, age, email AS mail, version, deleted, sex FROM tb_user WHERE deleted = 0 LIMIT 2
  4. */
  5. @Test
  6. public void testLast() {
  7. QueryWrapper<User> wrapper = new QueryWrapper<>();
  8. wrapper.last("limit 2");
  9. List<User> userList = userMapper.selectList(wrapper);
  10. userList.forEach(System.err::println);
  11. }

exists

  1. /**
  2. * exists
  3. * 拼接exists语句 子查询 返回true或者false 作为条件应用到外层sql
  4. */
  5. @Test
  6. public void testExists() {
  7. //SELECT id, user_name, name, age, email AS mail, version, deleted, sex FROM tb_user WHERE deleted = 0 AND EXISTS (SELECT * FROM tb_user WHERE age > 60)
  8. QueryWrapper<User> wrapper = new QueryWrapper<>();
  9. wrapper.exists("select * from tb_user where age >60");
  10. List<User> userList = userMapper.selectList(wrapper);
  11. userList.forEach(System.err::println);
  12. }

5.3.2 wrapper Lambda条件构造器

lambda根据条件查询1

  1. @Test
  2. public void selectLambda() {
  3. //创建对象的三种方式
  4. LambdaQueryWrapper<User> lambda = new QueryWrapper<User>().lambda();
  5. LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
  6. LambdaQueryWrapper<User> lambdaQuery = Wrappers.lambdaQuery();
  7. //SELECT id, user_name, name, age, email AS mail, version, deleted, sex FROM tb_user WHERE deleted = 0 AND name LIKE ? AND age < ?
  8. lambdaQuery.like(User::getName, "李").lt(User::getAge, 40);
  9. List<User> users = userMapper.selectList(lambdaQuery);
  10. users.forEach(System.err::println);
  11. }

lambda根据条件查询2

  1. /**
  2. * lambda根据条件查询
  3. * 查询姓名为孙姓 并且 (年龄小于40或者邮箱不为空)
  4. * SELECT id, user_name, name, age, email AS mail, version, deleted, sex FROM tb_user WHERE deleted = 0 AND name LIKE ? AND (age < ? OR email IS NOT NULL)
  5. */
  6. @Test
  7. public void selectLambda2() {
  8. LambdaQueryWrapper<User> wrapper = new QueryWrapper<User>().lambda();
  9. wrapper.likeRight(User::getName, "孙")
  10. .and(e -> e.lt(User::getAge, 40).or().isNotNull(User::getMail));
  11. List<User> users = userMapper.selectList(wrapper);
  12. users.forEach(System.err::println);
  13. }

LambdaQueryChainWrapper

  1. /**
  2. * 3.0.7后的新的wrapper 可以直接返回结果
  3. * LambdaQueryChainWrapper
  4. */
  5. @Test
  6. public void selectLambda3() {
  7. List<User> list = new LambdaQueryChainWrapper<>(userMapper)
  8. .like(User::getName, "孙").list();
  9. list.forEach(System.err::println);
  10. }