用户网站建设建设网站的网络公司
文章目录
- MyBatis-Plus入门和使用实践
- 一、前言
- 二、正文
- 1.创建项目
- 1)引入依赖
- 2)SpringBoot配置
- 3)测试数据
- 4)测试例子
- 2.常用注解
- 3.查询
- 1)普通条件查询
- 2)条件构造器查询
- 3)Lambda条件构造器
- 4)常用查询
- 排除查询字段
- 是否使用某个条件
- 实体对象作为条件
- 条件全匹配
- Map结果(统计)
- 其它查询
- 5)自定义SQL
- 接口类实现
- XML实现
- 6)分页查询
- Config配置
- BaseMapper分页查询
- 自定义SQL分页查询
- 4.增删改
- 新增
- 更新
- 删除
- 5. AR模式
- 6.主键策略
- 7.MP配置
- 8.通用Service
- 三、其它
- 1.完整配置文件
MyBatis-Plus入门和使用实践
一、前言
- 环境说明
- 操作系统:Windows 10 专业版
- Mybatis-Plus 版本:3.4.2
- JDK 版本:1.8
- 开发工具:IntelliJ IDEA 2020.2.2
- 简介
-
MyBatis-Plus(简称 MP)是一个 MyBatis 的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。
特性:
- 无侵入、消耗小、强大的 CRUD 操作
- 支持 Lambda 形式调用,支持多种数据库
- 支持主键自动生成,支持 ActiveRecord 模式
- 支持自定义全局通用操作,支持关键词自动转义
- 内置代码生成器,内置分页插件,内置性能分析插件
- 内置全局拦截插件,内置 SQL 注入剥离器
MyBatis-Plus 官网:https://mp.baomidou.com/
MyBatis-Plus 示例工程:https://gitee.com/baomidou/mybatis-plus-samples/tree/master
MyBatis 官网:https://mybatis.org/mybatis-3/zh/index.html
Spring Data JPA:https://spring.io/projects/spring-data-jpa
Active Record 模式-百度百科:https://baike.baidu.com/item/Active%20Record/3106858?fr=aladdin
二、正文
1.创建项目
1)引入依赖
pom.xml
引入依赖 mybatis-plus、lombok、spring-boot
<!-- spring-boot-starter 父工程 -->
<parent><artifactId>spring-boot-starter-parent</artifactId><groupId>org.springframework.boot</groupId><version>2.1.3.RELEASE</version>
</parent><dependencies><!-- spring-boot 启动器 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId></dependency><!-- spring-boot 测试启动器 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><!-- lombok --><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><!-- mybatis-plus spring-boot 启动器 --><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.4.2</version></dependency><!-- mybatis-plus --><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus</artifactId><version>3.4.2</version></dependency><!-- mysql 驱动 --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency><!-- junit --><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version><scope>test</scope></dependency>
</dependencies>
2)SpringBoot配置
- resources 文件夹创建
application.yml
# mysql 连接配置
spring:datasource:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/mp-db?useSSL=false&characterEncoding=UTF-8&serverTimezone=GMT%2B8username: rootpassword: 123456
# 输入日志,查看 sql 语句
logging:level:root: warnorg.example.dao: tracepattern:console: '%p%m%n'
App.java
启动 spring-boot
package org.example;import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;/*** spring-boot 启动入口**/
@SpringBootApplication
@MapperScan({"org.example.dao"})
public class App
{public static void main( String[] args ){SpringApplication.run(App.class, args);}
}
3)测试数据
- sql 脚本
#创建用户表
CREATE TABLE user (id BIGINT(20) PRIMARY KEY NOT NULL COMMENT '主键',name VARCHAR(30) DEFAULT NULL COMMENT '姓名',age INT(11) DEFAULT NULL COMMENT '年龄',email VARCHAR(50) DEFAULT NULL COMMENT '邮箱',manager_id BIGINT(20) DEFAULT NULL COMMENT '直属上级id',create_time DATETIME DEFAULT NULL COMMENT '创建时间',CONSTRAINT manager_fk FOREIGN KEY (manager_id)REFERENCES user (id)
) ENGINE=INNODB CHARSET=UTF8;#初始化数据:
INSERT INTO user (id, name, age, email, manager_id, create_time)
VALUES (1087982257332887553, '大boss', 40, 'boss@baomidou.com', NULL, '2019-01-11 14:20:20'),(1088248166370832385, '王天风', 25, 'wtf@baomidou.com', 1087982257332887553, '2019-02-05 11:12:22'),(1088250446457389058, '李艺伟', 28, 'lyw@baomidou.com', 1088248166370832385, '2019-02-14 08:31:16'),(1094590409767661570, '张雨琪', 31, 'zjq@baomidou.com', 1088248166370832385, '2019-01-14 09:15:15'),(1094592041087729666, '刘红雨', 32, 'lhm@baomidou.com', 1088248166370832385, '2019-01-14 09:48:16');
- 创建
entity/User.java
package org.example.entity;import lombok.Data;import java.time.LocalDateTime;/**** 用户实体类* */
@Data
public class User {// 员工 IDprivate Long id;// 姓名private String name;// 年龄private Integer age;// 邮箱private String email;// 上级领导 IDprivate Long managerId;// 创建时间private LocalDateTime createTime;
}
- 创建
dao/UserMapper.java
(接口)
package org.example.dao;import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.example.entity.User;public interface UserMapper extends BaseMapper<User> {}
4)测试例子
- 测试类:
AppTest.java
package org.example;import org.example.dao.UserMapper;
import org.example.entity.User;
import org.junit.Assert;
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.SpringJUnit4ClassRunner;import java.util.List;@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest
public class AppTest
{@Autowiredprivate UserMapper userMapper;/*** 查询列表* */@Testpublic void select(){List<User> users = userMapper.selectList(null);// 判断预期值与实际值是否相同// Assert.assertEquals(5, users.size());// 循环输出users.forEach(System.err::println);}
}
2.常用注解
注解 | 说明 |
---|---|
@TableName(“数据库表名”) | 指定实体类对应的数据库表名 |
@TableId | 指定属性作为主键,mp 默认 id 为主键 |
@TableId(type = IdType.ASSIGN_UUID) | 指定属性作为主键,并指定主键策略 |
@TableField(“数据库表字段名”) | 指定属性对应的数据库表字段名 |
@TableField(exist=false) | 实体属性排除映射;将属性标记为非数据库表字段 |
@TableField(condition = SqlCondition.LIKE) | 当实体对象作为条件构造器的查询条件时,属性可进行 like 查询,而非默认的等值(SqlCondition 中还有其它常量可选) |
3.查询
1)普通条件查询
- ID 查询
@Test
public void selectById()
{// 根据 ID 进行查询User user = userMapper.selectById(1087982257332887553L);System.err.println(user);
}
- 批量 ID 查询
@Test
public void selectBatchIds()
{List<Long> ids = Arrays.asList(1087982257332887553L, 1088248166370832385L);// 根据 ID 列表进行查询List<User> users = userMapper.selectBatchIds(ids);users.forEach(System.err::println);
}
- 根据 map 查询
@Test
public void selectByMap()
{Map map = new HashMap();map.put("name", "大boss"); // 数据库表字段名map.put("age", 40);// sql:where name = '大boss' and age =40// 根据 Map {name : value} 进行查询List<User> users = userMapper.selectByMap(map);users.forEach(System.err::println);
}
2)条件构造器查询
- 名字中包含’雨’,并且年龄小于 40
where name like ‘%雨%’ and age < 40
@Test
public void selectByWrapper()
{// 创建条件构造器QueryWrapper<User> queryWrapper = Wrappers.query();queryWrapper.like("name", "雨").lt("age", 40); // 数据库表字段名// 根据条件构造器进行查询List<User> users = userMapper.selectList(queryWrapper);users.forEach(System.err::println);
}
- 名字中包含’雨’,年龄大于等于 20,且小于等于 40,且邮箱不为空
where name like ‘%雨%’ and age between 20 and 40 and email is not null
@Test
public void selectByWrapper2()
{// 创建条件构造器QueryWrapper<User> queryWrapper = Wrappers.query();queryWrapper.like("name", "雨").between("age", 20, 40).isNotNull("email"); // 数据库表字段名// 根据条件构造器进行查询List<User> users = userMapper.selectList(queryWrapper);users.forEach(System.err::println);
}
- 名字姓’张’,或者年龄大于等于 30,按年龄降序排列,年龄相同的按id升序排列
where name like ‘张%’ or age >= 30 order by age desc,id asc
@Test
public void selectByWrapper3()
{// 创建条件构造器QueryWrapper<User> queryWrapper = Wrappers.query();queryWrapper.like("name", "张%").or().ge("age", 30).orderByDesc("age").orderByAsc("id"); // 数据库表字段名// 根据条件构造器进行查询List<User> users = userMapper.selectList(queryWrapper);users.forEach(System.err::println);
}
- 创建日期是’2019-02-14’,且上级领导姓’王’
where date_format(create_time, ‘%Y-%m-%d’)
and manager_id in (select id from user where name like ‘王%’)
@Test
public void selectByWrapper4()
{// 创建条件构造器QueryWrapper<User> queryWrapper = Wrappers.query();queryWrapper.apply("date_format(create_time, '%Y-%m-%d') = {0}", "2019-02-14") // {0} 参数序号.inSql("manager_id", "select id from user where name like '王%'");// 根据条件构造器进行查询List<User> users = userMapper.selectList(queryWrapper);users.forEach(System.err::println);
}
- 姓’王’,且(年龄小于 40 或邮箱不为空)
where name like ‘王%’ and (age<40 or email is not null)
@Test
public void selectByWrapper5()
{// 创建条件构造器QueryWrapper<User> queryWrapper = Wrappers.query();queryWrapper.likeRight("name", "王").and( wq->wq.lt("age", 40).or().isNotNull("email")); // 数据库表字段名// 根据条件构造器进行查询List<User> users = userMapper.selectList(queryWrapper);users.forEach(System.err::println);
}
- 姓’王’,或者(年龄小于 40 且大于 20 且邮箱不为空)
where name like ‘王%’ or (age<40 and age>20 and email is not null)
@Test
public void selectByWrapper6()
{// 创建条件构造器QueryWrapper<User> queryWrapper = Wrappers.query();queryWrapper.likeRight("name", "王").or( wq->wq.lt("age", 40).gt("age", 20).isNotNull("email")); // 数据库表字段名// 根据条件构造器进行查询List<User> users = userMapper.selectList(queryWrapper);users.forEach(System.err::println);
}
- (年龄小于 40 或邮箱不为空) 且姓’王’
where (age<40 or email is not null) and name like ‘王%’
@Test
public void selectByWrapper7()
{// 创建条件构造器QueryWrapper<User> queryWrapper = Wrappers.query();queryWrapper.nested( wq->wq.lt("age", 40).or().isNotNull("email") ).likeRight("name", "王"); // 数据库表字段名// 根据条件构造器进行查询List<User> users = userMapper.selectList(queryWrapper);users.forEach(System.err::println);
}
- 年龄包含 30、31、34
where age in (30, 31, 34)
@Test
public void selectByWrapper8()
{// 创建条件构造器QueryWrapper<User> queryWrapper = Wrappers.query();queryWrapper.in("age", Arrays.asList(30, 31, 32)); // 数据库表字段名// 根据条件构造器进行查询List<User> users = userMapper.selectList(queryWrapper);users.forEach(System.err::println);
}
- 仅获取一条数据
limit 1
@Test
public void selectByWrapper9()
{// 创建条件构造器QueryWrapper<User> queryWrapper = Wrappers.query();queryWrapper.in("age", Arrays.asList(30, 31, 32)).last("limit 1"); // last 方法存在 sql 注入的风险// 根据条件构造器进行查询List<User> users = userMapper.selectList(queryWrapper);users.forEach(System.err::println);
}
3)Lambda条件构造器
- 使用 lambda 表达式,可以避免数据库表字段名误写
@Test
public void selectByWrapperLambda()
{// LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper();// LambdaQueryWrapper<User> lambdaQueryWrapper = new QueryWrapper<User>().lambda();LambdaQueryWrapper<User> lambdaQueryWrapper = Wrappers.lambdaQuery();lambdaQueryWrapper.like(User::getName, "雨").lt(User::getAge, 40);// 根据条件构造器进行查询List<User> users = userMapper.selectList(lambdaQueryWrapper);users.forEach(System.err::println);
}
- 链式编程
@Test
public void selectByWrapperChain()
{List<User> users = new LambdaQueryChainWrapper<User>( userMapper ).like(User::getName, "雨").lt(User::getAge, 40).list();users.forEach(System.err::println);
}
4)常用查询
排除查询字段
- 名字包含’雨’,且年龄小于 40 ( 只查询 id 和 name 字段 )
select id,name from user where name like ‘雨%’ and age < 40
@Test
public void selectByWrapper10()
{// 创建条件构造器QueryWrapper<User> queryWrapper = Wrappers.query();queryWrapper.select("id", "name").like("name", "雨").lt("age", 40); // 数据库表字段名// 根据条件构造器进行查询List<User> users = userMapper.selectList(queryWrapper);users.forEach(System.err::println);
}
- 名字包含’雨’,且年龄小于 40 ( 查询排除 create_time 和 manager_id )
select id,name,age,email from user where name like ‘雨%’ and age < 40
@Test
public void selectByWrapper11()
{// 创建条件构造器QueryWrapper<User> queryWrapper = Wrappers.query();queryWrapper.select(User.class, u->!u.getColumn().equals("create_time")&&!u.getColumn().equals("manager_id")).like("name", "雨").lt("age", 40); // 数据库表字段名// 根据条件构造器进行查询List<User> users = userMapper.selectList(queryWrapper);users.forEach(System.err::println);
}
是否使用某个条件
- 如果 name 或 email 为空,则不使用该条件进行查询
@Test
public void selectByWrapper12()
{String name = "雨";String email = "";// 创建条件构造器QueryWrapper<User> queryWrapper = Wrappers.query();queryWrapper.like(StringUtils.isNotBlank(name), "name", name).like(StringUtils.isNotBlank(email), "email", email); // 数据库表字段名// 根据条件构造器进行查询List<User> users = userMapper.selectList(queryWrapper);users.forEach(System.err::println);
}
实体对象作为条件
- 名字是’李艺伟’,且年龄是28
where name=‘李艺伟’ and age=28
@Test
public void selectByWrapper13()
{User user = new User();user.setName("李艺伟");user.setAge(28);// 创建条件构造器QueryWrapper<User> queryWrapper = Wrappers.query(user);// 根据条件构造器进行查询List<User> users = userMapper.selectList(queryWrapper);users.forEach(System.err::println);
}
注意: 默认为等值查询,如果需要模糊查询,需要在实体类的属性中添加注解
@TableField(condition = SqlCondition.LIKE)
例如:
@TableField(condition = SqlCondition.LIKE) private String name;
条件全匹配
- 1.查询条件全匹配,包括 null 也会作为查询条件
- 2.设置 false 时;如果参数为 null,则参数会排除,不作为查询条件
- 3.通过函数,可排除某些字段作为查询条件
@Test
public void selectByWrapperAllEq()
{Map map =new HashMap();map.put("name", "大boss");map.put("email", null);// 创建条件构造器QueryWrapper<User> queryWrapper = Wrappers.query();// 1.全匹配// queryWrapper.allEq(map);// 2.设置为 false 时,如果参数为 null,则参数会排除,不作为查询条件// queryWrapper.allEq(map, false);// 3.通过函数,排除某些字段作为查询条件;例如:排除 name 字段作为查询条件queryWrapper.allEq((k,v)->!k.equals("name"), map);// 根据条件构造器进行查询List<User> users = userMapper.selectList(queryWrapper);users.forEach(System.err::println);
}
Map结果(统计)
- 返回 Map 对象,可避免实体对象因为排除查询字段后,大多数字段为空的情况
@Test
public void selectByWrapperMaps()
{// 创建条件构造器QueryWrapper<User> queryWrapper = Wrappers.query();queryWrapper.select("id", "name").like("name", "雨").lt("age", 40); // 数据库表字段名// 根据条件构造器进行查询List<Map<String, Object>> users = userMapper.selectMaps(queryWrapper);users.forEach(System.err::println);
}
- 按上级领导分组,查询分组的评价年龄,最大年龄,最小年龄,并且只取年龄总和小于500的分组
SELECT AVG(age) avg_age, MIN(age) min_age, MAX(age) max_age
FROM user
GROUP BY manager_id
HAVING SUM(age) < 500
@Test
public void selectByWrapperMaps2()
{// 创建条件构造器QueryWrapper<User> queryWrapper = Wrappers.query();queryWrapper.select("AVG(age) avg_age", "MIN(age) min_age", "MAX(age) max_age").groupBy("manager_id").having("SUM(age) < {0}", 500); // 数据库表字段名// 根据条件构造器进行查询List<Map<String, Object>> users = userMapper.selectMaps(queryWrapper);users.forEach(System.err::println);
}
其它查询
- 仅获取第一列数据,如下查询,仅输出 id 字段的数据
@Test
public void selectByWrapperObjs()
{QueryWrapper<User> queryWrapper = Wrappers.query();queryWrapper.select("id", "name").like("name", "雨").lt("age", 40); // 数据库表字段名// 根据条件构造器进行查询List<Object> users = userMapper.selectObjs(queryWrapper);users.forEach(System.err::println);
}
- 统计记录数
注意:不能指定字段
@Test
public void selectByWrapperCount()
{QueryWrapper<User> queryWrapper = Wrappers.query();queryWrapper.like("name", "雨").lt("age", 40); // 数据库表字段名// 根据条件构造器进行查询Integer count = userMapper.selectCount(queryWrapper);System.out.println("总记录数:"+count);
}
- 查询一条数据
注意:查询结果有多条时,会报错
@Test
public void selectByWrapperOne()
{QueryWrapper<User> queryWrapper = Wrappers.query();queryWrapper.like("name", "张雨琪").lt("age", 40); // 数据库表字段名// 根据条件构造器进行查询User user = userMapper.selectOne(queryWrapper);System.out.println(user);
}
5)自定义SQL
接口类实现
dao/UserMapper.java
- 条件构造器作为sql参数
package org.example.dao;import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.example.entity.User;import java.util.List;public interface UserMapper extends BaseMapper<User> {/*** 根据条件构造器进行查询* */@Select("select * from user ${ew.customSqlSegment}")public List<User> selectByWrapper(@Param(Constants.WRAPPER) Wrapper<User> wrapper);
}
- 测试类:
AppTest.java
@Test
public void selectByWrapperSQL()
{LambdaQueryWrapper<User> lambdaQueryWrapper = Wrappers.lambdaQuery();lambdaQueryWrapper.like(User::getName, "雨").lt(User::getAge, 40);// 根据条件构造器进行查询List<User> users = userMapper.selectByWrapper(lambdaQueryWrapper);users.forEach(System.err::println);
}
XML实现
application.yml
配置 mybatis-plus 的 mapper 文件目录
# mybatis-plus
mybatis-plus:# mapper 目录mapper-locations: classpath*:mapper/*Mapper.xml
resources/mapper/UserMapper.xml
(resources 资源目录下)- 条件构造器作为sql参数
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--
namespace:命名空间,指定为接口的全类名
-->
<mapper namespace="org.example.dao.UserMapper"><!--接口方式:id:接口方法名 ,resultType:返回类型--><select id="selectByWrapperXML" resultType="org.example.entity.User">select * from user ${ew.customSqlSegment}</select>
</mapper>
dao/UserMapper.java
package org.example.dao;import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.example.entity.User;import java.util.List;public interface UserMapper extends BaseMapper<User> {/*** 根据条件构造器进行查询,SQL 语句配置在 XML 文件中* */public List<User> selectByWrapperXML(@Param(Constants.WRAPPER) Wrapper<User> wrapper);
}
- 测试类:
AppTest.java
@Test
public void selectByWrapperSQL2()
{LambdaQueryWrapper<User> lambdaQueryWrapper = Wrappers.lambdaQuery();lambdaQueryWrapper.like(User::getName, "雨").lt(User::getAge, 40);// 根据条件构造器进行查询List<User> users = userMapper.selectByWrapperXML(lambdaQueryWrapper);users.forEach(System.err::println);
}
6)分页查询
mybatis 分页仅实现了逻辑分页,即将数据全部加载到内存,然后再分页。
Config配置
- 创建
config/MybatisPlusConfig.java
package org.example.config;import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.autoconfigure.ConfigurationCustomizer;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.annotation.EnableTransactionManagement;@Configuration
@EnableTransactionManagement
public class MybatisPlusConfig {/*** 新的分页插件,一缓和二缓遵循mybatis的规则,* 需要设置 MybatisConfiguration#useDeprecatedExecutor = false* 避免缓存出现问题(该属性会在旧插件移除后一同移除)*/@Beanpublic MybatisPlusInterceptor mybatisPlusInterceptor() {MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.H2));return interceptor;}@Beanpublic ConfigurationCustomizer configurationCustomizer() {return configuration -> configuration.setUseDeprecatedExecutor(false);}
}
BaseMapper分页查询
- 测试类:
AppTest.java
@Test
public void selectByWrapperPage()
{LambdaQueryWrapper<User> lambdaQueryWrapper = Wrappers.lambdaQuery();lambdaQueryWrapper.gt(User::getAge, 20);// 分页查询// Page<User> page = new Page<>(1, 3);// IPage<User> iPage = userMapper.selectPage(page, lambdaQueryWrapper);// MapPage page = new Page<>(1, 3);IPage<Map<String, Object>> iPage = userMapper.selectMapsPage(page, lambdaQueryWrapper);// 输出结果System.err.println("当前页:"+iPage.getCurrent());System.err.println("总页数:"+iPage.getPages());System.err.println("总记录数:"+iPage.getTotal());iPage.getRecords().forEach(System.err::println);
}
- 屏蔽总记录数的查询
Page<User> page = new Page<>(1, 3, false);
自定义SQL分页查询
dao/UserMapper.java
package org.example.dao;import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.example.entity.User;import java.util.List;public interface UserMapper extends BaseMapper<User> {/*** 分页查询* */public IPage<User> selectUserPage(Page<User> page, @Param(Constants.WRAPPER) Wrapper<User> wrapper);
}
resources/mapper/UserMapper.xml
(resources 资源目录下)
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--
namespace:命名空间,指定为接口的全类名
-->
<mapper namespace="org.example.dao.UserMapper"><!--接口方式:id:接口方法名 ,resultType:返回类型--><select id="selectUserPage" resultType="org.example.entity.User">select * from user ${ew.customSqlSegment}</select>
</mapper>
- 测试类:
AppTest.java
@Test
public void selectByWrapperPage2()
{LambdaQueryWrapper<User> lambdaQueryWrapper = Wrappers.lambdaQuery();lambdaQueryWrapper.gt(User::getAge, 20);// 分页查询Page<User> page = new Page<>(1, 3);IPage<User> iPage = userMapper.selectUserPage(page, lambdaQueryWrapper);// 输出结果System.err.println("当前页:"+iPage.getCurrent());System.err.println("总页数:"+iPage.getPages());System.err.println("总记录数:"+iPage.getTotal());iPage.getRecords().forEach(System.err::println);
}
4.增删改
新增
- 测试类:
AppTest.java
@Test
public void insert()
{User user = new User();user.setName("李小龙");user.setAge(22);user.setEmail("lxl@163.com");user.setManagerId(1088248166370832385L);user.setCreateTime(LocalDateTime.now());// 插入数据int num = userMapper.insert(user);System.err.println("影响记录数据:"+num);System.err.println("主键:"+user.getId());
}
更新
- 根据 ID 更新
@Test
public void updateById()
{User user = new User();user.setId(1094592041087729666L);user.setAge(31);// 更新数据int num = userMapper.updateById(user);System.err.println("影响记录数据:"+num);
}
- 根据条件构造器更新
@Test
public void updateByWrapper()
{// 条件构造器UpdateWrapper updateWrapper = new UpdateWrapper();updateWrapper.eq("name", "刘红雨");// 更新实体对象User user = new User();user.setAge(34);// 更新数据int num = userMapper.update(user,updateWrapper);System.err.println("影响记录数据:"+num);
}
- 条件构造器中 set 方法,更新少量字段时使用
@Test
public void updateByWrapper2()
{// 条件构造器/*UpdateWrapper<User> updateWrapper = new UpdateWrapper();updateWrapper.eq("name", "刘红雨").set("age", 30);*/// Lambda 条件构造器LambdaUpdateWrapper<User> lambdaUpdateWrapper = Wrappers.lambdaUpdate();lambdaUpdateWrapper.eq(User::getName, "刘红雨").set(User::getAge, 30); // set 方法设置修改的值// 更新数据int num = userMapper.update(null,lambdaUpdateWrapper);System.err.println("影响记录数据:"+num);// 链式编程boolean isUpdate = new LambdaUpdateChainWrapper<User>(userMapper).eq(User::getName, "刘红雨").set(User::getAge, 30).update();System.err.println("更新成功:"+isUpdate);
}
删除
- 根据 ID 删除
@Test
public void deleteById()
{Long userid = 1359388531205722114L;// 删除数据int num = userMapper.deleteById(userid);System.err.println("影响记录数据:"+num);
}
- 其它删除方法
@Test
public void deleteByMap()
{Map<String, Object> map =new HashMap<>();map.put("name", "刘红雨");map.put("age", 30);// 删除数据int num = userMapper.deleteByMap(map);System.err.println("影响记录数据:"+num);
}@Test
public void deleteByBatchId()
{List<Long> ids = Arrays.asList(123123123123L, 1233435234534L);// 删除数据int num = userMapper.deleteBatchIds(ids);System.err.println("影响记录数据:"+num);
}
- 条件构造器删除
@Test
public void deleteByBWrapper()
{LambdaQueryWrapper<User> lambdaQueryWrapper = Wrappers.lambdaQuery();lambdaQueryWrapper.eq(User::getId, 12312312312312L);// 删除数据int num = userMapper.delete(lambdaQueryWrapper);System.err.println("影响记录数据:"+num);
}
5. AR模式
百度百科:https://baike.baidu.com/item/Active%20Record/3106858?fr=aladdin
- Active Record(活动记录),是一种领域模型模式,特点是一个模型类对应关系型数据库中的一个表,而模型类的一个实例对应表中的一行记录。
具体操作
- 实体对象继承
com.baomidou.mybatisplus.extension.activerecord.Model
(当前为 User) - 编写好继承了
com.baomidou.mybatisplus.core.mapper.BaseMapper
的Mapper
(当前为 UserMapper)
entity/UserMapper.java
package org.example.entity;import com.baomidou.mybatisplus.extension.activerecord.Model;
import lombok.Data;import java.time.LocalDateTime;/**** 员工实体类* */
@Data
public class User extends Model {// 用户 IDprivate Long id;// 姓名private String name;// 年龄private Integer age;// 邮箱private String email;// 上级领导 IDprivate Long managerId;// 创建时间private LocalDateTime createTime;
}
- 测试类:
ARTest.java
@Test
public void arSelect()
{User user = new User();// 查询数据List<User> users = user.selectAll();// 循环输出users.forEach(System.err::println);
}@Test
public void arInsert()
{User user = new User();user.setName("路飞");user.setAge(25);user.setEmail("lf@163.com");user.setManagerId(1088248166370832385L);user.setCreateTime(LocalDateTime.now());// 新增数据boolean isInsert = user.insert();System.out.println("新增成功:"+isInsert);
}@Test
public void arUpdate()
{User user = new User();user.setId(1359800186100056065L);user.setName("路飞飞");// 修改数据boolean isUpdate = user.updateById();System.out.println("更新成功:"+isUpdate);
}@Test
public void arDelete()
{User user = new User();user.setId(1359800186100056065L);// 删除数据boolean isDelete = user.deleteById();System.out.println("删除成功:"+isDelete);
}
6.主键策略
- 默认是基于雪花算法的主键策略
com.baomidou.mybatisplus.annotation.IdType.java
IdType | 说明 |
---|---|
AUTO(0) | 数据库 ID 自增 |
NONE(1) | 该类型为未设置主键类型 (注解里等于跟随全局,全局里约等于 INPUT) |
INPUT(2) | 用户输入 ID; |
ASSIGN_ID(3) | 分配ID (主键类型为number或string);默认 雪花算法 |
ASSIGN_UUID(4) | 分配UUID (主键类型为 string) |
全局策略配置
resources/application.yml
# mybatis-plus
mybatis-plus:# 全局主键配置global-config:db-config:id-type: assign_id
7.MP配置
MP配置官网文档:https://mp.baomidou.com/config/
- 基本配置、全局配置、数据库配置
8.通用Service
- Service 接口继承
com.baomidou.mybatisplus.extension.service.IService
- Service 实现继承
com.baomidou.mybatisplus.extension.service.impl.ServiceImpl
- 具体操作,参考 dao 的操作
三、其它
1.完整配置文件
- pom.xml
<?xml version="1.0" encoding="UTF-8"?><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.0</modelVersion><groupId>org.example</groupId><artifactId>mp-demo</artifactId><version>1.0-SNAPSHOT</version><name>mp-demo</name><!-- FIXME change it to the project's website --><url>http://www.example.com</url><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><maven.compiler.source>1.8</maven.compiler.source><maven.compiler.target>1.8</maven.compiler.target></properties><!-- spring-boot-starter 父工程 --><parent><artifactId>spring-boot-starter-parent</artifactId><groupId>org.springframework.boot</groupId><version>2.1.3.RELEASE</version></parent><dependencies><!-- spring-boot 启动器 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId></dependency><!-- spring-boot 测试启动器 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><!-- lombok --><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><!-- mybatis-plus spring-boot 启动器 --><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.4.2</version></dependency><!-- mybatis-plus --><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus</artifactId><version>3.4.2</version></dependency><!-- mysql 驱动 --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency><!-- junit --><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version><scope>test</scope></dependency></dependencies><build><pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) --><plugins><!-- clean lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#clean_Lifecycle --><plugin><artifactId>maven-clean-plugin</artifactId><version>3.1.0</version></plugin><!-- default lifecycle, jar packaging: see https://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_jar_packaging --><plugin><artifactId>maven-resources-plugin</artifactId><version>3.0.2</version></plugin><plugin><artifactId>maven-compiler-plugin</artifactId><version>3.8.0</version></plugin><plugin><artifactId>maven-surefire-plugin</artifactId><version>2.22.1</version></plugin><plugin><artifactId>maven-jar-plugin</artifactId><version>3.0.2</version></plugin><plugin><artifactId>maven-install-plugin</artifactId><version>2.5.2</version></plugin><plugin><artifactId>maven-deploy-plugin</artifactId><version>2.8.2</version></plugin><!-- site lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#site_Lifecycle --><plugin><artifactId>maven-site-plugin</artifactId><version>3.7.1</version></plugin><plugin><artifactId>maven-project-info-reports-plugin</artifactId><version>3.0.0</version></plugin></plugins></pluginManagement></build>
</project>
- application.yml
# mysql 连接配置
spring:datasource:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/mp-db?useSSL=false&serverTimezone=GMT%2B8username: rootpassword: root2020
# 输入日志,查看 sql 语句
logging:level:root: warnorg.example.dao: tracepattern:console: '%p%m%n'
# mybatis-plus
mybatis-plus:# mapper 目录mapper-locations: classpath*:mapper/*Mapper.xml# 全局主键配置global-config:db-config:id-type: assign_id
- UserMapper.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--
namespace:命名空间,指定为接口的全类名
-->
<mapper namespace="org.example.dao.UserMapper"><!--接口方式:id:接口方法名 ,resultType:返回类型--><select id="selectByWrapperXML" resultType="org.example.entity.User">select * from user ${ew.customSqlSegment}</select><select id="selectUserPage" resultType="org.example.entity.User">select * from user ${ew.customSqlSegment}</select>
</mapper>