MyBatisPlus(简称MP)是基于MyBatis框架基础上开发的增强型工具,旨在简化开发、提高效率
MyBatisPlus简介
入门案例
- 创建新模块,选择Spring初始化,并配置模块相关基础信息
- 选择当前模块需要使用的技术集(仅选择MySQL Driver)
- 手动添加mp起步依赖
<dependencies>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.1</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.2.16</version>
</dependency>
由于mp并未被收录到idea的系统内置配置,无法直接选择加入
- 设置Jdbc参数( application. yml)
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/db1
username: root
password: "031006"
- 制作实体类与表结构(类名与表名对应,属性名与字段名对应)
package com.example.domain;
public class User {
private Long id;
private String name;
private String password;
private Integer age;
private String tel;
@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
", password='" + password + '\'' +
", age=" + age +
", tel='" + tel + '\'' +
'}';
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getTel() {
return tel;
}
public void setTel(String tel) {
this.tel = tel;
}
}
- 定义数据接口,继承BaseMapper<User>
package com.example.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.domain.User;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface UserDao extends BaseMapper<User> {
}
- 测试类中注入dao接口,测试功能
package com.example;
import com.example.dao.UserDao;
import com.example.domain.User;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.List;
@SpringBootTest
class MybatisplusApplicationTests {
@Autowired
private UserDao userDao;
@Test
void testGetAll() {
List<User> users = userDao.selectList(null);
System.out.println(users);
}
}
运行结果为
[User{id=1, name='Tom', password='tom123', age=18, tel='181633335556'}, User{id=2, name='Jerry', password='jerry666', age=17, tel='19533336666'}, User{id=3, name='Ben', password='ben555', age=20, tel='13788889999'}, User{id=4, name='王小明', password='wxm123456', age=19, tel='19999997787'}]
MyBatisPlus概述
MyBatisPlus(简称MP)是基于MyBatis框架基础上开发的增强型工具,旨在简化开发、提高效率
官网: MyBatis-Plus MyBatis-Plus (baomidou.com)
特性
- 无侵入:只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑
- 强大的 CRUD 操作:内置通用 Mapper、通用 Service,仅仅通过少量配置即可实现单表大部分 CRUD 操作,更有强大的条件构造器,满足各类使用需求
- 支持 Lambda 形式调用:通过 Lambda 表达式,方便的编写各类查询条件,无需再担心字段写错
- 支持主键自动生成:支持多达 4 种主键策略(内含分布式唯一 ID 生成器 - Sequence),可自由配置,完美解决主键问题
- 内置分页插件:基于 MyBatis 物理分页,开发者无需关心具体操作,配置好插件之后,写分页等同于普通 List 查询
- …
标准数据层开发
标准数据层CRUD功能
功能 | MP接口 |
---|---|
新增 | int insert(T t) |
删除 | int deleteById(Serializable id) |
修改 | int UpdateById(T t) |
根据id查询 | T selectById(Serializable id) |
查询全部 | List<T> selectList() |
分页查询 | IPage<T> selectPage(Ipage<T> page) |
按条件查询 | IPage<T> selectPage(Wrapper<T> queryWrapper) |
package com.example;
import com.example.dao.UserDao;
import com.example.domain.User;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.List;
@SpringBootTest
class MybatisplusApplicationTests {
@Autowired
private UserDao userDao;
@Test
void testInsert() {
User user = new User();
user.setAge(18);
user.setName("Faiz");
user.setTel("18155555555");
user.setPassword("faiz555");
userDao.insert(user);
}
@Test
void testDelete() {
userDao.deleteById(1685579916861468673L);
}
@Test
void testUpdate() {
User user = new User();
// 只修改set好的字段
user.setAge(18);
user.setName("Faiz");
user.setId(4L);
userDao.updateById(user);
}
@Test
void testGetById() {
User user = userDao.selectById(2L);
System.out.println(user);
}
@Test
void testGetAll() {
List<User> users = userDao.selectList(null);
System.out.println(users);
}
}
lombok
Lombok,一个Java类库,提供了一组注解,简化PO30实体类开发
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
package com.example.domain;
import lombok.*;
// lombok
//@Setter
//@Getter
//@ToString
//@NoArgsConstructor
//@AllArgsConstructor
@Data
public class User {
private Long id;
private String name;
private String password;
private Integer age;
private String tel;
}
常用注解:@Data
- 为当前实体类在编译期设置对应的get/set方法,toString方法, hashCode方法,equals方法等
分页功能
- 设置分页拦截器作为Spring管理的bean
package com.example.config;
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;
@Configuration
public class MpConfig {
@Bean
public MybatisPlusInterceptor mpIntercepter() {
// 1.定义Mp拦截器
MybatisPlusInterceptor mpIntercepter = new MybatisPlusInterceptor();
// 2.添加具体的拦截器
mpIntercepter.addInnerInterceptor(new PaginationInnerInterceptor());
return mpIntercepter;
}
}
- 执行分页查询
@Test
void testGetByPage() {
IPage page = new Page(1,2);
userDao.selectPage(page,null);
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());
}
运行结果为:
当前页码值:1
每页显示数:2
一共多少页:2
一共多少条数据:4
数据:[User(id=1, name=Tom, password=tom123, age=18, tel=181633335556), User(id=2, name=Jerry, password=jerry666, age=17, tel=19533336666)]
开启MP的日志(输出到控制台)
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/db1
username: root
password: "031006"
# 开启MP的日志(输出到控制台)
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
DQL编程控制
条件查询方式
MyBatisPlus将书写复杂的SQL查询条件进行了封装,使用编程的形式完成查询条件的组合
@Test
void testGetAll() {
// 方式一,按条件查询
QueryWrapper wrapper = new QueryWrapper();
// age < 18
wrapper.lt("age",18);
List<User> users1 = userDao.selectList(wrapper);
System.out.println(users1);
// 方式二,lambda格式按条件查询
QueryWrapper<User> wrapper2 = new QueryWrapper<>();
// age < 18
wrapper2.lambda().lt(User::getAge,18);
List<User> users2 = userDao.selectList(wrapper);
System.out.println(users2);
// 方式三,lambda格式按条件查询
LambdaQueryWrapper<User> lambdaQueryWrapper1 = new LambdaQueryWrapper<>();
// age < 18
lambdaQueryWrapper1.lt(User::getAge,18);
List<User> users = userDao.selectList(lambdaQueryWrapper1);
System.out.println(users);
LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
// // age < 20
// lambdaQueryWrapper.lt(User::getAge,20);
// // age > 17
// lambdaQueryWrapper.gt(User::getAge,17);
// age < 20 && age > 17
// lambdaQueryWrapper.lt(User::getAge,20).gt(User::getAge,17);
// age < 18 || age > 20
lambdaQueryWrapper.lt(User::getAge,18).or().gt(User::getAge,20);
List<User> users3 = userDao.selectList(lambdaQueryWrapper);
System.out.println(users3);
}
null值处理
- 方式一:用if
- 方式二:
UserQuery userQuery = new UserQuery();
// userQuery.setAge(20);
userQuery.setAge2(17);
LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
// 先判断第一个条件是否为true,为true则连接当前条件
// age < 20
lambdaQueryWrapper.lt(null != userQuery.getAge(),User::getAge,userQuery.getAge());
// age > 17
lambdaQueryWrapper.gt(null != userQuery.getAge2(),User::getAge,userQuery.getAge2());
List<User> users = userDao.selectList(lambdaQueryWrapper);
System.out.println(users);
查询投影
- 查询结果包含模型类中部分属性
// 查询投影
// 方式一
LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.select(User::getId,User::getName,User::getAge);
List<User> users1 = userDao.selectList(lambdaQueryWrapper);
// 方式二
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.select("id","name","age");
List<User> users2 = userDao.selectList(queryWrapper);
System.out.println(users1);
System.out.println(users2);
- 查询结果包含模型类中未定义的属性
// 查询投影
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.select("count(*) as count,age");
queryWrapper.groupBy("age");
List<Map<String, Object>> users = userDao.selectMaps(queryWrapper);
System.out.println(users);
查询条件设定
- 范围匹配(> 、= . between)
- 模糊匹配(like)
- 空判定(null)
- 包含性匹配(in)
- 分组(group)
- 排序(order)
- …
eq匹配
LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<>();
lqw.eq(User::getName,"Faiz");
lqw.eq(User::getPassword,"wxm123456");
// List<User> users = userDao.selectList(lqw);
// System.out.println(users);
User user = userDao.selectOne(lqw);
System.out.println(user);
范围查询
LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<>();
// 范围查询 lt,le,gt,ge,eq,between
// 18 <= age <20
lqw.between(User::getAge,18,20);
List<User> users = userDao.selectList(lqw);
System.out.println(users);
模糊匹配
// 模糊匹配 like
// %e%(String)
// lqw.like(User::getName,"e");
// // [User(id=2, name=Jerry, password=jerry666, age=17, tel=19533336666), User(id=3, name=Ben, password=ben555, age=20, tel=13788889999), User(id=6, name=Decade, password=wxmmmmm, age=19, tel=16666666666)]
// %e(String)
lqw.likeLeft(User::getName,"e");
// [User(id=6, name=Decade, password=wxmmmmm, age=19, tel=16666666666)]
// e%(String)
// lqw.likeRight(User::getName,"e");
// []
List<User> users = userDao.selectList(lqw);
System.out.println(users);
字段映射与表名映射
问题一:表字段与编码属性设计不同步
-
名称:@TableField
-
类型:属性注解
-
位置:模型类属性定义上方
-
作用:设置当前属性对应的数据库表中的字段关系
-
范例:
public class User { @TableField(value="pwd") private String password; }
-
相关属性
- value(默认):设置数据库表字段名称
问题二:编码中添加了数据库中未定义的属性
-
名称:@TableField
-
类型:属性注解
-
位置:模型类属性定义上方
-
作用:设置当前属性对应的数据库表中的字段关系
-
范例:
public class User { @TableField(exist = false) private Integer online; }
-
相关属性
- value:设置数据库表字段名称
- exist:设置属性在数据库表字段中是否存在,默认为true。此属性无法与value合并使用
问题三:采用默认查询开放了更多的字段查看权限
-
名称:@TableField
-
类型:属性注解
-
位置:模型类属性定义上方
-
作用:设置当前属性对应的数据库表中的字段关系
-
范例:
public class User { @TableField(value="pwd",select = false) private String password; }
-
相关属性
- value:设置数据库表字段名称
- exist:设置属性在数据库表字段中是否存在,默认为true。此属性无法与value合并使用
- select:设置属性是否参与查询,此属性与select()映射配置不冲突
问题四:表名与编码开发设计不同步
-
名称:@TableName
-
类型:类注解
-
位置:模型类定义上方
-
作用:设置当前类对应与数据库表关系
-
范例:
@TableName("tbl_user") public class User { private Long id; }
-
相关属性
- value:设置数据库表名称
package com.example.domain;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.*;
// lombok
//@Setter
//@Getter
//@ToString
//@NoArgsConstructor
//@AllArgsConstructor
@Data
@TableName("tbl_user")
public class User {
private Long id;
private String name;
@TableField(value = "pwd",select = false)
private String password;
private Integer age;
private String tel;
@TableField(exist = false)
private Integer online;
}
DML编程控制
Insert
id生成策略
不同的表应用不同的id生成策略
- 日志:自增( 1,2,3,4,…
- 购物订单:特殊规则( FQ23948AK3843)
- 外卖单:关联地区日期等信息( 10 04 20200314 34 91)
- 关系表:可省略id
- …
id生成策略控制
- 名称:@TableId
- 类型:属性注解
- 位置:模型类中用于表示主键的属性定义上方
- 作用:设置当前类中主键属性的生成策略·范例:
public class User {
@TableId(type = IdType.AUTO)
private Long id;
}
- 相关属性
- value:设置数据库主键名称
- type:设置主键属性的生成策略,值参照IdType枚举值
- AUTO(0)∶使用数据库id自增策略控制id生成
- NONE(1):不设置id生成策略
- INPUT(2):用户手工输入id
- ASSIGN_ID(3):雪花算法生成id(可兼容数值型与字符串型)
- ASSIGN_UUID(4):以UUID生成算法作为id生成策略
package com.example.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.*;
// lombok
//@Setter
//@Getter
//@ToString
//@NoArgsConstructor
//@AllArgsConstructor
@Data
@TableName("tbl_user")
public class User {
// 使用数据库定义的
// @TableId(type = IdType.AUTO)
// 自己定义 user.setId(555L);
// @TableId(type = IdType.INPUT)
// 雪花算法
@TableId(type = IdType.ASSIGN_ID)
private Long id;
private String name;
@TableField(value = "pwd",select = false)
private String password;
private Integer age;
private String tel;
@TableField(exist = false)
private Integer online;
}
id生成策略全局配置
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/db1
username: root
password: "031006"
main:
banner-mode: off
# 开启MP的日志(输出到控制台)
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
global-config:
banner: false
db-config:
id-type: assign_id
table-prefix: tbl_
Delete
多记录操作
@Test
void testDelete() {
// userDao.deleteById(1685579916861468673L);
List<Long> list = new ArrayList<>();
list.add(1685940449313812482L);
list.add(1685941696037003266L);
list.add(1685942172673523714L);
userDao.deleteBatchIds(list);
}
逻辑删除
- 删除操作业务问题:业务数据从数据库中丢弃
- 逻辑删除:为数据设置是否可用状态字段,删除时设置状态字段为不可用状态,数据保留在数据库中
@Data
//@TableName("tbl_user")
public class User {
// 使用数据库定义的
// @TableId(type = IdType.AUTO)
// 自己定义 user.setId(555L);
// @TableId(type = IdType.INPUT)
// 雪花算法
// @TableId(type = IdType.ASSIGN_ID)
private Long id;
private String name;
@TableField(value = "pwd",select = false)
private String password;
private Integer age;
private String tel;
@TableField(exist = false)
private Integer online;
// 逻辑删除字段,标记当前记录是否被删除
@TableLogic(value = "0",delval = "1")
private Integer deleted;
}
@Test
void testDelete() {
userDao.deleteById(1);
// List<Long> list = new ArrayList<>();
// list.add(1685940449313812482L);
// list.add(1685941696037003266L);
// list.add(1685942172673523714L);
// userDao.deleteBatchIds(list);
}
运行结果为:
Logging initialized using 'class org.apache.ibatis.logging.stdout.StdOutImpl' adapter.
Registered plugin: 'com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor@4277127c'
Property 'mapperLocations' was not specified.
Creating a new SqlSession
SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@6c075e9d] was not registered for synchronization because synchronization is not active
JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@2c06b113] will not be managed by Spring
==> Preparing: UPDATE tbl_user SET deleted=1 WHERE id=? AND deleted=0
==> Parameters: 1(Integer)
<== Updates: 1
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@6c075e9d]
查询操作
@Test
void testDelete() {
// userDao.deleteById(1);
userDao.selectList(null);
// List<Long> list = new ArrayList<>();
// list.add(1685940449313812482L);
// list.add(1685941696037003266L);
// list.add(1685942172673523714L);
// userDao.deleteBatchIds(list);
}
结果为
Logging initialized using 'class org.apache.ibatis.logging.stdout.StdOutImpl' adapter.
Registered plugin: 'com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor@20f6f88c'
Property 'mapperLocations' was not specified.
Creating a new SqlSession
SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@8fcc534] was not registered for synchronization because synchronization is not active
JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@16681017] will not be managed by Spring
==> Preparing: SELECT id,name,age,tel,deleted FROM tbl_user WHERE deleted=0
==> Parameters:
<== Columns: id, name, age, tel, deleted
<== Row: 2, Jerry, 17, 19533336666, 0
<== Row: 3, Ben, 20, 13788889999, 0
<== Row: 4, Faiz, 18, 19999997787, 0
<== Row: 5, Build, 21, 17569932244, 0
<== Row: 6, Decade, 19, 16666666666, 0
<== Row: 7, Exaid, 18, 19155555555, 0
<== Row: 111, Exaid, 18, 19155555555, 0
<== Row: 555, Exaid, 18, 19155555555, 0
<== Total: 8
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@8fcc534]
注意:
==> Preparing: SELECT id,name,age,tel,deleted FROM tbl_user WHERE deleted=0
配置的方式
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/db1
username: root
password: "031006"
main:
banner-mode: off
# 开启MP的日志(输出到控制台)
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
global-config:
banner: false
db-config:
id-type: assign_id
table-prefix: tbl_
logic-delete-field: deleted
logic-not-delete-value: 0
logic-delete-value: 1
update
乐观锁
- 数据库表中添加锁标记字段
- 实体类中添加对应字段,并设定当前字段为逻辑删除标记字段
@Data
//@TableName("tbl_user")
public class User {
// 使用数据库定义的
// @TableId(type = IdType.AUTO)
// 自己定义 user.setId(555L);
// @TableId(type = IdType.INPUT)
// 雪花算法
// @TableId(type = IdType.ASSIGN_ID)
private Long id;
private String name;
@TableField(value = "pwd",select = false)
private String password;
private Integer age;
private String tel;
@TableField(exist = false)
private Integer online;
// 逻辑删除字段,标记当前记录是否被删除
// @TableLogic(value = "0",delval = "1")
private Integer deleted;
@Version
private Integer version;
}
- 配置乐观锁拦截器实现锁机制对应的动态SQL语句拼装
@Configuration
public class MpConfig {
@Bean
public MybatisPlusInterceptor mpIntercepter() {
// 1.定义Mp拦截器
MybatisPlusInterceptor mpIntercepter = new MybatisPlusInterceptor();
// 2.添加具体的拦截器
mpIntercepter.addInnerInterceptor(new PaginationInnerInterceptor());
// 3.添加乐观锁的拦截器
mpIntercepter.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
return mpIntercepter;
}
}
- 使用乐观锁机制在修改前必须先获取到对应数据的verion方可正常进行
@Test
void testUpdate() {
// User user = new User();
// // 只修改set好的字段
// user.setAge(18);
// user.setName("Faiz");
// user.setId(4L);
// user.setPassword("fa5555");
// user.setVersion(1);
// userDao.updateById(user);
// //1.先通过要修改的数id将当前数据查询出来
// User user = userDao.selectById(4L);
// //2.将要修改的属性逐一设置进去
// user.setName("Faiz555");
// userDao.updateById(user);
User user = userDao.selectById(4L); // version=3,name=Faiz555
User user2 = userDao.selectById(4L); // version=3,name=Faiz555
user2.setName("Faiz666");
userDao.updateById(user2); // version=4,name=Faiz666
user.setName("Faiz777");
userDao.updateById(user);
// 最终:version=4,name=Faiz666
}
运行结果:
Logging initialized using 'class org.apache.ibatis.logging.stdout.StdOutImpl' adapter.
Registered plugin: 'com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor@5b7c8930'
Property 'mapperLocations' was not specified.
Creating a new SqlSession
SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@4a642e4b] was not registered for synchronization because synchronization is not active
JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@32ab408e] will not be managed by Spring
==> Preparing: SELECT id,name,age,tel,deleted,version FROM tbl_user WHERE id=? AND deleted=0
==> Parameters: 4(Long)
<== Columns: id, name, age, tel, deleted, version
<== Row: 4, Faiz555, 18, 19999997787, 0, 3
<== Total: 1
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@4a642e4b]
Creating a new SqlSession
SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@7b297740] was not registered for synchronization because synchronization is not active
JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@32ab408e] will not be managed by Spring
==> Preparing: SELECT id,name,age,tel,deleted,version FROM tbl_user WHERE id=? AND deleted=0
==> Parameters: 4(Long)
<== Columns: id, name, age, tel, deleted, version
<== Row: 4, Faiz555, 18, 19999997787, 0, 3
<== Total: 1
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@7b297740]
Creating a new SqlSession
SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@6e3dd5ce] was not registered for synchronization because synchronization is not active
JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@32ab408e] will not be managed by Spring
==> Preparing: UPDATE tbl_user SET name=?, age=?, tel=?, version=? WHERE id=? AND version=? AND deleted=0
==> Parameters: Faiz666(String), 18(Integer), 19999997787(String), 4(Integer), 4(Long), 3(Integer)
<== Updates: 1
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@6e3dd5ce]
Creating a new SqlSession
SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@7d7ceca8] was not registered for synchronization because synchronization is not active
JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@32ab408e] will not be managed by Spring
==> Preparing: UPDATE tbl_user SET name=?, age=?, tel=?, version=? WHERE id=? AND version=? AND deleted=0
==> Parameters: Faiz777(String), 18(Integer), 19999997787(String), 4(Integer), 4(Long), 3(Integer)
<== Updates: 0
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@7d7ceca8]
Process finished with exit code 0
快速开发
代码生成器
模板:MyBatisPlus提供
数据库相关配置:读取数据库获取信息
开发者自定义配置:手工配置
- 导入依赖
<?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>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.1</version>
</parent>
<groupId>com.itheima</groupId>
<artifactId>mybatisplus_04_generator</artifactId>
<version>0.0.1-SNAPSHOT</version>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<!--spring webmvc-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--mybatisplus-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.1</version>
</dependency>
<!--druid-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.16</version>
</dependency>
<!--mysql-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<!--test-->
<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>
<version>1.18.12</version>
</dependency>
<!--代码生成器-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>3.4.1</version>
</dependency>
<!--velocity模板引擎-->
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity-engine-core</artifactId>
<version>2.3</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
- 创建代码生成器对象,执行生成代码操作
public class CodeGenerator {
public static void main(String[] args) {
//1.获取代码生成器的对象
AutoGenerator autoGenerator = new AutoGenerator();
//设置数据库相关配置
DataSourceConfig dataSource = new DataSourceConfig();
dataSource.setDriverName("com.mysql.cj.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://localhost:3306/db1?serverTimezone=UTC");
dataSource.setUsername("root");
dataSource.setPassword("031006");
autoGenerator.setDataSource(dataSource);
//设置全局配置
GlobalConfig globalConfig = new GlobalConfig();
globalConfig.setOutputDir(System.getProperty("user.dir")+"/src/main/java"); //设置代码生成位置
globalConfig.setOpen(false); //设置生成完毕后是否打开生成代码所在的目录
globalConfig.setAuthor("xlr"); //设置作者
globalConfig.setFileOverride(true); //设置是否覆盖原始生成的文件
globalConfig.setMapperName("%sDao"); //设置数据层接口名,%s为占位符,指代模块名称
globalConfig.setIdType(IdType.ASSIGN_ID); //设置Id生成策略
autoGenerator.setGlobalConfig(globalConfig);
//设置包名相关配置
PackageConfig packageInfo = new PackageConfig();
packageInfo.setParent("com.example"); //设置生成的包名,与代码所在位置不冲突,二者叠加组成完整路径
packageInfo.setEntity("domain"); //设置实体类包名
packageInfo.setMapper("dao"); //设置数据层包名
autoGenerator.setPackageInfo(packageInfo);
//策略设置
StrategyConfig strategyConfig = new StrategyConfig();
strategyConfig.setInclude("tbl_user"); //设置当前参与生成的表名,参数为可变参数
strategyConfig.setTablePrefix("tbl_"); //设置数据库表的前缀名称,模块名 = 数据库表名 - 前缀名 例如: User = tbl_user - tbl_
strategyConfig.setRestControllerStyle(true); //设置是否启用Rest风格
strategyConfig.setVersionFieldName("version"); //设置乐观锁字段名
strategyConfig.setLogicDeleteFieldName("deleted"); //设置逻辑删除字段名
strategyConfig.setEntityLombokModel(true); //设置是否启用lombok
autoGenerator.setStrategy(strategyConfig);
//2.执行生成操作
autoGenerator.execute();
}
}