Mybatis-Plus(简称MP)是一个 Mybatis 的增强工具,在 Mybatis 的基础上只做增强不做改变,为简化开发、提高效率而生。
CREATE TABLE `employee` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`name` varchar(255) DEFAULT NULL,
`password` varchar(255) DEFAULT NULL,
`email` varchar(255) DEFAULT NULL,
`age` int(11) DEFAULT NULL,
`admin` bit(1) DEFAULT NULL,
`dept_id` bigint(20) DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC;
这里是用 SpringBoot 集成 Mybatis-Plus 需要引入的依赖,自己可以根据需求自己添加依赖。
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0modelVersion>
<groupId>mybatis-plusgroupId>
<artifactId>mybatis-plus-demoartifactId>
<version>1.0.1version>
<packaging>jarpackaging>
<parent>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-parentartifactId>
<version>2.4.3version>
parent>
<dependencies>
<dependency>
<groupId>com.baomidougroupId>
<artifactId>mybatis-plus-boot-starterartifactId>
<version>3.4.0version>
dependency>
<dependency>
<groupId>com.alibabagroupId>
<artifactId>druid-spring-boot-starterartifactId>
<version>1.1.17version>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<version>8.0.22version>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-testartifactId>
dependency>
<dependency>
<groupId>org.projectlombokgroupId>
<artifactId>lombokartifactId>
<version>1.18.16version>
<scope>providedscope>
dependency>
dependencies>
project>
Spring 整合 Mybatis-plus 很简单,只需把mybatis的依赖换成mybatis-plus的依赖,再把sqlSessionFactory换成mybatis-plus的即可;下面只给出核心依赖,自己根据需求引入其他依赖。本项目还需要的依赖有:mysql驱动、Druid、日志(slf4j-api,slf4j-log4j2)、lombok。集成mybatis-plus要把mybatis、mybatis-spring去掉,避免冲突。
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-contextartifactId>
<version>4.3.14.RELEASEversion>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-ormartifactId>
<version>4.3.14.RELEASEversion>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-testartifactId>
<version>4.3.14.RELEASEversion>
<scope>testscope>
dependency>
<dependency>
<groupId>com.baomidougroupId>
<artifactId>mybatis-plusartifactId>
<version>2.3version>
dependency>
server.port=8888
#mysql
spring.datasource.url=jdbc:mysql://localhost:3306/mybatis-plus?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2b
spring.datasource.username=root
spring.datasource.password=admin
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
# mybatis 配置 slq 打印日志
#logging.level.com.yy.mp.mapper=debug
# mybatis-plus 配置 slq 打印日志
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
package com.yy.mp.domain;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
@Data
// @TableName("t_employee") // 表名映射注解,当类名跟表名不一致时使用
public class Employee {
// mybatis-plus id 策略默认是使用雪花算法(随机生成一组唯一的数字)
@TableId(type = IdType.AUTO) // id注解,指定 id生成算法(AUTO 为数据表自增)
private Long id;
// @TableField("name") // 列名映射注解,当属性名跟列名不一致时使用
private String name;
private String password;
private String email;
private int age;
private Boolean admin;
private Long deptId;
@TableField(exist = false) // 当表中没有该列时使用
private int sex; // 表中没有的列
@TableField(exist = false)
private Department dept;
}
public interface EmployeeMapper extends BaseMapper<Employee> {
}
@SpringBootApplication
@MapperScan(basePackages = "com.yy.mp.mapper")
public class App {
}
@TableName(“t_employee”)
描述:表名注解;
作用:当表名与类名不一致时使用,指定当前实体类映射哪张数据库表, 默认是跟实体类名一致;
@TableName("t_employee") // 表名映射注解,当类名跟表名不一致时使用
public class Employee {
}
@TableId(value=“id”, type= IdType.AUTO)
描述:主键注解;
作用:标记当前属性为映射表主键,type = IdType.AUTO 指定 id 生成算法(AUTO 为数据表自增);
@TableId(type = IdType.AUTO) // id注解,指定 id生成算法(AUTO 为数据表自增)
private Long id;
@TableField(value=“employename”,exist = false)
描述:字段注解(非主键);
作用:当属性名跟列名不一致时使用,指定当前属性映射数据库表哪一列, 默认是跟属性名一致;
@TableField("name") // 列名映射注解,当属性名跟列名不一致时使用
private String name;
@Version
描述:乐观锁注解、标记 @Verison 在字段上
作用:用于标记乐观锁操作字段
# mybatis 配置 slq 打印日志
#logging.level.com.yy.mp.mapper=debug
# mybatis-plus 配置 slq 打印日志
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
// 需求:添加一条用户信息
// 打印的SQL语句:INSERT INTO employee ( name, password, email, age, admin, dept_id ) VALUES ( ?, ?, ?, ?, ?, ? )
@Test
public void testSave(){
Employee employee = new Employee();
employee.setAdmin(true);
employee.setAge(18);
employee.setDeptId(1L);
employee.setEmail("yanyang@wolfcode");
employee.setName("yanyang");
employee.setPassword("111");
employeeMapper.insert(employee);
}
// 需求: 将 id=20 用户名字修改为 yy
// 打印的SQL语句:UPDATE employee SET name=?, age=? WHERE id=?
@Test
public void testUpdateById() {
Employee employee = new Employee();
employee.setId(20L);
employee.setName("yy");
employeeMapper.updateById(employee);
}
注意:基本数据类型默认值的存在导致属性参与 sql 拼接,引起参数丢失问题
参数实体属性值如果为 null,不参与 sql 拼接;
如果参数实体属性类型是 8 大基本数据类型,有不为 null 的默认值,mybatis-plus 认为有属性值,参数参与 sql 拼接;
解决:
方案一:将基本数据类型属性改为包装类型;
方案二:1> 先查询得到整条数据;2> 修改该条数据上想要修改的字段;3> 更新整条数据;
方案三:使用 update(null,wrapper)方法操作,部分字段更新方法;
// 需求: 将 id=20 用户名字修改为 yy
// 打印的SQL语句:UPDATE employee SET name=? WHERE (id = ?)
// 部分字段更新
@Test
public void testUpdate() {
// 条件构造器:暂时理解 where 条件拼接逻辑
UpdateWrapper<Employee> wrapper = new UpdateWrapper<>();
wrapper.eq("id", 20L); // 等价于:where id = 20
wrapper.set("name", "yy"); // 等价于:set name = yy
employeeMapper.update(null, wrapper);
}
updateById(entry)
1> sql 的 where 条件是 id 时使用;
2> 全部字段更新时使用;
update(null, wrapper)
1> sql 的 where 条件不一定是 id 时使用,例如 eg:where age > 19;
2> 部分字段更新时使用;
// 需求:删除 id = 20 的员工信息
// 打印的SQL语句:DELETE FROM employee where id = ?
@Test
public void testDeleteById() {
employeeMapper.deleteById(20L);
}
// 需求:删除 id=21,id=22 的员工信息
// 打印的SQL语句:DELETE FROM employee WHERE id IN ( ? , ? )
@Test
public void deleteBatchIds() {
employeeMapper.deleteBatchIds(Arrays.asList(21L, 22L));
}
// 需求:删除 name=yanyang 且 age=18 的员工信息
// 打印的SQL语句:DELETE FROM employee WHERE name = ? AND age = ?
@Test
public void testDeleteByMap() {
// key:条件对应的表列;value:条件对应的表值
Map<String, Object> map = new HashMap<>();
map.put("name", "yanyang");
map.put("age", 18);
employeeMapper.deleteByMap(map);
}
// 需求:删除 name=yanyang 且 age=18 的员工信息
// 打印的SQL语句:DELETE FROM employee WHERE (name = ? AND age = ?)
@Test
public void testDelete() {
// updateWrapper:更新操作使用
// QueryWrapper:查询条件使用
QueryWrapper<Employee> wrapper = new QueryWrapper<>();
wrapper.eq("name", "yanyang");
wrapper.eq("age", 18);
employeeMapper.delete(wrapper);
}
// 需求:查询 id=1 的员工信息
// 打印的SQL语句:SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE id=?
@Test
public void testSelectById() {
Employee employee = employeeMapper.selectById(1L);
System.out.println("employee = " + employee);
}
// 需求:查询 id=1,id=2 的员工信息
// 打印的SQL语句:SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE id IN ( ? , ? )
@Test
public void selectBatchIds() {
List<Employee> employees = employeeMapper.selectBatchIds(Arrays.asList(1L, 2L));
employees.forEach(System.out::println);
}
// 需求:查询 name=yanyang,且 age=18 的员工信息
// 打印的SQL语句:SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE name = ? AND age = ?
@Test
public void selectByMap() {
// key:条件对应的表列;value:条件对应的表值
Map<String, Object> map = new HashMap<>();
map.put("name", "yanyang");
map.put("age", 18);
List<Employee> employee = employeeMapper.selectByMap(map);
System.out.println("employee = " + employee);
}
// 需求:查询所有员工个数
// 打印的SQL语句:SELECT COUNT( 1 ) FROM employee
@Test
public void selectCount() {
// 没有条件查询所有
Integer count = employeeMapper.selectCount(null);
System.out.println("count = " + count);
}
// 需求:查询所有员工信息,返回 List
// 打印的SQL语句:SELECT id,name,password,email,age,admin,dept_id FROM employee
@Test
public void selectList() {
// 如果加 wrapper 表示条件查询,如果为 null,表示查询所有
List<Employee> employees = employeeMapper.selectList(null);
employees.forEach(System.out::println);
}
// 需求:查询所有员工信息,返回 List
// 打印的SQL语句:SELECT id,name,password,email,age,admin,dept_id FROM employee
@Test
public void selectMaps() {
// 如果加 wrapper 表示条件查询,如果为 null,表示查询所有
List<Map<String, Object>> employees = employeeMapper.selectMaps(null);
for (Map<String, Object> employee : employees) {
System.out.println("employee = " + employee);
}
}
@SpringBootApplication
@MapperScan(basePackages = "com.yy.mp.mapper")
public class App {
// 分页拦截器
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
PaginationInnerInterceptor paginationInnerInterceptor = new PaginationInnerInterceptor(DbType.MYSQL);
interceptor.addInnerInterceptor(paginationInnerInterceptor); // 合理化
return interceptor;
}
public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
}
// 7.需求:查询第 2 页员工数据,每页显示 3 条,(分页返回数据是实体对象)
// 打印的SQL语句:SELECT id,name,password,email,age,admin,dept_id FROM employee LIMIT ?,?
@Test
public void selectPage() {
// mybatis-plus 分页2个步骤
// 步骤1:配置分页插件(主配置类 / 启动类)
// 步骤2:编写分页代码
// 参数1:当前页,参数2:每页显示条数
IPage<Employee> page = new Page<>(2L, 3L);
// 参数1:分页参数对象,参数2:wrapper 条件对象(条件构造器)
IPage<Employee> page1 = employeeMapper.selectPage(page, null);
System.out.println(page1 == page);
System.out.println("当前页:" + page.getCurrent());
System.out.println("每页显示条数:" + page.getSize());
System.out.println("总页数:" + page.getPages());
System.out.println("总数:" + page.getTotal());
System.out.println("当前页数据:" + page.getRecords());
}
函数名 | 含义 | 例子 |
---|---|---|
eq | 等于 = | eq(“name”, “yy”):name = “yy” |
ne | 不等于 <> | ne(“name”, “yy”):name <> “yy” |
gt | 大于 > | gt(“age”, 18):age > 18 |
ge | 大于等于 >= | ge(“age”, 18):age >= 18 |
lt | 小于 < | lt(“age”, 18):age < 18 |
le | 小于等于 <= | le(“age”, 18):age <= 18 |
allEq | 所有等于 | allEq(map):map中条件都成立 |
between | between value1 and value2 | between(“age”, 18, 30):年龄在 18 ~ 30 之间 |
notBetween | not between value1 and value2 | notBetween(“age”, 18, 30):年龄不在在 18 ~ 30 之间 |
like | like ‘%value%’ | like(“name”, “yy”):name like %yy% |
notLike | not like ‘%value%’ | notLike(“name”, “yy”):name not like %yy% |
likeLeft | like ‘%value’ | likeLeft(“name”, “yy”):name like %yy |
likeRight | like ‘value%’ | likeRight(“name”, “yy”):name like yy% |
isNull | 字段 is null | isNull(“dept_id”):dept_id is null |
isNotNull | 字段 is not null | isNotNull(“dept_id”):dept_id is not null |
in | 字段 in(value1, value2…) | in(“id”, 1L, 2L):id in (1L,2L) |
notIn | 字段 not in(value1, value2…) | not in(“id”, 1L, 2L):id not in (1L,2L) |
inSql | 字段 in (sql 语句) | inSql(“id”, “1, 2”):id in (1,2),sql片段 |
notInSql | 字段 not in (sql 语句) | notinsql(“id”, “1, 2”):id ont in (1,2),sql片段 |
groupBy | 分组查询 | groupBy(“dept_id”):GROUP BY dept_id |
orderByAsc | 正序排序 | orderByAsc(“age”):ORDER BY age ASC |
orderByDesc | 逆序排序 | orderByDesc(“id”):ORDER BY id DESC |
orderBy | 默认正序排序 | orderBy(true, true, “age”):param1:条件,param2:isAsc,param3:列名 |
having | having (条件) | having(“count > 3”):HAVING count > 3(sql 片段) having(“count > {0}”, 3):HAVING count > ?(s占位符的方式) |
or | 拼接 or | eq(“age”, 18).or().eq(“name”, “yy”):(age = 18 OR name = “yy”) |
and | 拼接 and (默认) | eq(“age”, 18).eq(“name”, “yy”):(age >= 18 AND name = “yy”) |
nested | 正常嵌套,不带 and 或者 or | |
apply | 拼接 sql | |
last | 无视优化规则直接凭借到 sql 的最后 | |
exists | 拼接 exists (sql 语句) | |
notExists | 拼接 not exists (sql 语句) |
@SpringBootTest
public class QueryTest {
@Autowired(required = false)
private EmployeeMapper employeeMapper;
}
// 1.需求: 将 name=yanyang 且 age=18 的用户名字修改为 yy
// 打印的SQL语句:UPDATE employee SET name=? WHERE (name = ? AND age = ?)
@Test
public void testUpdate() {
UpdateWrapper<Employee> wrapper = new UpdateWrapper<>();
wrapper.eq("name", "yanyang").eq("age", 18);
// 占位符的形式,预编译
wrapper.set("name", "yy");
employeeMapper.update(null, wrapper);
}
// 2.需求: 将 name=yanyang 且 age=18 的用户名字修改为 yy
// 打印的SQL语句:UPDATE employee SET name = 'yy' WHERE (name = ? AND age = ?)
@Test
public void testUpdateWrapper() {
UpdateWrapper<Employee> wrapper = new UpdateWrapper<>();
wrapper.eq("name", "yanyang").eq("age", 18);
// 拼接 sql 片段,直接塞
wrapper.setSql("name = 'yy'");
employeeMapper.update(null, wrapper);
}
// 3.需求: 将 name=yanyang 且 age=18 的用户名字修改为 yy(推荐使用)
// 打印的SQL语句:UPDATE employee SET name=? WHERE (name = ? AND age = ?)
@Test
public void testLambdaUpdateWrapper() {
LambdaUpdateWrapper<Employee> wrapper = new LambdaUpdateWrapper<>();
wrapper.eq(Employee::getName, "yanyang").eq(Employee::getAge, 18);
// 占位符的形式,预编译
wrapper.set(Employee::getName, "yy");
employeeMapper.update(null, wrapper);
}
// 1.需求:查询 name=yy,age=18 的用户
// 打印的SQL语句:SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE (name = ? AND age = ?)
@Test
public void testQueryWrapper() {
QueryWrapper<Employee> wrapper = new QueryWrapper<>();
wrapper.eq("name", "yy").eq("age", 18);
List<Employee> employees = employeeMapper.selectList(wrapper);
employees.forEach(System.out::println);
}
// 2.需求:查询 name=yy,age=18 的用户(推荐使用)
// 打印的SQL语句:SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE (name = ? AND age = ?)
@Test
public void testLambdaQueryWrapper() {
LambdaQueryWrapper<Employee> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(Employee::getName, "yy").eq(Employee::getAge, 18);
List<Employee> employees = employeeMapper.selectList(wrapper);
employees.forEach(System.out::println);
}
@Test
public void testWrappers() {
// Query
QueryWrapper<Employee> queryWrapper1 = new QueryWrapper<>();
QueryWrapper<Employee> queryWrapper2 = Wrappers.<Employee>query();
LambdaQueryWrapper<Employee> lambdaQueryWrapper1 = new LambdaQueryWrapper<>();
LambdaQueryWrapper<Employee> lambdaQueryWrapper2 = Wrappers.<Employee>lambdaQuery();
LambdaQueryWrapper<Employee> lambdaQueryWrapper3 = queryWrapper1.lambda();
// Update
UpdateWrapper<Employee> updateWrapper1 = new UpdateWrapper<>();
UpdateWrapper<Employee> updateWrapper2 = Wrappers.<Employee>update();
LambdaUpdateWrapper<Employee> lambdaUpdateWrapper1 = new LambdaUpdateWrapper<>();
LambdaUpdateWrapper<Employee> lambdaUpdateWrapper2 = Wrappers.<Employee>lambdaUpdate();
LambdaUpdateWrapper<Employee> lambdaUpdateWrapper3 = updateWrapper1.lambda();
}
@SpringBootTest
public class QueryTest {
@Autowired(required = false)
private EmployeeMapper employeeMapper;
}
// 1.需求:查询所有员工,返回员工 name,age 列
// 打印的 SQL:SELECT name, age FROM employee
@Test
public void testQuery() {
QueryWrapper<Employee> wrapper = new QueryWrapper<>();
wrapper.select("name", "age"); // 挑选显示
// wrapper.select("name, age"); // sql 片段
List<Employee> employees = employeeMapper.selectList(wrapper);
employees.forEach(System.out::println);
}
// 1.需求:查询所有员工信息按 age 正序排序,如果 age 一样,按 id 倒叙排序
// 打印的 SQL:SELECT id,name,password,email,age,admin,dept_id FROM employee ORDER BY age ASC,id DESC
@Test
public void testOrderBy() {
QueryWrapper<Employee> wrapper = new QueryWrapper<>();
wrapper.orderByAsc("age");
wrapper.orderByDesc("id");
List<Employee> employees = employeeMapper.selectList(wrapper);
employees.forEach(System.out::println);
}
// 2.需求:查询所有员工信息按 age 正序排序
// 打印的 SQL:SELECT id,name,password,email,age,admin,dept_id FROM employee ORDER BY age ASC
@Test
public void testOrderBy2() {
QueryWrapper<Employee> wrapper = new QueryWrapper<>();
// 参数1:true:执行排序逻辑,false:不执行排序逻辑
// 参数2:true:正序排序,false:倒序排序
// 参数3:排序的列
wrapper.orderBy(true, true, "age");
List<Employee> employees = employeeMapper.selectList(wrapper);
employees.forEach(System.out::println);
}
// 3.需求:以部门 id 进行分组查询,查每个部门员工个数
// 打印的 SQL:SELECT dept_id,count(id) count FROM employee GROUP BY dept_id
@Test
public void testGroupBy() {
QueryWrapper<Employee> wrapper = new QueryWrapper<>();
wrapper.select("dept_id", "count(id) count");
wrapper.groupBy("dept_id");
List<Map<String, Object>> mapList = employeeMapper.selectMaps(wrapper);
mapList.forEach(System.out::println);
}
// 4.需求:以部门 id 进行分组查询,查每个部门员工个数,将大于 3 人的部门过滤出来
// 打印的 SQL:SELECT dept_id,count(id) count FROM employee GROUP BY dept_id HAVING count > 3(sql 片段)
// 打印的 SQL:SELECT dept_id,count(id) count FROM employee GROUP BY dept_id HAVING count > ?(s占位符的方式)
@Test
public void testGroupBy2() {
QueryWrapper<Employee> wrapper = new QueryWrapper<>();
wrapper.select("dept_id", "count(id) count");
wrapper.groupBy("dept_id");
// wrapper.having("count > 3"); // sql 片段
wrapper.having("count > {0}", 3); // 占位符的方式
List<Map<String, Object>> mapList = employeeMapper.selectMaps(wrapper);
mapList.forEach(System.out::println);
}
// 1.需求:查询 name=yy,age=18 的员工信息
@Test
public void testEq() {
QueryWrapper<Employee> wrapper = new QueryWrapper<>();
/**
Map map = new HashMap<>();
map.put("name", "yy");
map.put("age", 18);
// 所有条件都必须相等
wrapper.allEq(map); // where(name = ? and age = ?)
*/
wrapper.eq("age", 18).eq("name", "yy"); // where(age = ?)
// wrapper.ne("age", 18); // where(age <> ?)
employeeMapper.selectList(wrapper);
}
// 2.需求:查询年龄介于18~30岁的员工信息
@Test
public void testBetween() {
QueryWrapper<Employee> wrapper = new QueryWrapper<>();
wrapper.between("age", 18, 30); // 年龄在 18 ~ 30 之间
// wrapper.notBetween("age", 18, 30); // 年龄不在在 18 ~ 30 之间
employeeMapper.selectList(wrapper);
}
// 3.需求:查询dept_id 为null 员工信息
@Test
public void testNull() {
QueryWrapper<Employee> wrapper = new QueryWrapper<>();
wrapper.isNull("dept_id"); // where dept_id is null
// wrapper.isNotNull("dept_id"); // where dept_id is not null
employeeMapper.selectList(wrapper);
}
// 4.需求:查询id为1, 2 的员工信息
@Test
public void testIn() {
QueryWrapper<Employee> wrapper = new QueryWrapper<>();
// 占位符形式
wrapper.in("id", 1L, 2L); // where (id in (?,?))
// sql 片段
// wrapper.inSql("id", "1, 2"); // where (id in (1,2))
employeeMapper.selectList(wrapper);
}
// 1.需求:查询 age=18 或者 name=yy 或者 id=1 的员工
// 打印的 SQL:SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE (age = ? OR name = ? OR id = ?)
@Test
public void testOR() {
QueryWrapper<Employee> wrapper = new QueryWrapper<>();
wrapper.eq("age", 18)
.or()
.eq("name", "yy")
.or()
.eq("id", 1L);
employeeMapper.selectList(wrapper);
}
// 2.需求:查询 name 中含有 yy 字样,或年龄在 18 到 30 之间的员工
// 打印的 SQL:SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE (name LIKE ? OR (age >= ? AND age <= ?))
@Test
public void testOrAnd() {
QueryWrapper<Employee> wrapper = new QueryWrapper<>();
wrapper.like("name", "yy");
wrapper.or(
wp -> wp.ge("age", 18).le("age", 30)
);
employeeMapper.selectList(wrapper);
}
// 3.需求:查询 name 中含有 yy 字样,或年龄小于 18 大于 30 的员工
// 打印的 SQL:SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE (name LIKE ? AND (age < ? AND age > ?))
@Test
public void testAndOr() {
QueryWrapper<Employee> wrapper = new QueryWrapper<>();
wrapper.like("name", "yy");
wrapper.and(
wp -> wp.lt("age", 18).gt("age", 30)
);
employeeMapper.selectList(wrapper);
}
mapper.xml 方式
多表查询时还是和以前使用 mybatis 一样;
注解方式
// 单表查询
@Select("select e.* from employee e")
List<Employee> listByAnnoSingle();
// 多表关联查询
@Select("select e.*, d.id d_id, d.name d_name, d.sn d_sn from employee e left join department d on e.dept_id = d.id")
@Results({
@Result(column="d_id", property = "dept.id"),
@Result(column="d_name", property = "dept.name"),
@Result(column="d_sn", property = "dept.sn")
})
List<Employee> listByAnnoJoin();
package com.yy.mp.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.IService;
import com.yy.mp.domain.Employee;
import com.yy.mp.qo.EmployeeQueryObject;
/**
* 自定义 mybatis-plus 服务层接口
* 1> 自定义接口 IEmployeeService
* 2> 继承通用接口 IService
* 3> 指定泛型,即操作实体类型
*/
public interface IEmployeeService extends IService<Employee> {
/**
* 分页查询
*/
IPage<Employee> queryPage(EmployeeQueryObject qo);
/**
* 获取观看前三的游记
* @param destId
* @return
*/
List<Travel> queryViewnumTop3Travels(Long destId);
}
package com.yy.mp.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yy.mp.domain.Employee;
import com.yy.mp.mapper.EmployeeMapper;
import com.yy.mp.qo.EmployeeQueryObject;
import com.yy.mp.service.IEmployeeService;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
/**
* 自定义 mybatis-plus 服务层接口实现类
* 1> 自定义类 EmployeeServiceImpl
* 2> 实现自定义接口:IEmployeeService
* 3> 继承通用接口 IService 实现类:ServiceImpl
* 4> 指定2个泛型:1:操作实体类 mapper 接口;2:操作实体对象类型:Employee
*/
@Service
public class EmployeeServiceImpl extends ServiceImpl<EmployeeMapper, Employee> implements IEmployeeService {
@Override
public IPage<Employee> queryPage(EmployeeQueryObject qo) {
IPage<Employee> page = new Page<>(qo.getCurrentPage(), qo.getPageSize());
QueryWrapper<Employee> wrapper = new QueryWrapper<>();
/*if (StringUtils.hasLength(qo.getKeyword())) {
wrapper.like("name", qo.getKeyword());
}*/
wrapper.like(StringUtils.hasLength(qo.getKeyword()), "name", qo.getKeyword());
return super.page(page, wrapper);
}
@Override
public List<Travel> queryViewnumTop3Travels(Long destId) {
QueryWrapper<Travel> wrapper = new QueryWrapper<>();
wrapper.eq("dest_id", destId)
.orderByDesc("viewnum")
.groupBy("dest_id")
.last("limit 3");
return super.list(wrapper);
}
}
上面就是 Mybatis-Plus 的详细总结了,代码仅供参考,欢迎讨论交流。