Mybatis-Plus简介
MyBatis-Plus (opens new window)(简称 MP)是一个MyBatis (opens new window)的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。
特性:
- 无侵入:只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑
- 损耗小:启动即会自动注入基本 CURD,性能基本无损耗,直接面向对象操作
- 强大的 CRUD 操作:内置通用 Mapper、通用 Service,仅仅通过少量配置即可实现单表大部分 CRUD 操作,更有强大的条件构造器,满足各类使用需求
- 支持 Lambda 形式调用:通过 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、SQLServer 等多种数据库
- 内置性能分析插件:可输出 SQL 语句以及其执行时间,建议开发测试时启用该功能,能快速揪出慢查询
- 内置全局拦截插件:提供全表 delete 、 update 操作智能分析阻断,也可自定义拦截规则,预防误操作
MyBatis Plus基础使用-helloworld
1:导包
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>mybatis-plus</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>mybatis-plus</name>
<description>mybatis-plus</description>
<properties>
<java.version>1.8</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<spring-boot.version>2.6.13</spring-boot.version>
</properties>
<dependencies>
<!--springboot依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<!--测试场景-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!--mybatis plus场景-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.1</version>
</dependency>
<!-- mybatis plus 代码生成器引擎依赖-->
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity</artifactId>
<version>1.7</version>
</dependency>
<!-- mybatis plus 代码生成器依赖 -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>3.5.1</version>
</dependency>
<dependency>
<groupId>com.github.yulichang</groupId>
<artifactId>mybatis-plus-join</artifactId>
<version>1.2.4</version>
</dependency>
<!--数据库-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.21</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.12</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring-boot.version}</version>
<configuration>
<mainClass>com.example.mybatisplus.MybatisPlusApplication</mainClass>
<skip>true</skip>
</configuration>
<executions>
<execution>
<id>repackage</id>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
2:配置application.yml
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/table_name?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&autoReconnect=true&allowMultiQueries=true&serverTimezone=GMT%2B8&rewriteBatchedStatements=true&useSSL=true
username: root
password: 123456
mybatis-plus:
mapper-locations: classpath:mapper/*.xml,classpath:mapper/*/*.xml
#配置日志
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
3:mybatis-plus代码生成器
package com.example.mybatisplus.utils;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.generator.FastAutoGenerator;
import com.baomidou.mybatisplus.generator.config.OutputFile;
import com.baomidou.mybatisplus.generator.engine.VelocityTemplateEngine;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class CodeGenerator {
public static void main(String[] args){
String url = "jdbc:mysql://127.0.0.1:3306/table_name?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&autoReconnect=true&allowMultiQueries=true&serverTimezone=GMT%2B8&rewriteBatchedStatements=true&useSSL=true";
String username = "root";
String password = "123456";
String outPath = System.getProperty("user.dir") + "/src/main/java";//文件输出路径
String outPathxml = System.getProperty("user.dir") + "/src/main/resources/mapper";//xml文件输出路径
String parent = "com.example.mybatisplus";//父包的名称
String moduleName = "";//模块名称
String entity = "entity";//设置实体类文件名
String mapper = "mapper";
String service = "service";
String serviceImpl = "service.impl";
String controller = "controller";
//表名
List<String> tables = new ArrayList<>();
tables.add("country_dic");
FastAutoGenerator.create(url, username, password)
//全局配置
.globalConfig(builder -> {
builder.author("wkl") // 设置作者
// .enableSwagger() // 开启 swagger 模式
.fileOverride() // 覆盖已生成文件
.outputDir(outPath) // 指定输出目录
.disableOpenDir();// 生成后不打开目录
})
//包配置
.packageConfig(builder -> {
builder.parent(parent) // 设置父包名
.moduleName(moduleName) // 设置父包模块名
.entity(entity)//设置实体类文件名
.mapper(mapper)
.service(service)
.serviceImpl(serviceImpl)
.controller(controller)
.pathInfo(Collections.singletonMap(OutputFile.mapperXml, outPathxml)); // 设置mapperXml生成路径
})
//策略配置
.strategyConfig(builder -> {
builder.addInclude(tables) // 设置需要生成的表名
// .addTablePrefix("t_", "c_"); // 设置过滤表前缀
// .enableCapitalMode()// 开启大写命名
.entityBuilder()// 开启生成实体类
// .disableSerialVersionUID()// 禁用生成 serialVersionUID
.enableLombok()// 开启lombox模型
.enableTableFieldAnnotation() // 开启生成实体时生成字段注解
// 阿里巴巴开发规范之创建时间、更新时间 交由mybatis-plus处理,如若交给数据库处理,则取消此设置
// .addTableFills(new Column("create_time", FieldFill.INSERT), new Column("update_time", FieldFill.INSERT_UPDATE))
.mapperBuilder()//开启生成mapper
.superClass(BaseMapper.class)// 设置父类
.enableMapperAnnotation()// 开启mapper注解
.formatMapperFileName("%sMapper")//格式化mapper名称
.formatXmlFileName("%sMapper")//格式化xml名称
.enableBaseResultMap()// 生成通用的resultMap
.serviceBuilder()//开启生成service
.formatServiceFileName("%sService")//格式化service接口文件名称
.formatServiceImplFileName("%sServiceImpl")
.controllerBuilder()//开启生成controller
.enableHyphenStyle()//开启驼峰转连字符
.formatFileName("%sController")
.enableRestStyle();
})
.templateEngine(new VelocityTemplateEngine()) // 使用Freemarker引擎模板,默认的是Velocity引擎模板
.execute();
}
}
4:分析mybatis-plus文件结构
1:实体类
2:Service 接口
3:ServiceImpl 实现
4:Mapper 接口
5:Mapper xml
MyBatis Plus的使用
1:BaseMapper的查询
根据 ID 查询
T selectById(Serializable id);
根据 entity 条件,查询一条记录
T selectOne(@Param(Constants.WRAPPER) Wrapper queryWrapper);
userMapper.selectById(4L)
查询(根据ID 批量查询)
List selectBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList);
userMapper.selectBatchIds(Arrays.asList(1L, 2L, 3L))
根据 entity 条件,查询全部记录
List selectList(@Param(Constants.WRAPPER) Wrapper queryWrapper);
userMapper.selectList(new QueryWrapper<User>().eq("age", 20)).forEach(System.out::println);
查询(根据 columnMap 条件)
List selectByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap);
Map<String, Object> map = new HashMap<>();
map.put("name", "嘎嘎嘎");
map.put("age", 3);
userMapper.selectByMap(map).forEach(System.out::println);
==> Preparing: SELECT id,name,age,email FROM user WHERE name = ? AND age = ?
==> Parameters: 嘎嘎嘎(String), 3(Integer)
<== Columns: id, name, age, email
<== Row: 4, 嘎嘎嘎, 3, gagaga@gaga.com
<== Total: 1
User(id=4, name=嘎嘎嘎, age=3, email=gagaga@gaga.com)
根据 Wrapper 条件,查询全部记录
List<Map<String, Object>> selectMaps(@Param(Constants.WRAPPER) Wrapper queryWrapper);
userMapper.selectObjs(new QueryWrapper<User>().eq("age", 20)).forEach(System.out::println);
根据 Wrapper 条件,查询全部记录。注意: 只返回第一个字段的值
List selectObjs(@Param(Constants.WRAPPER) Wrapper queryWrapper);
userMapper.selectPage(new Page(1, 5), new QueryWrapper<User>().ne("id", 1L));
根据 entity 条件,查询全部记录(并翻页)
IPage selectPage(IPage page, @Param(Constants.WRAPPER) Wrapper queryWrapper);
userMapper.selectMapsPage(new Page(1, 5), new QueryWrapper<User>().ne("id", 1L));
根据 Wrapper 条件,查询全部记录(并翻页)
IPage<Map<String, Object>> selectMapsPage(IPage page, @Param(Constants.WRAPPER) Wrapper queryWrapper);
userMapper.selectMapsPage(new Page(1, 5), new QueryWrapper<User>().ne("id", 1L));
根据 Wrapper 条件,查询总记录数
Integer selectCount(@Param(Constants.WRAPPER) Wrapper queryWrapper);
System.out.println("结果:" + userMapper.selectCount(new QueryWrapper<User>().eq("id", 1L)));
==> Preparing: SELECT COUNT( * ) FROM user WHERE (id = ?)
==> Parameters: 1(Long)
<== Columns: COUNT( * )
<== Row: 1
<== Total: 1
结果:1
2:BaseMapper的新增
插入一条记录
int insert(T entity);
==> Preparing: INSERT INTO user ( id, name, age, email ) VALUES ( ?, ?, ?, ? )
==> Parameters: 1583712489828356098(Long), Ami(String), 20(Integer), 999@mm.com(String)
<== Updates: 1
结果:1
User(id=1583712489828356098, name=Ami, age=20, email=999@mm.com)
注:第一次用的小伙伴肯定很好奇,我没有给表主键设置自增,我也没给主键赋值,为何主键会有值呢?
MP默认使用雪花算法给主键赋值
3:BaseMapper的修改
mybatis-plus 在 serviceImpl 层可以直接使用 this.baseMapper.update 和 updateById ,
如果更新的字段值是null,这时候需更新为 null 的字段更新不成功。打印的 sql 也没有更新为 null 的字段。
原因:
Mybatis-Plus默认的更新策略设置的问题,Mybatis-Plus中FieldStrategy有三种策略:
- IGNORED:忽略。不管有没有有设置属性,所有的字段都会设置到insert语句中,如果没设置值会更新为null;
- NOT_NULL:非 NULL,默认策略。也就是忽略null的字段,不忽略"";
- NOT_EMPTY:非空。为null,为空串的忽略,就是如果设置值为null,“”,不会插入数据库;
根据 whereWrapper 条件,更新记录
int update(@Param(Constants.ENTITY) T updateEntity, @Param(Constants.WRAPPER) Wrapper whereWrapper);
User user = new User();
user.setId(400L);
user.setName("咕咕咕");
user.setAge(16);
user.setEmail("gugugu@gugu.com");
System.out.println("结果:" + userMapper.update(user,
new UpdateWrapper<User>().eq("id", 4L)));
==> Preparing: UPDATE user SET name=?, age=?, email=? WHERE (id = ?)
==> Parameters: 咕咕咕(String), 16(Integer), gugugu@gugu.com(String), 4(Long)
<== Updates: 1
结果:1
根据 ID 修改
int updateById(@Param(Constants.ENTITY) T entity);
User user = new User();
user.setId(4L);
user.setName("嘎嘎嘎");
user.setAge(3);
user.setEmail("gagaga@gaga.com");
System.out.println("结果:" + userMapper.updateById(user));
==> Preparing: UPDATE user SET name=?, age=?, email=? WHERE id=?
==> Parameters: 嘎嘎嘎(String), 3(Integer), gagaga@gaga.com(String), 4(Long)
<== Updates: 1
结果:1
4:BaseMapper的删除
根据 entity 条件,删除记录
int delete(@Param(Constants.WRAPPER) Wrapper wrapper);
userMapper.delete(new QueryWrapper<User>().eq("id", 1L))
删除(根据ID 批量删除)
int deleteBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList);
userMapper.deleteBatchIds(Arrays.asList(1L, 2L, 3L))
根据 ID 删除
int deleteById(Serializable id);
==> Preparing: DELETE FROM user WHERE id=?
==> Parameters: 1583712489828356098(Long)
<== Updates: 1
结果:1
根据 columnMap 条件,删除记录
int deleteByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap);
Map<String, Object> map = new HashMap<>();
map.put("name", "张三");
map.put("age", 20);
System.out.println("结果:" + userMapper.deleteByMap(map));
==> Preparing: DELETE FROM user WHERE name = ? AND age = ?
==> Parameters: 张三(String), 20(Integer)
<== Updates: 0
结果:0
2:Wrapper查询
通过BaseMapper提供的一些方法我们可以完成一些基本的CRUD,但无法完成复杂条件的查询;对于复杂条件的查询,MyBatis Plus提供了Wrapper接口来处理;
Wrapper是MyBatis Plus提供的一个条件构造器,主要用于构建一系列条件,当Wrapper构建完成后,可以使用Wrapper中的条件进行查询、修改、删除等操作;
1:Wrapper的继承体系如下
Wrapper是条件构造抽象类,最顶端父类,其主要实现类有如下:
- AbstractWrapper : 用于查询条件封装,生成 sql 的 where 条件
- QueryWrapper : Query条件封装
- UpdateWrapper : Update条件封装
- AbstractLambdaWrapper : 使用Lambda语法
- LambdaQueryWrapper :基于Lambda语法使用的查询Wrapper
- LambdaUpdateWrapper : 基于Lambda语法使用的更新Wrapper
2:Wrapper的基本方法
AbstractWrapper是其他常用Wrapper的父类,用于生成 sql 的 where 条件
1)基本方法介绍
AbstractWrapper提供了很多公有的方法,其子类全部具备这些方法,方法列表如下
* 基本⽐较操作
方法名 | 解释 | 示例 |
---|---|---|
eq | 等于 = | eq(“name”, “老王”)—>name = ‘老王’ |
ne | 不等于 <> | ne(“name”, “老王”)—>name <> ‘老王’ |
gt | 大于 > | gt(“age”, 18)—>age > 18 |
ge | 大于等于 >= | ge(“age”, 18)—>age >= 18 |
lt | 小于 < | lt(“age”, 18)—>age < 18 |
le | 小于等于 <= | le(“age”, 18)—>age <= 18 |
between | between 值1 and 值2 | between(“age”, 18, 30)—>age between 18 and 30 |
notBetween | not between 值1 and 值2 | notBetween(“age”, 18, 30)—>age not between 18 and 30 |
* 模糊查询
方法名 | 解释 | 示例 |
---|---|---|
like | LIKE ‘%值%’ | like(“name”, “王”)—>name like ‘%王%’ |
notLike | NOT LIKE ‘%值%’ | notLike(“name”, “王”)—>name not like ‘%王%’ |
likeLeft | LIKE ‘%值’ | likeLeft(“name”, “王”)—>name like ‘%王’ |
likeRight | LIKE ‘值%’ | likeRight(“name”, “王”)—>name like ‘王%’ |
* 分组排序
方法名 | 解释 | 示例 |
---|---|---|
groupBy | 分组:GROUP BY 字段, … | groupBy(“id”, “name”)—>group by id,name |
orderByAsc | 排序:ORDER BY 字段, … ASC | orderByAsc(“id”, “name”)—>order by id ASC,name ASC |
orderByDesc | 排序:ORDER BY 字段, … DESC | orderByDesc(“id”, “name”)—>order by id DESC,name DESC |
orderBy | 排序:ORDER BY 字段, … | orderBy(true, true, “id”, “name”)—>order by id ASC,name ASC |
having | HAVING ( sql语句 ) | 例1:having(“sum(age) > 10”) —>having sum(age) > 10,例2:having(“sum(age) > {0}”, 11)—>having sum(age) > 11 |
* 子查询
方法名 | 解释 | 示例 |
---|---|---|
isNull | 字段 IS NULL | isNull(“name”)—>name is null |
isNotNull | 字段 IS NOT NULL | isNotNull(“name”)—>name is not null |
in | 字段 IN (v0, v1, …) | in(“age”, 1, 2, 3)—>age in (1,2,3) |
notIn | 字段 NOT IN (v0, v1, …) | notIn(“age”, 1, 2, 3)—>age not in (1,2,3) |
inSql | 字段 IN ( sql语句 ) | inSql(“id”, “select id from table where id < 3”)—>id in (select id from table where id < 3) |
notInSql | 字段 NOT IN ( sql语句 ) | notInSql(“id”, “select id from table where id < 3”) —> id not in (select id from table where id < 3) |
* 逻辑拼接
方法名 | 解释 | 示例 |
---|---|---|
func | 主要解决条件拼接 | func(i -> if(true) {i.eq(“id”, 1)} else {i.ne(“id”, 1)}) |
or | 拼接 OR | eq(“id”,1).or().eq(“name”,“老王”)—>id = 1 or name = ‘老王’ |
and | AND 嵌套 | and(i -> i.eq(“name”, “李白”).ne(“status”, “活着”))—>and (name = ‘李白’ and status <> ‘活着’) |
nested | 用于多条件拼接时 | nested(i -> i.eq(“name”, “李白”).ne(“status”, “活着”))—>(name = ‘李白’ and status <> ‘活着’) |
apply | 用于拼接SQL语句 | 例1:apply(“id = 1”)—>id = 1,例2:apply(“id = {0}”,1)—>id = 1,例3:apply(“name like {0} and age > {1}”,“%J%”,18) —>name like ‘%J%’ and age > 18 |
last | 无视优化规则直接拼接到 sql 的最后 | last(“limit 1”) —>在SQL语句最后面拼接:limit 1 |
exists | 拼接 EXISTS ( sql语句 ) | exists(“select id from table where age = 1”)—>exists (select id from table where age = 1) |
notExists | 拼接 NOT EXISTS ( sql语句 ) | notExists(“select id from table where age = 1”)—>not exists (select id from table where age = 1) |
3:创建Wrapper对象:
- Wrappers静态方法:public static QueryWrapper query()
- QueryWrapper wrapper = Wrappers.query();
- 通过QueryWrapper对象的构造方法:public QueryWrapper()
- QueryWrapper wrapper2 = new QueryWrapper<>();
4:QueryMapper
QueryMapper是AbstractWrapper的子类,主要用于查询指定字段,方法列表如下:
方法名 | 解释 | 示例 |
---|---|---|
select(String… sqlSelect) | 设置查询字段 | 例1:select(“id”, “name”, “age”),例2:select(i -> i.getProperty().startsWith(“test”)) |
// 选择查询的字段
@Test
public void test1() throws Exception {
QueryWrapper<User> wrapper = Wrappers.query();
// 确定要查询的字段
wrapper.select("id", "name", "sex");
// in
wrapper.in("id","1","2");
// SQL: SELECT id,name,sex FROM user WHERE (id IN (?,?))
List<User> userList = userMapper.selectList(wrapper);
userList.forEach(System.out::println);
}
5:UpdateWrapper
UpdateWrapper也是AbstractWrapper的子类,因此UpdateWrapper也具备之前的那些查询方法,不同的是,UpdateMapper在那些方法基础之上还提供了很多有关于更新操作的方法;
方法名 | 解释 | 示例 |
---|---|---|
set(String column, Object val) | 设置查询字段 | 例1:set(“name”, “张三”),例2:set(“name”, “”)—>数据库字段值变为空字符串,例3:set(“name”, null)—>数据库字段值变为null |
setSql(String sql) | 设置set子句的部分SQL | 例1:setSql(“name = ‘张三’”),例2:setSql(“name = ‘张三’,age=22 where id=1”) |
@Test
public void test4() throws Exception {
User user = new User();
user.setId(1L);
// user当做查询条件
UpdateWrapper<User> wrapper = Wrappers.update(user);
wrapper.set("name", "xiaohui");
wrapper.set("sex", "0");
wrapper.set("age", "22");
// SQL : UPDATE user SET name=?,sex=?,age=? WHERE id=?
userMapper.update(null, wrapper);
}
@Test
public void test5() throws Exception {
UpdateWrapper<User> wrapper = Wrappers.update();
wrapper.setSql("name='abc',sex='0',age=18 where id=1");
// SQL: UPDATE user SET name='abc',sex='0',age=18 where id=1
userMapper.update(null, wrapper);
}
6:LambdaQueryWrapper
LambdaQueryWrapper是QueryWrapper的子类,具备QueryWrapper的所有方法,在QueryWrapper的方法上提供了一系列有关于方法链的操作;
@Test
public void test1() throws Exception {
LambdaQueryWrapper<User> wrapper = Wrappers.lambdaQuery();
wrapper.in(User::getId,"1","2","3")
.like(User::getName,"a")
.select(User::getId,User::getName,User::getAge);
List<User> userList = userMapper.selectList(wrapper);
for (User user : userList) {
System.out.println(user);
}
}
7:LambdaUpdateMapper
LambdaUpdateMapper同样是UpdateMapper的子类,具备UpdateMapper的所有方法,在UpdateMapper的方法上提供了一系列有关于方法链式的操作;
@Test
public void test2() throws Exception {
LambdaUpdateWrapper<User> wrapper = Wrappers.lambdaUpdate();
wrapper.eq(User::getId,"1").set(User::getName,"lili").set(User::getAge,18);
userMapper.update(null,wrapper);
}
MyBatis Plus的Service查询
1:通用Service简介
通用 Service CRUD 封装IService接口,进一步封装 CRUD 采用 get 查询单行、remove删除、list 查询集合、page查询分页
2:通用service常用方法
新增:
- default boolean save(T entity):新增记录
- boolean saveBatch(Collection entityList):批量插入
- saveBatch(Collection entityList, int batchSize):一次性批量插入batchSize条记录
@Test
public void test1() throws Exception {
User user = new User(null, "zhagnsan", "0", 21);
userService.save(user);
}
删除:
- boolean removeById(Serializable id):根据id删除
- boolean removeByMap(Map<String, Object> columnMap):根据条件删除
- boolean remove(Wrapper queryWrapper):使用Wrapper封装条件删除
- boolean removeByIds(Collection<? extends Serializable> idList):删除一批
@Test
public void test2() throws Exception {
userService.removeById(1L);
}
修改:
- boolean updateById(T entity):修改
- boolean update(Wrapper updateWrapper):根据Wrapper修改
- boolean update(T entity, Wrapper updateWrapper):使用Wrapper查询出结果,修改为entity
- boolean updateBatchById(Collection entityList):批量修改
- updateBatchById(Collection entityList, int batchSize):一次性批量修改batchSize条记录
- boolean saveOrUpdate(T entity):如果id存在则修改,如果id不存在则新增
/**
* 如果id存在则修改,不存在则新增
*
* @throws Exception
*/
@Test
public void test3() throws Exception {
User user = new User(1L, "zhagnsan", "0", 18);
userService.saveOrUpdate(user);
}
/**
* 根据id修改
*
* @throws Exception
*/
@Test
public void test4() throws Exception {
User user = new User(1L, "xiaolan", "1", 18);
userService.updateById(user);
}
查询:
- T getById(Serializable id):根据id查询
- List listByIds(Collection<? extends Serializable> idList):根据一批id查询多条记录
- List listByMap(Map<String, Object> columnMap):根据条件查询多条记录
- T getOne(Wrapper queryWrapper):根据Wrapper查询一条记录,如果查询到多条则抛出异常
- T getOne(Wrapper queryWrapper, boolean throwEx):根据Wrapper查询一条记录,通过throwEx决定是否抛出异常
- int count():查询总记录数
- int count(Wrapper queryWrapper):根据条件查询总记录数
/**
* 根据id查询
*
* @throws Exception
*/
@Test
public void test5() throws Exception {
User user = userService.getById(1L);
System.out.println(user);
}
/**
* 查询列表
*
* @throws Exception
*/
@Test
public void test6() throws Exception {
QueryWrapper<User> wrapper = Wrappers.query();
wrapper.in("id", "1", "2");
// 查询所有
// List<User> userList = userService.list();
// 通过wrapper查询
List<User> userList = userService.list(wrapper);
for (User user : userList) {
System.out.println(user);
}
}
/**
* 查询总记录数
*
* @throws Exception
*/
@Test
public void test7() throws Exception {
QueryWrapper<User> wrapper = Wrappers.query();
wrapper.like("name", "a");
// 查询总记录数
// int count = userService.count();
// 根据条件查询总记录数
int count = userService.count(wrapper);
System.out.println(count);
}
分页:
- <E extends IPage> E page(E page, Wrapper queryWrapper):带条件分页查询,当前页数据为T类型
- <E extends IPage> E page(E page):无条件分页
- List<Map<String, Object>> pageMaps(E page,Wrapper queryWrapper):带条件分页查询,当前页数据为HashMap类型
- List<Map<String, Object>> pageMaps(E page):无条件分页
/**
* 分页查询(当前页类型为指定类型)
*
* @throws Exception
*/
@Test
public void test8() throws Exception {
Page<User> page = new Page<>(1, 3);
userService.page(page);
// 当前页数据
List<User> pageData = page.getRecords();
for (User user : pageData) {
System.out.println(user);
}
System.out.println("------------");
System.out.println("当前页:" + page.getCurrent());
System.out.println("每页显示的条数:" + page.getSize());
System.out.println("总记录数:" + page.getTotal());
System.out.println("总页数:" + page.getPages());
System.out.println("是否有上一页:" + page.hasPrevious());
System.out.println("是否有下一页:" + page.hasNext());
}
/**
* 分页查询(当前页结果为HashMap类型)
*
* @throws Exception
*/
@Test
public void test9() throws Exception {
Page page = new Page<>(1, 3);
userService.pageMaps(page);
// 当前页数据
List<HashMap<String, Object>> pageData = page.getRecords();
for (HashMap userMap : pageData) {
System.out.println(userMap);
}
System.out.println("------------");
System.out.println("当前页:" + page.getCurrent());
System.out.println("每页显示的条数:" + page.getSize());
System.out.println("总记录数:" + page.getTotal());
System.out.println("总页数:" + page.getPages());
System.out.println("是否有上一页:" + page.hasPrevious());
System.out.println("是否有下一页:" + page.hasNext());
}