一、什么是 MyBatis-Plus
官网地址:点击进入
MyBatis-Plys(简称 MP)是一个 MyBatis 的增强工具,在MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。
二、为什么要用 MyBatis-Plus
MP的特性:
- 无侵入: 只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑
- 损耗小: 启动即会自动注入基本的 CRUD,性能基本无损耗,直接面向对象操作
- 强大的 CRUD 操作: 通过 Lambda 表达式,方便的编写各类查询条件,无需再担心字段写错
- 支持主键自动生成: 支持多达4种主键策略(内含分布式唯一 ID 生成器 - Sequence),可自由配置,完美解决主键问题
- 支持 ActiveRecord 模式: 支持 ActiveRecord 形式调用,实体类只需要继承 Model 类即可进行强大的 CRUD 操作
- 支持自定义全局通用操作: 支持全局通用方法注入(Write once,use anywhere)
- 内置代码生成器: 采用代码或者 Maven 插件可快速生成Mapper、Model、Service、Controller 层代码,支持模板引擎,更有超多自定义配置等您来使用
- 内置分页插件: 基于MyBatis 物理分页,开发者无需关心具体操作,配置好插件之后,写分页等同于普通 List 查询
- 分页插件支持多种数据库: 支持MySQL、MariaDB、Oracle、DB2、H2、HSQL、SQLite、Postgre、SQL、Server等多种数据库
- 内置性能分析插件: 可输出 Sql 语句以及执行时间,建议开发测试时启用该功能,能快速揪出慢查询
- 内置全局拦截插件: 提供全表 delete、update 操作智能分析阻断,也可自定义拦截规则,预防误操作
支持数据库
- mysql 、mariadb 、oracle 、db2 、h2 、hsql 、sqlite 、postgresql 、sqlserver 、presto 、Gauss 、Firebird
- Phoenix 、clickhouse 、Sybase ASE 、 OceanBase 、达梦数据库 、虚谷数据库 、人大金仓数据库 、南大通用数据库
三、测试环境
3.1.创建并初始化数据库
CREATE DATABASE TQYL_MP
CREATE TABLE user
(
id BIGINT(20) NOT NULL COMMENT '主键ID',
name VARCHAR(30) NULL DEFAULT NULL COMMENT '姓名',
age INT(11) NULL DEFAULT NULL COMMENT '年龄',
email VARCHAR(50) NULL DEFAULT NULL COMMENT '邮箱',
PRIMARY KEY (id)
);
INSERT INTO user (id, name, age, email) VALUES
(1, 'Jone', 18, 'test1@baomidou.com'),
(2, 'Jack', 20, 'test2@baomidou.com'),
(3, 'Tom', 28, 'test3@baomidou.com'),
(4, 'Sandy', 21, 'test4@baomidou.com'),
(5, 'Billie', 24, 'test5@baomidou.com');
3.2.初始化 Spring Boot工程
- 步骤一:
- 步骤二:
- 步骤三:
后面就直接next
3.3.添加依赖
<!--简化代码的工具包-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency> <!--mybatis-plus的springboot支持-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.1.1</version>
</dependency> <!--mysql驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13</version>
<scope>test</scope>
</dependency>
3.4.application.yml
spring:
datasource:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/tqyl_mp?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC
username: root
password: 1234
3.5.编写 pojo
package com.tqyl.domain;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.persistence.Column;
import javax.persistence.Id;
import javax.persistence.Table;
import java.io.Serializable;
@Data
@NoArgsConstructor
@AllArgsConstructor
@Table(name = "`user`")
public class User implements Serializable {
/**
* 主键ID
*/
@Id
@Column(name = "id")
private Long id;
/**
* 姓名
*/
@Column(name = "`name`")
private String name;
/**
* 年龄
*/
@Column(name = "age")
private Integer age;
/**
* 邮箱
*/
@Column(name = "email")
private String email;
private static final long serialVersionUID = 1L;
}
3.6.Mapper
package com.tqyl.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.tqyl.domain.User;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface UserMapper extends BaseMapper<User> {
}
3.7.启动类
package com.tqyl;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@MapperScan("com.tqyl.dao")
@SpringBootApplication
public class TqylMpApplication {
public static void main(String[] args) {
SpringApplication.run(TqylMpApplication.class, args);
}
}
3.8.测试类
package com.tqyl;
import com.tqyl.dao.UserMapper;
import com.tqyl.domain.User;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.List;
/**
* @author 庭前云落
* @Date 2020/9/15 14:17
* @description
*/
@RunWith(SpringRunner.class)
@SpringBootTest
public class TqylTest {
@Autowired
private UserMapper userMapper;
@Test
public void testSelect(){
System.out.println("-----------华丽的分割线------------");
List<User> ulist = userMapper.selectList(null);
for (User user : ulist) {
System.out.println(user);
}
}
}
四、CRUD 接口
Mapper CRUD 接口
- 通用 CURD 封装 BaseMapper 接口,为
Mybatis-Plus
启动时自动解析实体表关系映射转换为Mybatis
内部对象注入容器- 泛型
T
为任意实体对象- 参数
Serializable
为任意类型主键Mybatis-Plus
不推荐使用复合主键约定每一张表都有自己的唯一id
主键- 对象
Wrapper
为条件构造器
1、Insert
// 插入一条记录
int insert(T entity);
TEST
@Test
public void testInsert(){
User user = new User();
user.setAge(20);
user.setEmail("WTINGSSS@outlook.com");
user.setName("庭前云落");
//返回的result是受影响的行数,并不是自增后的id
int result = userMapper.insert(user);
System.out.println("result="+result);
//自增后的id会回填到对象中
System.out.println(user.getId());
}
数据已经写入数据库,但是,id的值不正确,我们期望的是数据库自增长,实际是MP生成了 id的值,写入到了数据库。
如何设置 id 的生成策略呢?
MP 支持的 id 策略:
public enum IdType {
//数据库ID自增
AUTO(0),
//该类型为未设置主键类型
NONE(1),
//用户输入ID,该类型可以通过自己注册自动填充插件进行填充
INPUT(2),
/* 以下3种类型、只有当插入对象ID 为空,才自动填充。 */
/*** 全局唯一ID (idWorker) */
ID_WORKER(3),
/*** 全局唯一ID (UUID) */
UUID(4),
/*** 字符串全局唯一ID (idWorker 的字符串表示) */
ID_WORKER_STR(5);
private final int key;
private IdType(int key) {
this.key = key;
}
}
修改后的 User ID 类型:
数据插入成功:
扩展: @TableField
在MP中通过@TableField 注解可以指定字段的一些属性,常常解决的问题有2个:
1、对象中的属性名和字段名不一致的问题(非驼峰)
2、对象中的属性字段在表中不存在的问题
@TableField(value="email")//解决字段名不一致
@TableField(exist=false)//该字段在数据库表中不存在
2、UPDATE
// 根据 whereEntity 条件,更新记录
int update(@Param(Constants.ENTITY) T entity, @Param(Constants.WRAPPER) Wrapper<T> updateWrapper);
// 根据 ID 修改
int updateById(@Param(Constants.ENTITY) T entity);
类型 | 参数名 | 描述 |
---|---|---|
T | entity | 实体对象 (set 条件值,可为 null) |
Wrapper<T> | updateWrapper | 实体对象封装操作类(可以为 null,里面的 entity 用于生成 where 语句) |
根据 ID 修改
// 根据 ID 修改
int updateById(@Param(Constants.ENTITY) T entity);
测试:
@Test
public void testUpdateById(){
User user = new User();
user.setId(6L);//主键
user.setName("庭前云落的修改");
//根据id更新,更新不为null的字段
this.userMapper.updateById(user);
}
根据条件更新
// 根据 whereEntity 条件,更新记录
int update(@Param(Constants.ENTITY) T entity, @Param(Constants.WRAPPER) Wrapper<T> updateWrapper);
测试:
@Test
public void testUpdate(){
User user = new User();
//更新的字段
user.setAge(122);
//更新的条件
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.eq("id",6);
//执行更新操作
int result = userMapper.update(user, wrapper);
System.out.println("result="+result);
}
OR,通过 UpdateWrapper进行操作:
@Test
public void testUpdate2(){
//更新的条件
UpdateWrapper<User> wrapper = new UpdateWrapper<>();
wrapper.eq("id",6).set("age",23);
//执行更新操作
int result = userMapper.update(null,wrapper);
System.out.println("result="+result);
}
3、DELETE
// 根据 entity 条件,删除记录
int delete(@Param(Constants.WRAPPER) Wrapper<T> wrapper);
// 删除(根据ID 批量删除)
int deleteBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList);
// 根据 ID 删除
int deleteById(Serializable id);
// 根据 columnMap 条件,删除记录
int deleteByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap);
类型 | 参数名 | 描述 |
---|---|---|
Wrapper<T> | wrapper | 实体对象封装操作类(可以为 null) |
Collection<? extends Serializable> | idList | 主键ID列表(不能为 null 以及 empty) |
Serializable | id | 主键ID |
Map<String, Object> | columnMap | 表字段 map 对象 |
deleteById
// 根据 ID 删除
int deleteById(Serializable id);
@Test
public void testDeleteById(){
//执行删除操作
int result = userMapper.deleteById(6L);
System.out.println("result="+result);
}
deleteByMap
// 根据 columnMap 条件,删除记录
int deleteByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap);
public void testDeleteByMap(){
HashMap<String, Object> columnMap = new HashMap<>();
columnMap.put("age",20);
columnMap.put("name","Jack");
//将columnMap中的元素设置为删除的条件,多个之间为and关系
int result = userMapper.deleteByMap(columnMap);
System.out.println("result="+result);
}
delete
// 根据 entity 条件,删除记录
int delete(@Param(Constants.WRAPPER) Wrapper<T> wrapper);
@Test
public void testDelete(){
User user = new User();
user.setAge(21);
user.setName("Sandy");
//将实体对象进行包装,包装为操作条件
QueryWrapper<User> wrapper = new QueryWrapper<>(user);
int result = userMapper.delete(wrapper);
System.out.println("result="+result);
}
deleteBatchlds
// 删除(根据ID 批量删除)
int deleteBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList);
@Test
public void testDeleteBatchIds(){
//根据id集合批量删除
int result = userMapper.deleteBatchIds(Arrays.asList(1L, 3L, 5L));
System.out.println("result="+result);
}
4、SELECT
// 根据 ID 查询
T selectById(Serializable id);
// 根据 entity 条件,查询一条记录
T selectOne(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
// 查询(根据ID 批量查询)
List<T> selectBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList);
// 根据 entity 条件,查询全部记录
List<T> selectList(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
// 查询(根据 columnMap 条件)
List<T> selectByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap);
// 根据 Wrapper 条件,查询全部记录
List<Map<String, Object>> selectMaps(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
// 根据 Wrapper 条件,查询全部记录。注意: 只返回第一个字段的值
List<Object> selectObjs(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
// 根据 entity 条件,查询全部记录(并翻页)
IPage<T> selectPage(IPage<T> page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
// 根据 Wrapper 条件,查询全部记录(并翻页)
IPage<Map<String, Object>> selectMapsPage(IPage<T> page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
// 根据 Wrapper 条件,查询总记录数
Integer selectCount(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
类型 | 参数名 | 描述 |
---|---|---|
Serializable | id | 主键ID |
Wrapper<T> | queryWrapper | 实体对象封装操作类(可以为 null) |
Collection<? extends Serializable> | idList | 主键ID列表(不能为 null 以及 empty) |
Map<String, Object> | columnMap | 表字段 map 对象 |
IPage<T> | page | 分页查询条件(可以为 RowBounds.DEFAULT) |
selectById
// 根据 ID 查询
T selectById(Serializable id);
@Test
public void testSelectById(){
//根据id查询数据
User user = userMapper.selectById(2L);
System.out.println("result="+user);
}
selectBatchlds
// 查询(根据ID 批量查询)
List<T> selectBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList);
@Test
public void testSelectBatchIds() {
//根据id集合批量查询
List<User> ulist = userMapper.selectBatchIds(Arrays.asList(2L, 3L, 1L));
for (User user : ulist) {
System.out.println(user);
}
}
selectOne
// 根据 entity 条件,查询一条记录
T selectOne(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
@Test
public void testSelectOne(){
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.eq("name","Jone");
//根据条件查询一条数据,如果结果超过一条会报错
User user = userMapper.selectOne(wrapper);
System.out.println(user);
}
selectCount
/**
* 根据 Wrapper 条件,查询总记录数
*
* @param queryWrapper 实体对象封装操作类(可以为 null)
*/
Integer selectCount(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
@Test
public void testSelectCount(){
QueryWrapper<User> wrapper = new QueryWrapper<>();
//年龄大于23岁
wrapper.gt("age",23);
//根据条件查询数据条数
Integer count = userMapper.selectCount(wrapper);
System.out.println("count="+count);
}
selectList
// 根据 entity 条件,查询全部记录
List<T> selectList(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
@Test
public void testSelectList(){
QueryWrapper<User> wrapper = new QueryWrapper<>();
//年龄大于23岁
wrapper.gt("age",23);
//根据条件查询数据
List<User> ulist = userMapper.selectList(wrapper);
for (User user : ulist) {
System.out.println("user="+user);
}
}
selectPage
/**
* 根据 entity 条件,查询全部记录(并翻页)
*
* @param page 分页查询条件(可以为 RowBounds.DEFAULT)
* @param queryWrapper 实体对象封装操作类(可以为 null)
*/
IPage<T> selectPage(IPage<T> page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
配置分页插件:
package com.tqyl.config;
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;
/**
* @author 庭前云落
* @Date 2020/9/16 9:40
* @description
*/
@Configuration
@MapperScan("com.tqyl.dao")//设置mapper接口的扫描包
public class MybatisPlusConfig {
/**
* 分页插件
*/
@Bean
public PaginationInterceptor paginationInterceptor(){
return new PaginationInterceptor();
}
}
测试用例:
@Test
public void testSelectPage(){
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.gt("age",20);
Page<User> page = new Page<>(1, 3);
//根据条件查询数据
IPage<User> iPage = userMapper.selectPage(page, wrapper);
System.out.println("数据总体数:"+iPage.getTotal());
System.out.println("总页数:"+iPage.getPages());
List<User> ulist = iPage.getRecords();
for (User user : ulist) {
System.out.println("user="+user);
}
}
五、SQL注入器
注入器配置
全局配置
sqlInjector
用于注入ISqlInjector
接口的子类,实现自定义方法注入
-
SQL自动注入器接口
ISqlInjector
public interface ISqlInjector { /** * <p> * 检查SQL是否注入(已经注入过不再注入) * </p> * * @param builderAssistant mapper 信息 * @param mapperClass mapper 接口的 class 对象 */ void inspectInject(MapperBuilderAssistant builderAssistant, Class<?> mapperClass); }
自定义自己的通用方法可以实现接口
ISqlInjector
也可以继承抽象类AbstractSqlInjector
注入通用方法SQL 语句
然后继承BaseMapper
添加到自定义方法,全局配置sqlInjector
注入 MP会自动讲类所有方法注入到mybatis
容器中。
六、条件构造器
说明
以下出现的第一个入参
boolean condition
表示该条件是否加入最后生成的 sql 中以下代码块内的多个方法均从上往下补全个别
boolean
类型的入参,默认为true
以下方法在入参中出现的
R
为泛型,普通 wrapper 中是String
,在LambdaWrapper中是函数(例:
Entity::getId,Entity
为实体类,getId
为字段id
的 getMethodsd)以下方法入参中的
R column
均表示数据库字段,当R
具体类型为String
时则为数据库字段名(字段名是数据库关键字的自己用转义符包裹!)!而不是实体类数据字段名!!!,另当R
具体类型为SFunction
时项目runtime不支持eclipse自家的编译器!!!以下举例均为使用普通wrapper,入参为
Map
和List
的均以json
形式表现!使用中如果入参的
Map
或者List
为空,则不会加入最后生成的sql中!!!
allEq
allEq(Map<R, V> params)
allEq(Map<R, V> params, boolean null2IsNull)
allEq(boolean condition, Map<R, V> params, boolean null2IsNull)
- 全部eq(或个别 isNull)
个别参数说明:
params
:key
为数据库字段名,value
为字段值null2IsNull
: 为true
则在map
的value
为null
时调用 isNull 方法,为false
时则忽略value
为null
的
- 例1:
allEq({id:1,name:"老王",age:null})
--->id = 1 and name = '老王' and age is null
- 例2:
allEq({id:1,name:"老王",age:null}, false)
--->id = 1 and name = '老王'
allEq(BiPredicate<R, V> filter, Map<R, V> params)
allEq(BiPredicate<R, V> filter, Map<R, V> params, boolean null2IsNull)
allEq(boolean condition, BiPredicate<R, V> filter, Map<R, V> params, boolean null2IsNull)
个别参数说明:
filter
:过滤函数,是否允许字段传入对比条件中
params
与null2IsNull
:同上
- 例1:
allEq((k,v) -> k.indexOf("a") >= 0, {id:1,name:"老王",age:null})
--->name = '老王' and age is null
- 例2:
allEq((k,v) -> k.indexOf("a") >= 0, {id:1,name:"老王",age:null}, false)
--->name = '老王'
测试
@Test
public void testAllEq() {
QueryWrapper<User> wrapper = new QueryWrapper<>();
//设置条件
HashMap<String, Object> params = new HashMap<>();
params.put("name", "Jack");
params.put("age", 20);
params.put("email", null);
//SELECT * FROM tb_user WHERE password IS NULL AND name = ? AND age = ?
wrapper.allEq(params);
//SELECT * FROM tb_user WHERE name = ? AND age = ?
wrapper.allEq(params, false);
//SELECT * FROM tb_user WHERE name = ? AND age = ?
wrapper.allEq(k, v)->(k.equals("name") || k.equals("age")), params);
List<User> users = this.userMapper.selectList(wrapper);
for (User user : users) {
System.out.println(user);
}
6.1.基本比较操作
- eq
- 等于 =
- 例:
eq("name", "老王")
--->name = '老王'
eq(R column, Object val)
eq(boolean condition, R column, Object val)
- ne
- 不等于 <>
- 例:
ne("name", "老王")
--->name <> '老王'
ne(R column, Object val)
ne(boolean condition, R column, Object val)
- gt
- 大于 >
- 例:
gt("age", 18)
--->age > 18
gt(R column, Object val)
gt(boolean condition, R column, Object val)
- ge
- 大于等于 >=
- 例:
ge("age", 18)
--->age >= 18
ge(R column, Object val)
ge(boolean condition, R column, Object val)
- lt
- 小于 <
- 例:
lt("age", 18)
--->age < 18
lt(R column, Object val)
lt(boolean condition, R column, Object val)
- le
- 小于等于 <=
- 例:
le("age", 18)
--->age <= 18
le(R column, Object val)
le(boolean condition, R column, Object val)
- between
- BETWEEN 值1 AND 值2
- 例:
between("age", 18, 30)
--->age between 18 and 30
between(R column, Object val1, Object val2)
between(boolean condition, R column, Object val1, Object val2)
- notBetween
- NOT BETWEEN 值1 AND 值2
- 例:
notBetween("age", 18, 30)
--->age not between 18 and 30
notBetween(R column, Object val1, Object val2)
notBetween(boolean condition, R column, Object val1, Object val2)
- in
- 字段 IN (value.get(0), value.get(1), ...)
- 例:
in("age",{1,2,3})
--->age in (1,2,3)
in(R column, Collection<?> value)
in(boolean condition, R column, Collection<?> value)
- 字段 IN (v0, v1, ...)
- 例:
in("age", 1, 2, 3)
--->age in (1,2,3)
in(R column, Object... values)
in(boolean condition, R column, Object... values)
- notIn
- 字段 NOT IN (value.get(0), value.get(1), ...)
- 例:
notIn("age",{1,2,3})
--->age not in (1,2,3)
notIn(R column, Collection<?> value)
notIn(boolean condition, R column, Collection<?> value)
- 字段 NOT IN (v0, v1, ...)
- 例:
notIn("age", 1, 2, 3)
--->age not in (1,2,3)
notIn(R column, Object... values)
notIn(boolean condition, R column, Object... values)
测试
@Test
public void testEq() {
QueryWrapper<User> wrapper = new QueryWrapper<>();
//SELECT id,name,age,email FROM tb_user WHERE email = ? AND age >= ? AND name IN (?,?,?)
wrapper.eq("email", "test1@baomidou.com").ge("age", 20).in("name", "Jack", "Tom", "Sandy");
List<User> ulist = userMapper.selectList(wrapper);
for (User user : ulist) {
System.out.println(ulist);
}
}
6.2.模糊查询
- like
- LIKE ' %值%'
- 例:
like("name","王")
-->name like '%王%'
like(R column, Object val)
like(boolean condition, R column, Object val)
- notLike
- NOT LIKE '%值%'
- 例:
notLike("name","王")
-->name like '%王'
notLike(R column, Object val)
notLike(boolean condition, R column, Object val)
- likeLeft
- LIKE '%值'
- 例:
likeLeft("name", "王") ---> name like '%王'
likeLeft(R column, Object val)
likeLeft(boolean condition, R column, Object val)
- likeRight
- LIKE '值%'
- 例:
likeRight("name","王")
-->name like '王%'
likeRight(R column, Object val)
likeRight(boolean condition, R column, Object val)
测试
@Test
public void testLike() {
QueryWrapper<User> wrapper = new QueryWrapper<>();
// SELECT id,name,age,email FROM tb_user WHERE name LIKE ?
// Parameters: %J%(String)
wrapper.like("name","J");
List<User> ulist = userMapper.selectList(wrapper);
for (User user : ulist) {
System.out.println(user);
}
}
6.3.排序
-
order By
- 排序:ORDER BY 字段...
- 例:
orderBy(true, true, "id", "name") ---> order by id ASC,name ASC
orderBy(boolean condition, boolean isAsc, R... columns)
-
orderByAsc
- 排序:ORDER BY 字段,.... ASC
- 例:
orderByAsc("id", "name") ---> order by id ASC,name ASC
orderByAsc(R... columns) orderByAsc(boolean condition, R... columns)
-
orderByDesc
- 排序:ORDER BY 字段,... DESC
- 例:
orderByDesc("id", "name") ---> order by id DESC,name DESC
orderByDesc(R... columns) orderByDesc(boolean condition, R... columns)
@Test public void testOrder(){ QueryWrapper<User> wrapper = new QueryWrapper<>(); //SELECT id,user_name,name,age,email FROM tb_user ORDER BY age DESC wrapper.orderByDesc("age"); List<User> ulist = userMapper.selectList(wrapper); for (User user : ulist) { System.out.println(user); } }
6.4.逻辑查询
- or
- 拼接 OR
- 主动调用 or 表示紧接着下一个方法不是用 and 连接!(不调用 or 则默认为使用 and 连接)
- and
- AND 嵌套
- 例:
and(i -> i.eq("name", "李白").ne("status", "活着")) ---> and (name = '李白' and status <> '活着')
@Test
public void testAndOr() {
QueryWrapper<User> wrapper = new QueryWrapper<>();
//SELECT id,name,age,email FROM tb_user WHERE name = ? OR age = ?
wrapper.eq("name", "Jone").or().eq("age", 18);
List<User> ulist = userMapper.selectList(wrapper);
for (User user : ulist) {
System.out.println(ulist);
}
}