自己学习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 操作智能分析阻断,也可自定义拦截规则,预防误操作
jdk:1.8
maven:3.8.1
idea:2021.2
mysql:8.0.33
SpringBoot:2.7.17
org.springframework.boot
spring-boot-starter-test
test
org.springframework.boot
spring-boot-starter
org.projectlombok
lombok
true
com.baomidou
mybatis-plus-boot-starter
3.5.1
mysql
mysql-connector-java
8.0.33
spring:
#配置数据源信息
datasource:
url: jdbc:mysql://localhost:3306/mybatis?characterEncoding=UTF-8&serverTimezero=GMT%2B8
driver-class-name: com.mysql.cj.jdbc.Driver
username: root
password: 123456
#加入日志
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
@TableName():与数据库中的表名映射
@Data
@ToString
@AllArgsConstructor
@NoArgsConstructor
@TableName("t_user")
public class User {
private Integer id;
private String username;
private String password;
private Integer age;
private String sex;
private String email;
}
- @Respsitory:解决后面注入时爆红 (也可以不用)
- mapper必须继承BaseMapper
@Repository
public interface UserMapper extends BaseMapper {
}
@Autowired
private UserMapper userMapper;
@Test
public void test() {
//通过条件构造器查询list的集合,没有条件可设置null为条件
List users = userMapper.selectList(null);
users.forEach(user -> System.out.println(user));
}
@DisplayName("测试添加")
@Test
public void test2() {
User user = new User(null, "张沟", "1111", 18, "男", "[email protected]");
int row = userMapper.insert(user);
System.out.println("成果添加" + row + "行记录");
}
@DisplayName("根据Id删除")
@Test
public void test3() {
int row = userMapper.deleteById(1);
System.out.println("成果删除" + row + "行记录");
}
@DisplayName("根据map条件删除")
@Test
public void test4() {
Map map = new HashMap<>();
map.put("username", "大飞");
map.put("age", 23);
int row = userMapper.deleteByMap(map);
System.out.println("成果删除" + row + "行记录");
}
@DisplayName("批量删除")
@Test
public void test5(){
List list= Arrays.asList(18,20);
int row = userMapper.deleteBatchIds(list);
System.out.println("成果删除" + row + "行记录");
}
@DisplayName("修改")
@Test
public void test6(){
User user=new User(2,"小张","666888",18,"男","[email protected]");
int row = userMapper.updateById(user);
System.out.println("成果修改" + row + "行记录");
}
@DisplayName("根据id查询")
@Test
public void test7() {
User user = userMapper.selectById(2);
System.out.println(user);
}
@DisplayName("多个id查询")
@Test
public void test8() {
List list = Arrays.asList(2, 3, 4, 5);
List users = userMapper.selectBatchIds(list);
users.forEach(user -> System.out.println(user));
}
@DisplayName("根据map条件查询")
@Test
public void test9() {
Map map = new HashMap<>();
map.put("sex", "男");
map.put("age", 18);
List users = userMapper.selectByMap(map);
users.forEach(user -> System.out.println(user));
}
@DisplayName("根据条件查询")
@Test
public void test10() {
List users = userMapper.selectList(null);
users.forEach(user -> System.out.println(user));
}
mybatis-plus默认的mapper映射文件路径:/mapper/**/*.xml
@Repository
public interface UserMapper extends BaseMapper {
/**
* 根据id查询用户信息为map集合
* @param id
* @return
*/
Map selectMapById(@Param("id") Integer id);
}
@DisplayName("自定义查询")
@Test
public void test11(){
Map map = userMapper.selectMapById(2);
System.out.println(map);
}
让接口继承Mybatis-plus的通用IService<实体类型>
public interface UserService extends IService {
}
- service实现自己的接口
- 继承mybatis-plus的实现类ServiceImpl<自己的mapper,要操作的实体类>
@Service
public class UserServiceImpl extends ServiceImpl implements UserService {
}
@SpringBootTest
public class TestService {
@Autowired
protected UserService userService;
@DisplayName("查询总记录数")
@Test
public void test1(){
long count = userService.count();
System.out.println("总记录数:"+count);
}
}
- 说明:在UserMapper里面没有批量添加的功能。
@DisplayName("批量添加")
@Test
public void test2() {
List list = new ArrayList<>();
for (int i = 7; i <= 12; i++) {
User user = new User(i, "小张" + i, "666" + i, 11 + i, "男", "666" + i + "@qq.com");
list.add(user);
}
boolean b = userService.saveBatch(list);
System.out.println("是否添加成功:"+b);
}
}
- @TableName:将指定的数据库表和实体类名相映射
@TableName("t_user")
public class User {
private Integer id;
private String username;
private String password;
private Integer age;
private String sex;
private String email;
}
注意:如果数据库表名的前缀是一致的,则可以使用全局配置
mybatis-plus:
#设置表名前缀
global-config:
db-config:
table-prefix: t_
- @TableId:将属性所对应的字段标识为主键(默认把id标识为主键,当不为 id 时,用此注解)
属性 类型 默认值 描述 value String "" 主键字段名 type Enum IdType.NONE(雪花算法),与数据库是否设置自增无关
IdType.AUTO (自动递增),数据库必须设置id自增,否则无效
指定主键类型
@TableName("t_user")
public class User {
@TableId(value = "id",type = IdType.AUTO)
private Integer id;
private String username;
private String password;
private Integer age;
private String sex;
private String email;
}
注意:也可以在全局配置里统一 主键生成策略
mybatis-plus:
configuration:
id-type: auto
- @TableFild:指定属性对应的字段名
@TableName("t_user")
public class User {
@TableId(value = "id",type = IdType.AUTO)
private Integer id;
@TableField("username")
private String name;
private String password;
private Integer age;
private String sex;
private String email;
}
- @TableLogic:逻辑删除(自动转化为修改)
属性 类型 描述 value String 逻辑未删除值 delval String 逻辑删除值
@TableName("t_user")
public class User {
@TableId(value = "id",type = IdType.AUTO)
private Integer id;
@TableField("username")
private String name;
private String password;
private Integer age;
private String sex;
private String email;
@TableLogic
private Integer isDelete;
- Wrapper: 条件构造抽象类,最顶端父类
- AbstractWrapper:用于查询条件封装,生成 sql 的 where 条件
- QueryWrapper:查询条件封装
- UpdateWrapper : Update条件封装
- AbstractLambdaWrapper: 使用Lambda 语法
- LambdaQueryWrapper:用于Lambda语法使用的查询Wrapper
- LambdaUpdateWrapper: Lambda 更新封装Wrapper
注意:查询的不是实体类的属性,而是数据空表中的字段
@DisplayName("条件查询")
@Test
public void test1() {
QueryWrapper queryWrapper = new QueryWrapper();
//查询包含 张 ,age在19和22之间,email不为空
queryWrapper.like("username", "张").between("age", 19, 22).isNotNull("email");
List list = userMapper.selectList(queryWrapper);
list.forEach(user -> System.out.println(user));
}
查询结果:
因为之前添加了@TableLogic,所以查询的都是未删除的:WHERE is_delete=0
==> Preparing: SELECT id,username AS name,password,age,sex,email,is_delete FROM t_user WHERE is_delete=0 AND (username LIKE ? AND age BETWEEN ? AND ? AND email IS NOT NULL)
==> Parameters: %张%(String), 19(Integer), 22(Integer)
<== Columns: id, name, password, age, sex, email, is_delete
<== Row: 10, 小张10, 66610, 21, 男, [email protected], 0
<== Row: 11, 小张11, 66611, 22, 男, [email protected], 0
<== Total: 2
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@76889e60]
User(id=10, name=小张10, password=66610, age=21, sex=男, [email protected], isDelete=0)
User(id=11, name=小张11, password=66611, age=22, sex=男, [email protected], isDelete=0)
- orderByDesc:按照降序排
- orderByAsc:按照升序排
@DisplayName("排序条件")
@Test
public void test2(){
QueryWrapper queryWrapper=new QueryWrapper<>();
//先按照年龄降序排,若年龄相等,按照id升序排,年龄在19-22
queryWrapper.orderByDesc("age").orderByAsc("id").between("age",19,22);
List list = userMapper.selectList(queryWrapper);
list.forEach(user -> System.out.println(user));
}
结果:
==> Preparing: SELECT id,username AS name,password,age,sex,email,is_delete FROM t_user WHERE is_delete=0 AND (age BETWEEN ? AND ?) ORDER BY age DESC,id ASC
==> Parameters: 19(Integer), 22(Integer)
<== Columns: id, name, password, age, sex, email, is_delete
<== Row: 11, 小张11, 66611, 22, 男, [email protected], 0
<== Row: 10, 小张10, 66610, 21, 男, [email protected], 0
<== Total: 2
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@55e2fe3c]
User(id=11, name=小张11, password=66611, age=22, sex=男, [email protected], isDelete=0)
User(id=10, name=小张10, password=66610, age=21, sex=男, [email protected], isDelete=0)
@DisplayName("删除条件")
@Test
public void test3(){
QueryWrapper queryWrapper=new QueryWrapper<>();
queryWrapper.isNull("email");
int row = userMapper.delete(queryWrapper);
System.out.println("成功删除"+row+"条");
}
因为前面添加了@TableLogic逻辑删除,所以应当是修改语句!!!!!
==> Preparing: UPDATE t_user SET is_delete=1 WHERE is_delete=0 AND (email IS NULL)
==> Parameters:
<== Updates: 1
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@6f139fc9]
成功删除1条
AND连接是默认的,但是OR需要 添加.or()
@DisplayName("修改条件")
@Test
public void test4() {
QueryWrapper queryWrapper = new QueryWrapper<>();
//将(年龄大于20并且用户名中包含张)或(邮箱为null的用户信息修改)
queryWrapper.gt("age", 20).like("username", "张").or().isNull("email");
User user = new User();
user.setName("小小张");
user.setEmail("[email protected]");
//第一个参数是修改的内容,第二个参数是查询条件
int row = userMapper.update(user, queryWrapper);
System.out.println("成功修改" + row + "行");
}
结果:
JDBC Connection [HikariProxyConnection@976042249 wrapping com.mysql.cj.jdbc.ConnectionImpl@4fb392c4] will not be managed by Spring
==> Preparing: UPDATE t_user SET username=?, email=? WHERE is_delete=0 AND (age > ? AND username LIKE ? OR email IS NULL)
==> Parameters: 小小张(String), [email protected](String), 20(Integer), %张%(String)
<== Updates: 5
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@64f1fd08]
成功修改5行
因为email为空的,之前被逻辑删除了,所以没有修改
lambda中的条件优先执行
@DisplayName("优先级")
@Test
public void test5() {
QueryWrapper queryWrapper = new QueryWrapper<>();
//将用户名中包含 9 并且(年龄大于18或邮箱为null)的用户修改
queryWrapper.like("username", "9")
.and(i -> i.gt("age", 18).or().isNull("email"));
User user=new User();
user.setName("小小陈");
int row = userMapper.update(user, queryWrapper);
System.out.println("成功修改"+row+"行");
}
结果:
注意看下面的修改语句!!!,你品,你细细品~
==> Preparing: UPDATE t_user SET username=? WHERE is_delete=0 AND (username LIKE ? AND (age > ? OR email IS NULL))
==> Parameters: 小小陈(String), %9%(String), 18(Integer)
<== Updates: 1
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@64469d8]
成功修改1行
@DisplayName("指定字段")
@Test
public void test6(){
QueryWrapper queryWrapper=new QueryWrapper<>();
//查用户名,密码
queryWrapper.select("username","password");
List
结果:
注意看下面的查询语句!!!,你品,你细细品~
==> Preparing: SELECT username,password FROM t_user WHERE is_delete=0
==> Parameters:
<== Columns: username, password
<== Row: 小张, 666888
<== Row: 张沟, 1111
<== Row: 张大沟, 2222
<== Row: jack, 888
<== Total: 4
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@3dd818e8]
{password=666888, username=小张}
{password=1111, username=张沟}
{password=2222, username=张大沟}
{password=888, username=jack}
@DisplayName("子查询")
@Test
public void test7(){
QueryWrapper queryWrapper=new QueryWrapper<>();
//年龄小于20的
queryWrapper.inSql("age","select age from t_user where age<20");
List list = userMapper.selectList(queryWrapper);
list.forEach(user -> System.out.println(user));
}
结果:
==> Preparing: SELECT id,username AS name,password,age,sex,email,is_delete FROM t_user WHERE is_delete=0 AND (age IN (select age from t_user where age<20))
==> Parameters:
<== Columns: id, name, password, age, sex, email, is_delete
<== Row: 2, 小张, 666888, 18, 男, [email protected], 0
<== Row: 3, 张沟, 1111, 18, 女, [email protected], 0
<== Row: 4, 张大沟, 2222, 8, 男, [email protected], 0
<== Row: 5, jack, 888, 18, 女, [email protected], 0
<== Total: 4
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@64f1fd08]
User(id=2, name=小张, password=666888, age=18, sex=男, [email protected], isDelete=0)
User(id=3, name=张沟, password=1111, age=18, sex=女, [email protected], isDelete=0)
User(id=4, name=张大沟, password=2222, age=8, sex=男, [email protected], isDelete=0)
User(id=5, name=jack, password=888, age=18, sex=女, [email protected], isDelete=0)
根据用户选择,进行加入查询条件
@Test
public void test9(){
String username="";
Integer ageBegin=20;
Integer ageEnd=30;
QueryWrapper queryWrapper=new QueryWrapper<>();
if (StringUtils.isNotBlank(username)){//isNotBlank判断某个字符串是否不为空字符串,不为null,不为空白符
queryWrapper.like("username",username);
}
if (ageBegin!=null){
queryWrapper.gt("age",ageBegin);
}
if (ageEnd!=null){
queryWrapper.lt("age",ageEnd);
}
List list = userMapper.selectList(queryWrapper);
list.forEach(user -> System.out.println(user));
}
结果:
发现结果是根据age进行查询的,因为username=" ",所以不进行拼接
==> Preparing: SELECT id,username AS name,password,age,sex,email,is_delete FROM t_user WHERE is_delete=0 AND (age > ? AND age < ?)
==> Parameters: 20(Integer), 30(Integer)
<== Columns: id, name, password, age, sex, email, is_delete
<== Row: 6, 小王, 123456, 23, 男, [email protected], 0
<== Row: 10, 小小张, 66610, 21, 男, [email protected], 0
<== Row: 11, 小小张, 66611, 22, 男, [email protected], 0
<== Row: 12, 小小张, 66612, 23, 男, [email protected], 0
<== Row: 22, 小小张, 66612, 23, 男, [email protected], 0
<== Row: 23, 小小张, 66613, 24, 男, [email protected], 0
<== Total: 6
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@6c15e8c7]
User(id=6, name=小王, password=123456, age=23, sex=男, [email protected], isDelete=0)
User(id=10, name=小小张, password=66610, age=21, sex=男, [email protected], isDelete=0)
User(id=11, name=小小张, password=66611, age=22, sex=男, [email protected], isDelete=0)
User(id=12, name=小小张, password=66612, age=23, sex=男, [email protected], isDelete=0)
User(id=22, name=小小张, password=66612, age=23, sex=男, [email protected], isDelete=0)
User(id=23, name=小小张, password=66613, age=24, sex=男, [email protected], isDelete=0)
condition:就是里面的条件---》like(条件,字段,字段值)
@DisplayName("condition查询")
@Test
public void test10() {
String username = "";
Integer ageBegin = 20;
Integer ageEnd = 30;
QueryWrapper queryWrapper = new QueryWrapper<>();
queryWrapper.like(StringUtils.isNotBlank(username), "username", username)
.gt(ageBegin != null, "age", 20)
.lt(ageEnd != null, "age", 30);
List list = userMapper.selectList(queryWrapper);
list.forEach(user -> System.out.println(user));
结果:
==> Preparing: SELECT id,username AS name,password,age,sex,email,is_delete FROM t_user WHERE is_delete=0 AND (age > ? AND age < ?)
==> Parameters: 20(Integer), 30(Integer)
<== Columns: id, name, password, age, sex, email, is_delete
<== Row: 6, 小王, 123456, 23, 男, [email protected], 0
<== Row: 10, 小小张, 66610, 21, 男, [email protected], 0
<== Row: 11, 小小张, 66611, 22, 男, [email protected], 0
<== Row: 12, 小小张, 66612, 23, 男, [email protected], 0
<== Row: 22, 小小张, 66612, 23, 男, [email protected], 0
<== Row: 23, 小小张, 66613, 24, 男, [email protected], 0
<== Total: 6
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@6b3f6585]
User(id=6, name=小王, password=123456, age=23, sex=男, [email protected], isDelete=0)
User(id=10, name=小小张, password=66610, age=21, sex=男, [email protected], isDelete=0)
User(id=11, name=小小张, password=66611, age=22, sex=男, [email protected], isDelete=0)
User(id=12, name=小小张, password=66612, age=23, sex=男, [email protected], isDelete=0)
User(id=22, name=小小张, password=66612, age=23, sex=男, [email protected], isDelete=0)
User(id=23, name=小小张, password=66613, age=24, sex=男, [email protected], isDelete=0)
注意:条件中的字段,不是实体类型的属性,而是数据库表中的字段!!!!!
不用在创建修改的对象,直接通过.set()进行设置即可
@DisplayName("UpdateWrapper修改")
@Test
public void test8(){
UpdateWrapper updateWrapper=new UpdateWrapper<>();
//将用户名中包含 陈 并且(年龄大于18或邮箱为null)的用户修改
updateWrapper.like("username","陈").and(i->i.gt("age",18).or().isNull("email"));
//修改的字段
updateWrapper.set("username","大大张").set("age",20);
int row = userMapper.update(null, updateWrapper);
System.out.println("成功修改"+row+"行");
}
结果:
==> Preparing: UPDATE t_user SET username=?,age=? WHERE is_delete=0 AND (username LIKE ? AND (age > ? OR email IS NULL))
==> Parameters: 大大张(String), 20(Integer), %陈%(String), 18(Integer)
<== Updates: 1
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@2e807c54]
成功修改1行
为了避免字段名写错,可以使用lambda表达式: User::getName
@Test
public void test11(){
LambdaQueryWrapper lambdaQueryWrapper=new LambdaQueryWrapper();
String username = "张";
Integer ageBegin = 20;
Integer ageEnd = 30;
lambdaQueryWrapper.like(StringUtils.isNotBlank(username),User::getName,username)
.ge(ageBegin!=null,User::getAge,ageBegin)
.le(ageEnd!=null,User::getAge,ageEnd);
List list = userMapper.selectList(lambdaQueryWrapper);
list.forEach(user -> System.out.println(user));
}
结果:
==> Preparing: SELECT id,username AS name,password,age,sex,email,is_delete FROM t_user WHERE is_delete=0 AND (username LIKE ? AND age >= ? AND age <= ?)
==> Parameters: %张%(String), 20(Integer), 30(Integer)
<== Columns: id, name, password, age, sex, email, is_delete
<== Row: 9, 大大张, 6669, 20, 男, [email protected], 0
<== Row: 10, 小小张, 66610, 21, 男, [email protected], 0
<== Total: 2
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@39c385d6]
User(id=9, name=大大张, password=6669, age=20, sex=男, [email protected], isDelete=0)
User(id=10, name=小小张, password=66610, age=21, sex=男, [email protected], isDelete=0)
同样使用lambda表达式,防止字段名写错;User.getName
@Test
public void test12() {
LambdaUpdateWrapper updateWrapper = new LambdaUpdateWrapper<>();
//将用户名中包含 陈 并且(年龄大于18或邮箱为null)的用户修改
updateWrapper.like(User::getName, "张").and(i -> i.gt(User::getAge, 23).or().isNull(User::getEmail));
updateWrapper.set(User::getName,"大大大张").set(User::getAge,88);
int row = userMapper.update(null, updateWrapper);
System.out.println("成功修改" + row + "行");
}
结果:
==> Preparing: UPDATE t_user SET username=?,age=? WHERE is_delete=0 AND (username LIKE ? AND (age > ? OR email IS NULL))
==> Parameters: 大大大张(String), 88(Integer), %张%(String), 23(Integer)
<== Updates: 1
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@6438a7fe]
成功修改1行
Mybatis-plus自带分页插件,但需要配置
@Configuration
public class MyConfig {
/**
* 分页插件
*/
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor(){
MybatisPlusInterceptor interceptor=new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
return interceptor;
}
}
@Test
public void test1() {
Page page = new Page<>(1,3);
userMapper.selectPage(page,null);
System.out.println(page.getCurrent());
}
描述:当小李和小王同时修改商品时,他俩都是对原商品操作,在没有锁的情况下,后来的会覆盖之前的,这是老板再来查询,就是小王在原商品上的修改,而并非在小李修改后,对小李的结果进行修改。
@Autowired
private ProductMapper productMapper;
@DisplayName("商品操作")
@Test
public void test(){
//小李查询商品
Product product1 = productMapper.selectById(1);
System.out.println("小李查询的价格"+product1.getPrice());
//小王查询商品
Product product2 = productMapper.selectById(1);
System.out.println("小王查询的价格"+product2.getPrice());
//小李+50
product1.setPrice(product1.getPrice()+50);
productMapper.updateById(product1);
//小王-30
product2.setPrice(product2.getPrice()-30);
productMapper.updateById(product2);
//老板
Product product3 = productMapper.selectById(1);
System.out.println("老板查询的价格:"+product3.getPrice());
}
运行结果可知:
- 小李查询的价格100
- 小王查询的价格100
- 老板查询的价格70
老板说:求求大哥,给孩子加个锁吧!!!
@Configuration
public class MyConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor(){
MybatisPlusInterceptor interceptor=new MybatisPlusInterceptor();
//分页插件
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
//乐观锁插件
interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
return interceptor;
}
}
- @Version:标识乐观锁版本号字段
@TableName("t_product")
public class Product {
@TableId(value = "id",type = IdType.AUTO)
private Integer id;
@TableField("t_name")
private String name;
private Integer price;
@Version
private Integer version;
}
若小王查询后返回0,继续让他重新查询;这是他查询的就是小李更改后的
@Autowired
private ProductMapper productMapper;
@DisplayName("商品操作")
@Test
public void test(){
//小李查询商品
Product product1 = productMapper.selectById(1);
System.out.println("小李查询的价格"+product1.getPrice());
//小王查询商品
Product product2 = productMapper.selectById(1);
System.out.println("小王查询的价格"+product2.getPrice());
//小李+50
product1.setPrice(product1.getPrice()+50);
productMapper.updateById(product1);
//小王-30
product2.setPrice(product2.getPrice()-30);
int row = productMapper.updateById(product2);
if (row==0){//操作失败
Product productNew = productMapper.selectById(1);
productNew.setPrice(product2.getPrice()-30);
productMapper.updateById(productNew);
}
//老板
Product product3 = productMapper.selectById(1);
System.out.println("老板查询的价格:"+product3.getPrice());
}
这是查询结果:
- 小李查询的价格100
- 小王查询的价格100
- 小王再次查询的价格150
- 老板查询的价格:120
这时,老板露出了久违的笑容~
如果数据库中的字段值是固定的,如性别,就可以使用枚举喽~
- @EnumValue:将注解所标识的属性值存储到数据库中
@AllArgsConstructor
@Getter
public enum SexEnums {
MALE(1,"男"),
FEMALE(2,"女");
@EnumValue//将注解所标识的属性值存储到数据库中
private Integer sex;
private String sexName;
}
当然实体类时,sex的类型就是SexEnums
private SexEnums sex;
mybatis-plus:
#通用枚举
type-enums-package: com.xz.enums
这时的性别,就可以使用SexEnums.MALE/FMALE,枚举类型了
@DisplayName("测试枚举")
@Test
public void test(){
User user=new User(null,"荒天帝","888",18, SexEnums.MALE,"[email protected]");
int row = userMapper.insert(user);
System.out.println("成功添加:"+row+"行记录");
}
一不小心成功了!!!
==> Preparing: INSERT INTO t_user ( username, password, age, sex, email ) VALUES ( ?, ?, ?, ?, ? )
==> Parameters: 荒天帝(String), 888(String), 18(Integer), 1(Integer), [email protected](String)
<== Updates: 1
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@1866da85]
成功添加:1行记录
com.baomidou
mybatis-plus-generator
3.5.1
org.freemarker
freemarker
2.3.32
官方的更权威
FastAutoGenerator.create("jdbc:mysql://localhost:3306/mybatis?characterEncoding=UTF-8&serverTimezero=GMT%2B8", "root", "123456")
//全局配置
.globalConfig(builder -> {
builder.author("小张") // 设置作者
.enableSwagger() // 开启 swagger 模式
.fileOverride() // 覆盖已生成文件
.outputDir("F://Mybatis-PLUS"); // 指定输出目录
})
//设置包
.packageConfig(builder -> {
builder.parent("com.xz") // 设置父包名
.moduleName("mybatis-plus") // 设置父包模块名
.pathInfo(Collections.singletonMap(OutputFile.mapperXml, "F://Mybatis-PLUS")); // 设置mapperXml生成路径
})
//设置策略
.strategyConfig(builder -> {
builder.addInclude("t_user") // 设置需要生成的表名
.addTablePrefix("t_", "c_"); // 设置过滤表前缀
})
//生成的模板
.templateEngine(new FreemarkerTemplateEngine()) // 使用Freemarker引擎模板,默认的是Velocity引擎模板
//执行
.execute();
}
- 若下面报错 :说明url配置有问题,查看你的url中是否存在空格!!!
Exception in thread "main" java.lang.RuntimeException: 无法创建文件,请检查配置信息!
at com.baomidou.mybatisplus.generator.engine.AbstractTemplateEngine.batchOutput(AbstractTemplateEngine.java:244)
at com.baomidou.mybatisplus.generator.AutoGenerator.execute(AutoGenerator.java:179)
at com.baomidou.mybatisplus.generator.FastAutoGenerator.execute(FastAutoGenerator.java:213)
at com.xz.TestAuto.main(TestAuto.java:35)
Caused by: java.lang.RuntimeException: java.sql.SQLException: No suitable driver found for jdbc:mysql://localhost:3306/mybatis?characterEncoding=UTF-8&serverTimezero=GMT%2B8
at com.baomidou.mybatisplus.generator.config.DataSourceConfig.getConn(DataSourceConfig.java:206)
at com.baomidou.mybatisplus.generator.config.querys.DecoratorDbQuery.(DecoratorDbQuery.java:58)
at com.baomidou.mybatisplus.generator.IDatabaseQuery$DefaultDatabaseQuery.(IDatabaseQuery.java:97)
at com.baomidou.mybatisplus.generator.config.builder.ConfigBuilder.getTableInfoList(ConfigBuilder.java:139)
at com.baomidou.mybatisplus.generator.engine.AbstractTemplateEngine.batchOutput(AbstractTemplateEngine.java:226)
... 3 more
Caused by: java.sql.SQLException: No suitable driver found for jdbc:mysql://localhost:3306/mybatis?characterEncoding=UTF-8&serverTimezero=GMT%2B8
at java.sql.DriverManager.getConnection(DriverManager.java:689)
at java.sql.DriverManager.getConnection(DriverManager.java:247)
at com.baomidou.mybatisplus.generator.config.DataSourceConfig.getConn(DataSourceConfig.java:196)
... 7 more
MyBatis-Plus为我们提供了强大的mapper和service模板,能够大大的提高开发效率但是在真正开发过程中, MyBatis-Plus并不能为我们解决所有问题,例如一些复杂的SQL,多表联查,我们就需要自己去编写代码和SQL语句,我们该如何快速的解决这个问题呢,这个时候可以使用MyBatisX插件MyBatisX—款基于 IDEA的快速开发插件,为效率而生。
重启生效!!!
你就会惊奇的发现:
- mapper接口前有个蓝鸟
- mapper接口映射文件有个红鸟
点击红鸟,会定位到所对应的蓝鸟,反之亦然!!!!