Mybatis-Plus
1、基本概述
MyBatis-Plus(简称 MP),为简便而生,只在Mybatis的基础上做增强,其中一个就是将基本的CRUD的sql进行自动拼接
2、Mybatis 与 MP 的优缺点
MyBatis
优点:
1>SQL语句自由控制,较为灵活
2>SQL与业务代码分离,易于阅读与维护
3>提供动态SQL语句,可以根据需求灵活控制
缺点:
1>简单的crud操作也必须提供对应SQL语句
2>必须维护大量的xml文件
3>自身功能有限,要拓展只能依赖第三方插件
MyBatis-plus(MP) 是在Mybatis的基础上进行二次开发的具有MyBatis所有功能, 也添加了不少好用的功能
比如:
1>提供无sql 的crud操作
2>内置代码生成器,分页插件, 性能分析插件等
3>提供功能丰富的条件构造器快速进行无sql开发
3、导入相应依赖
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.3</version>
</parent>
<dependencies>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.0</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.17</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.22</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.16</version>
<scope>provided</scope>
</dependency>
</dependencies>
4、配置application.properties文件
#mysql
spring.datasource.url=jdbc:mysql://192.168.126.129:3306/mybatis-plus?useUnicode=true&characterEncoding=utf8
spring.datasource.username=root
spring.datasource.password=admin
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
# 配置slq打印日志
第一种:
logging.level.cn.wolfcode.mp.mapper=debug
第二种:
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
5、写个EmployeeMapper接口继承BaseMapper
public interface EmployeeMapper extends BaseMapper<Employee> {
}
6、MP常用注解
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.ToString;
@Data
@ToString
@TableName("Employee") //指定当前实体类映射哪张数据库表, 默认是跟实体类名一致
public class Employee {
@TableId(type = IdType.AUTO) //id自增
private Long id;
private String name;
private String password;
private String email;
private int age;
private boolean admin;
private Long deptId; //Mybatis-Plus会自动将驼峰命名法转换成mysql中_形式(deptId---> dept_id)
@TableField(exist = false) // 当属性没有映射列时,使用
private Department dept;
}
@TableName(“表名”) :指定当前实体类映射哪张数据库表, 默认是跟实体类名一致
@TableField(“列名”) : 指定当前属性映射数据库表哪一列, 默认是跟属性名一致
例子: @TableField(exist = false) // 当属性没有映射列时,使用
@TableId(“自增算法”) : 标记当前属性映射表主键。
例子 :@TableId(type=IdType.AUTO) ID自增
@TableId(type=IdType.NONE) 无状态,该类型为未设置主键类型
@TableId(type=IdType.INPUT) insert前自行set主键值
@TableId(type=IdType.ASSIGN_ID) 分配ID
@TableId(type=IdType.ASSIGN_UUID) 分配UUID,主键类型为String(since 3.3.0),使用接口IdentifierGenerator的方法nextUUID(默认default方法)
7、通用Mapper接口
添加方法1个,更新方法2个,删除方法4个,查询方法7个(必须掌握)
1、insert(Object entity)方法
//需求:添加一条用户信息
@Test
public void testSave(){
Employee employee = new Employee();
employee.setAdmin(1);
employee.setAge(18);
employee.setDeptId(1L);
employee.setEmail("dafei@wolfcode.cn");
employee.setName("dafei");
employee.setPassword("1");
employeeMapper.insert(employee);
}
//sql语句
INSERT INTO employee ( name, password, email, age, admin, dept_id ) VALUES ( ?, ?, ?, ?, ?, ? )
//注意:主键增长的方式变了,要在主键属性上贴注解
2、update 方法
/**
* updateById(entity)
* 需求:将id=1用户名字修改为dafei
* UPDATE employee SET name=?, password=?, email=?, age=?, admin=?, dept_id=? WHERE id=?
*/
@Test
public void updateById(){
//方式一:1:先查 2:替换 3:更新
Employee employee = employeeMapper.selectById(1L);
employee.setName("dafei");
employeeMapper.updateById(employee);
}
/**
* update(entity, wrapper)
* 需求:更新name=dafei员工年龄为18岁
* UPDATE employee SET age=? WHERE (id = ?)
*/
@Test
public void update(){
UpdateWrapper<Employee> wrapper = new UpdateWrapper<>();
wrapper.eq("id",1L);
wrapper.set("age",18);
employeeMapper.update(null,wrapper);
}
/**
* 更新name=dafei,并且password=1111的员工年龄为18岁
* UPDATE employee SET age=? WHERE (name = ? AND password = ?)
*/
@Test
public void test(){
UpdateWrapper<Employee> wrapper = new UpdateWrapper<>();
wrapper.eq("name","dafei").eq("password","1111");
wrapper.set("age",18);
employeeMapper.update(null,wrapper);
}
总结:
什么时候用updateById?什么时候用update?
1.where条件是id时,并且所有更新使用updateById
2.where条件不是id时,部分字段更新,使用update
使用这种方式:wrapper.条件.set更新字段
/**
* updateById
* :全量更新, 只要传入对象属性不为null, 都可以进行update更新, 条件是通过id匹配
* 正确操作姿势: 前提: 必须知道id
* //1:查
* //2:替换
* //3:更新
* update+wrapper
* :部分字段更新, 通过wrapper对象拼接各种满足要求条件, 更新set的列由wrapper 决定
* 正确操作姿势:
* 1>设置更新条件
* 2>拼接更新列
*/
3、delete 方法
/**
* 删除id=1的员工信息
* DELETE FROM employee WHERE id=?
*/
@Test
public void deleteById(){
employeeMapper.deleteById(1L);
}
/**
* 删除id=1, id=2的员工信息
* DELETE FROM employee WHERE id IN ( ? , ? )
*/
@Test
public void deleteBatchIds(){
employeeMapper.deleteBatchIds(Arrays.asList(1L,2L));
}
/**
* 需求:删除name=dafei并且age=18的员工信息
* DELETE FROM employee WHERE name = ? AND age = ?
*/
@Test
public void deleteByMap(){
HashMap<String, Object> map = new HashMap<>();
map.put("name","dafei");
map.put("age",18);
employeeMapper.deleteByMap(map);
}
/**
*需求:删除name=dafei并且age=18的员工信息
*DELETE FROM employee WHERE (name = ? AND age = ?)
*/
@Test
public void deleteWrapper(){
QueryWrapper<Employee> wrapper = new QueryWrapper<>();
wrapper.eq("name","dafei");
wrapper.eq("age",18);
employeeMapper.delete(wrapper);
}
4、select 方法
/**
* 查询id=1的员工信息
* SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE id=?
*/
@Test
public void selectById(){
System.out.println(employeeMapper.selectById(1L));
}
/**
* 需求:查询id=1,id=2的员工信息
* SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE id IN ( ? , ? )
*/
@Test
public void selectBatchIds(){
System.out.println(employeeMapper.selectBatchIds(Arrays.asList(1L, 2L)));
}
/**
*需求: 查询name=dafei, age=18的员工信息
*SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE name = ? AND age = ?
*/
@Test
public void selectByMap(){
HashMap<String, Object> map = new HashMap<>();
map.put("name","dafei");
map.put("age",18);
List<Employee> employeeList = employeeMapper.selectByMap(map);
System.out.println(employeeList);
}
/**
* 需求: 查询满足条件的所有的员工个数
* SELECT COUNT( 1 ) FROM employee
*/
@Test
public void selectByCount(){
QueryWrapper<Employee> wrapper = new QueryWrapper<>();
Integer count = employeeMapper.selectCount(wrapper);
System.out.println(count);
}
/**
* 需求: 查询满足条件的所有的员工信息, 返回List<Employee>
* SELECT id,name,password,email,age,admin,dept_id FROM employee
*/
@Test
public void selectList(){
//方式一
// List<Employee> list = employeeMapper.selectList(null);
// list.forEach(System.out::println);
//方式二
QueryWrapper<Employee> wrapper = new QueryWrapper<>();
List<Employee> list = employeeMapper.selectList(wrapper);
list.forEach(System.out::println);
}
/**
* 如果查询所有的数据信息能进行封装则用selectList查询;若不能封装,
* 则用selectMaps进行查询,因为HashMap可以将"列"对应的"值"封装到map集合中的key和value上
*
* 需求: 查询满足条件的所有的员工信息, 返回List<Map<String, Object>> 底层将每条数据封装成HashMap
* SELECT id,name,password,email,age,admin,dept_id FROM employee
*/
@Test
public void selectMaps(){
//方式一:没有指定条件, 等价于传入null
// List<Map<String, Object>> maps = employeeMapper.selectMaps(null);
// maps.forEach(System.out::println);
//方式二:
QueryWrapper<Employee> wrapper = new QueryWrapper<>();
List<Map<String, Object>> maps = employeeMapper.selectMaps(wrapper);
maps.forEach(System.out::println);
}
/**
* 需求:查询第二页员工数据, 每页显示3条, (分页返回的数据是实体对象)
* SELECT id,name,password,email,age,admin,dept_id FROM employee LIMIT ?,?
*/
@Test
public void selectPage(){
QueryWrapper<Employee> wrapper = new QueryWrapper<>();
//参数1:当前页, 参数2:每页显示条数
IPage<Employee> page = new Page<>(2, 3);
employeeMapper.selectPage(page, wrapper);
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());
}
8、继承体系
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MBloKJzA-1646450206859)(G:\桌面\叩丁狼\课堂资料\07 项目二-大飞\03.Mybatis-plus\Warrper继承体系.png)]
父类:AbstaractWrapper
共有条件方法
allEq、eq、ne、gt、ge、lt、le、between、notBetween、
like、notLike、likeLeft、likeRight、isNull、isNotNull、
in、notIn、inSql、notInSql、groupBy、orderByAsc、orderByDesc、orderBy、having、
func、or、and、nested、apply、last、exists、notExists、
修改型子类
实现子类:UpdateWrapper,LambdaUpdateWrapper
独有的实现方法:set,setSql
查询型子类
实现子类:QueryWrapper,LambdaQueryWrapper
独有的实现方法:select
1、更新操作
/**
* UpdateWrapper更新
* 需求:将id=1的员工age改为18, 如果传入uname变量值不等于null或者“”,修改为员工name为uname变量值
* UPDATE employee SET age=? WHERE (id = ?)
*/
@Test
public void update2(){
String uname = "";
UpdateWrapper<Employee> wrapper = new UpdateWrapper<>();
wrapper.eq("id",1)
.set("age",18);
if (StringUtils.hasLength(uname)) {
wrapper.set("name",uname);
}
// wrapper.eq("id",1L)
// .set(StringUtils.hasLength(uname),"name",uname);
employeeMapper.update(null,wrapper);
}
/**
* UpdateWrapper更新(使用setSql==sql片段拼接) set和setSql均可用
* 需求:将id=1的用户name改为dafei
* UPDATE employee SET name='dafei' WHERE (id = ?)
*/
@Test
public void update3(){
UpdateWrapper<Employee> wrapper = new UpdateWrapper<>();
wrapper.eq("id",1L)
.setSql("name='dafei'");
employeeMapper.update(null,wrapper);
}
/**
* LambdaUpdateWrapper更新
* 需求:将id=1的用户name改为dafei
* UPDATE employee SET name=? WHERE (id = ?)
*/
@Test
public void update4(){
LambdaUpdateWrapper<Employee> wrapper = new LambdaUpdateWrapper<>();
wrapper.eq(Employee::getId,1L)
.set(Employee::getName,"dafei");
employeeMapper.update(null,wrapper);
}
2、查询操作
/**
* 普通查询
* 需求:查询name=dafei, age=18的用户
* SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE name = ? AND age = ?
*/
@Test
public void select(){
HashMap<String, Object> map = new HashMap<>();
map.put("name","dafei");
map.put("age",18);
List<Employee> employees = employeeMapper.selectByMap(map);
employees.forEach(System.out::println);
}
/**
* QueryWrapper查询
*需求:查询name=dafei, age=18的用户
* SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE (name = ? AND age = ?)
*/
@Test
public void select2(){
QueryWrapper<Employee> wrapper = new QueryWrapper<>();
wrapper.eq("name","dafei").eq("age",18);
employeeMapper.selectList(wrapper);
}
/**
* LambdaQueryWrapper查询
* 需求:查询name=dafei, age=18的用户
* SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE (name = ? AND age = ?)
*/
@Test
public void select3(){
LambdaQueryWrapper<Employee> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(Employee::getName,"dafei")
.eq(Employee::getAge,18);
employeeMapper.selectList(wrapper);
}
9、高级查询
1、列投影 select
/**
* wrapper.select指定查询某些列
* 需求:查询所有员工, 返回员工name, age列
* SELECT name,age FROM employee
*/
@Test
public void query1(){
QueryWrapper<Employee> wrapper = new QueryWrapper<>();
wrapper.select("name","age");
List<Employee> employees = employeeMapper.selectList(wrapper);
employees.forEach(System.out::println);
}
/**
* 需求:查询所有员工, 返回员工以a字母开头的列
* SELECT id,age,admin FROM employee
*/
@Test
public void query2(){
QueryWrapper<Employee> wrapper = new QueryWrapper<>();
wrapper.select(Employee.class,tableFieldInfo -> tableFieldInfo.getProperty().startsWith("a"));
List<Employee> employees = employeeMapper.selectList(wrapper);
employees.forEach(System.out::println);
}
2、排序 orderByAsc/orderByDesc
/**
* orderByAsc
* 需求:查询所有员工信息按age正序排, 如果age一样, 按id正序排
* SELECT id,name,password,email,age,admin,dept_id FROM employee ORDER BY age ASC,id ASC
*/
@Test
public void query3(){
QueryWrapper<Employee> wrapper = new QueryWrapper<>();
wrapper.orderByAsc("age","id");
List<Employee> employees = employeeMapper.selectList(wrapper);
employees.forEach(System.out::println);
}
/**
* 需求:查询所有员工信息按age正序排, 如果age一样, 按id倒序排
* SELECT id,name,password,email,age,admin,dept_id FROM employee ORDER BY age ASC,id DESC
*/
@Test
public void query4(){
QueryWrapper<Employee> wrapper = new QueryWrapper<>();
wrapper.orderByAsc("age").orderByDesc("id");
employeeMapper.selectList(wrapper);
}
3、 分组查询
groupBy
/**
* groupBy
* 需求: 以部门id进行分组查询,查每个部门员工个数
*/
@Test
public void query5(){
QueryWrapper<Employee> wrapper = new QueryWrapper<>();
wrapper.groupBy("dept_id")
.select("dept_id","count(*) count");
employeeMapper.selectList(wrapper);
}
having
/**
* having
* 需求: 以部门id进行分组查询,查每个部门员工个数, 将大于3人的部门过滤出来
* SELECT dept_id,count(*) count FROM employee GROUP BY dept_id HAVING count(*) > 3
*/
@Test
public void query6(){
QueryWrapper<Employee> wrapper = new QueryWrapper<>();
wrapper.groupBy("dept_id")
.select("dept_id","count(*) count")
.having("count(*) > 3");
employeeMapper.selectList(wrapper);
}
4、比较运算符
/**
* allEq : 全等匹配
* 需求:查询name=dafei, age=18的员工信息
* SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE (name = ? AND age = ?)
*/
@Test
public void query7(){
HashMap<String, Object> map = new HashMap<>();
map.put("name","dafei");
map.put("age",18);
map.put("dept_id",null);
QueryWrapper<Employee> wrapper = new QueryWrapper<>();
wrapper.allEq(map,false);//是否允许空字段传入比对条件中
employeeMapper.selectList(wrapper);
}
/**
* gt:> lt:< ge:>= le:<= ne:<>不等于
* 需求:查询age 大于18岁 小于30岁员工信息
* SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE (age > ? AND age < ?)
*/
@Test
public void query8(){
QueryWrapper<Employee> wrapper = new QueryWrapper<>();
wrapper.gt("age",18).lt("age",30);
List<Employee> employees = employeeMapper.selectList(wrapper);
employees.forEach(System.out::println);
}
/**
* between/notBetween
* 需求:查询年龄介于18~30岁的员工信息
* SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE (age BETWEEN ? AND ?)
*/
@Test
public void query9(){
QueryWrapper<Employee> wrapper = new QueryWrapper<>();
wrapper.between("age",18,30);
List<Employee> employees = employeeMapper.selectList(wrapper);
employees.forEach(System.out::println);
}
/**
* isNull/isNotNull
* 需求: 查询dept_id 为null 员工信息
* SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE (dept_id IS NULL)
*/
@Test
public void query10(){
QueryWrapper<Employee> wrapper = new QueryWrapper<>();
wrapper.isNull("dept_id");
employeeMapper.selectList(wrapper);
}
/**
* in
* 需求: 查询id为1, 2 的员工信息
* SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE (id IN (?,?))
*/
@Test
public void query11(){
QueryWrapper<Employee> wrapper = new QueryWrapper<>();
wrapper.in("id",1L,2L);
List<Employee> employees = employeeMapper.selectList(wrapper);
employees.forEach(System.out::println);
}
/**
* notIn
* 需求: 查询id不为1, 2 的员工信息
* SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE (id NOT IN (?,?))
*/
@Test
public void query12(){
QueryWrapper<Employee> wrapper = new QueryWrapper<>();
wrapper.notIn("id",1L,2L);
List<Employee> employees = employeeMapper.selectList(wrapper);
employees.forEach(System.out::println);
}
/**
* inSql("id","1,2")(sql片段拼接) == in
* notInSql("id","1,2")(sql片段拼接) == notIn
* 需求: 查询id为1, 2 的员工信息
*/
@Test
public void query13(){
QueryWrapper<Employee> wrapper = new QueryWrapper<>();
wrapper.inSql("id","1,2");
List<Employee> employees = employeeMapper.selectList(wrapper);
employees.forEach(System.out::println);
}
5、模糊查询
/**
* like/notLike
* 需求: 查询name中含有fei字样的员工
* SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE (name LIKE ?)
*/
@Test
public void query14(){
QueryWrapper<Employee> wrapper = new QueryWrapper<>();
wrapper.like("name","fei");
List<Employee> employees = employeeMapper.selectList(wrapper);
employees.forEach(System.out::println);
}
/**
* likeLeft: LIKE '%值'
* 需求: 查询name以fei结尾的员工信息
*/
@Test
public void query15(){
QueryWrapper<Employee> wrapper = new QueryWrapper<>();
wrapper.likeLeft("name","fei");
employeeMapper.selectList(wrapper);
}
/**
* likeRight: LIKE '值%'
* 需求: 查询姓赵的员工信息
*/
@Test
public void query16(){
QueryWrapper<Employee> wrapper = new QueryWrapper<>();
wrapper.likeRight("name","赵");
List<Employee> employees = employeeMapper.selectList(wrapper);
employees.forEach(System.out::println);
}
6、逻辑运算符
/**
*
* 需求: 查询age = 18 或者 name=dafei 或者 id =1 的用户
* SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE (age = ? OR name = ? OR id = ?)
*/
@Test
public void query17(){
QueryWrapper<Employee> wrapper = new QueryWrapper<>();
wrapper.eq("age",18)
.or()
.eq("name","dafei")
.or()
.eq("id",1L);
List<Employee> employees = employeeMapper.selectList(wrapper);
employees.forEach(System.out::println);
}
/**
* 嵌套OR
* 需求:查询name含有fei字样的,或者 年龄在18到30之间的用户
* SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE (name = ? OR (age >= ? AND age <= ?))
*
*/
@Test
public void query18(){
QueryWrapper<Employee> wrapper = new QueryWrapper<>();
wrapper.eq("name","dafei")
.or(a -> a.ge("age",18).le("age",30));
List<Employee> employees = employeeMapper.selectList(wrapper);
employees.forEach(System.out::println);
}
/**
* 嵌套and
*需求:查询name含有fei字样的并且 年龄在小于18或者大于30的用户
* SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE (name LIKE ? AND (age < ? OR age > ?))
*/
@Test
public void query19(){
QueryWrapper<Employee> wrapper = new QueryWrapper<>();
wrapper.like("name","fei")
.and(a -> a.lt("age",18).or().gt("age",30));
List<Employee> employees = employeeMapper.selectList(wrapper);
employees.forEach(System.out::println);
}
10、通用Service接口
通用方式
1:自定义服务接口集成IService接口
public interface IEmployeeService extends IService<Employee> {
}
2:服务接口实现类集成IService接口实现类ServiceImpl同时实现自定义接口
注意ServiceImpl实现类泛型:
泛型1:实体类的mapper接口
泛型2:实体类
@Service
public class EmployeeServiceImpl extends ServiceImpl<EmployeeMapper, Employee> implements IEmployeeService {
}
常用方法
getBaseMapper() //获取引用的XxxxMapper对象
getOneMapper() //指定条件查询单个, 结果数据超过1个报错
list(wrapper) //指定条件查询多个
page(page,wrapper) //分页+高级查询
分页 + 高级查询****page(page, wrapper)
步骤1:配置分页插件
//分页
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
PaginationInnerInterceptor paginationInnerInterceptor = new PaginationInnerInterceptor(DbType.MYSQL);
paginationInnerInterceptor.setOverflow(true); //合理化
interceptor.addInnerInterceptor(paginationInnerInterceptor);
return interceptor;
}
步骤2:编写分页代码
@Override
public IPage<Employee> queryPage(EmployeeQueryObject qo) {
IPage<Employee> page = new Page<>(qo.getCurrentPage(),qo.getPageSize());
QueryWrapper<Employee> wrapper = new QueryWrapper<>();
wrapper.like("name",qo.getKeyword());
return employeeMapper.selectPage(page,wrapper);
}
/**
* 分页 + 高级查询 操作
*需求:查询第2页员工信息, 每页显示3条, 按id排序
*/
@Test
public void page(){
EmployeeQueryObject qo = new EmployeeQueryObject();
qo.setCurrentPage(2);
qo.setPageSize(3);
qo.setKeyword("周");
//自定义一个分页查询的方法queryPage
IPage<Employee> page = employeeService.queryPage(qo);
System.out.println("当前页:" + page.getCurrent());
System.out.println("总页数:" + page.getPages());
System.out.println("每页显示条数:" + page.getSize());
System.out.println("总记录数:" + page.getTotal());
System.out.println("当前页显示记录:" + page.getRecords());
}
11、事务
需求:在IEmployeeService 定义一个tran方法, 执行save2次, 在中间模拟事务
步骤1:定义tran方法, 实现逻辑
步骤2:在EmployeeServiceImpl类头顶贴@Transactional
public void tran() {
Employee employee = new Employee();
employee.setName("dafei1");
super.save(employee);
System.out.println(1/0);
employee = new Employee();
employee.setName("dafei2");
super.save(employee);
}
t();
qo.setCurrentPage(2);
qo.setPageSize(3);
qo.setKeyword(“周”);
//自定义一个分页查询的方法queryPage
IPage page = employeeService.queryPage(qo);
System.out.println("当前页:" + page.getCurrent());
System.out.println("总页数:" + page.getPages());
System.out.println("每页显示条数:" + page.getSize());
System.out.println("总记录数:" + page.getTotal());
System.out.println("当前页显示记录:" + page.getRecords());
}
#### 11、事务
```java
需求:在IEmployeeService 定义一个tran方法, 执行save2次, 在中间模拟事务
步骤1:定义tran方法, 实现逻辑
步骤2:在EmployeeServiceImpl类头顶贴@Transactional
public void tran() {
Employee employee = new Employee();
employee.setName("dafei1");
super.save(employee);
System.out.println(1/0);
employee = new Employee();
employee.setName("dafei2");
super.save(employee);
}