MyBatisPlus学习记录
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.DruidDataSourcedriver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/db1username: rootpassword: "031006"
- 制作实体类与表结构(类名与表名对应,属性名与字段名对应)
package com.example.domain;public class User {private Long id;private String name;private String password;private Integer age;private String tel;@Overridepublic 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 {@Autowiredprivate UserDao userDao;@Testvoid 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 {@Autowiredprivate UserDao userDao;@Testvoid testInsert() {User user = new User();user.setAge(18);user.setName("Faiz");user.setTel("18155555555");user.setPassword("faiz555");userDao.insert(user);}@Testvoid testDelete() {userDao.deleteById(1685579916861468673L);}@Testvoid testUpdate() {User user = new User();// 只修改set好的字段user.setAge(18);user.setName("Faiz");user.setId(4L);userDao.updateById(user);}@Testvoid testGetById() {User user = userDao.selectById(2L);System.out.println(user);}@Testvoid 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 {@Beanpublic MybatisPlusInterceptor mpIntercepter() {// 1.定义Mp拦截器MybatisPlusInterceptor mpIntercepter = new MybatisPlusInterceptor();// 2.添加具体的拦截器mpIntercepter.addInnerInterceptor(new PaginationInnerInterceptor());return mpIntercepter;}
}
- 执行分页查询
@Testvoid 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.DruidDataSourcedriver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/db1username: rootpassword: "031006"# 开启MP的日志(输出到控制台)
mybatis-plus:configuration:log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
DQL编程控制
条件查询方式
MyBatisPlus将书写复杂的SQL查询条件进行了封装,使用编程的形式完成查询条件的组合
@Testvoid testGetAll() {// 方式一,按条件查询QueryWrapper wrapper = new QueryWrapper();// age < 18wrapper.lt("age",18);List<User> users1 = userDao.selectList(wrapper);System.out.println(users1);// 方式二,lambda格式按条件查询QueryWrapper<User> wrapper2 = new QueryWrapper<>();// age < 18wrapper2.lambda().lt(User::getAge,18);List<User> users2 = userDao.selectList(wrapper);System.out.println(users2);// 方式三,lambda格式按条件查询LambdaQueryWrapper<User> lambdaQueryWrapper1 = new LambdaQueryWrapper<>();// age < 18lambdaQueryWrapper1.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 > 20lambdaQueryWrapper.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 < 20lambdaQueryWrapper.lt(null != userQuery.getAge(),User::getAge,userQuery.getAge());// age > 17lambdaQueryWrapper.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 <20lqw.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.DruidDataSourcedriver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/db1username: rootpassword: "031006"main:banner-mode: off# 开启MP的日志(输出到控制台)
mybatis-plus:configuration:log-impl: org.apache.ibatis.logging.stdout.StdOutImplglobal-config:banner: falsedb-config:id-type: assign_idtable-prefix: tbl_
Delete
多记录操作
@Testvoid 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;
}
@Testvoid 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]
查询操作
@Testvoid 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.DruidDataSourcedriver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/db1username: rootpassword: "031006"main:banner-mode: off# 开启MP的日志(输出到控制台)
mybatis-plus:configuration:log-impl: org.apache.ibatis.logging.stdout.StdOutImplglobal-config:banner: falsedb-config:id-type: assign_idtable-prefix: tbl_logic-delete-field: deletedlogic-not-delete-value: 0logic-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;@Versionprivate Integer version;
}
- 配置乐观锁拦截器实现锁机制对应的动态SQL语句拼装
@Configuration
public class MpConfig {@Beanpublic MybatisPlusInterceptor mpIntercepter() {// 1.定义Mp拦截器MybatisPlusInterceptor mpIntercepter = new MybatisPlusInterceptor();// 2.添加具体的拦截器mpIntercepter.addInnerInterceptor(new PaginationInnerInterceptor());// 3.添加乐观锁的拦截器mpIntercepter.addInnerInterceptor(new OptimisticLockerInnerInterceptor());return mpIntercepter;}
}
- 使用乐观锁机制在修改前必须先获取到对应数据的verion方可正常进行
@Testvoid 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=Faiz555User user2 = userDao.selectById(4L); // version=3,name=Faiz555user2.setName("Faiz666");userDao.updateById(user2); // version=4,name=Faiz666user.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); //设置是否启用lombokautoGenerator.setStrategy(strategyConfig);//2.执行生成操作autoGenerator.execute();}
}
相关文章:

MyBatisPlus学习记录
MyBatisPlus(简称MP)是基于MyBatis框架基础上开发的增强型工具,旨在简化开发、提高效率 MyBatisPlus简介 入门案例 创建新模块,选择Spring初始化,并配置模块相关基础信息选择当前模块需要使用的技术集(仅选择MySQL …...

如何开启一个java微服务工程
安装idea IDEA常用配置和插件(包括导入导出) https://blog.csdn.net/qq_38586496/article/details/109382560安装配置maven 导入source创建项目 修改项目编码utf-8 File->Settings->Editor->File Encodings 修改项目的jdk maven import引入…...

libhv之hio_t分析
上一篇文章解析了fd是怎么与io模型关联。其中最主要的角色扮演者:hio_t 1. hio_t与hloop的关系 fd的值即hio_t所在loop ios变量中所在的index值。 hio_t ios[fd] struct hloop_s { ...// ios: with fd as array.index//io_array保存了和hloop关联的所有hio_t&…...

C语言的转义字符
转义字符也叫转移序列,包含如下: 转移序列 \0oo 和 \xhh 是 ASCII 码的特殊表示。 八进制数示例: 代码: #include<stdio.h> int main(void) {char beep\007;printf("%c\n",beep);return 0; }结果: …...

【腾讯云 Cloud Studio 实战训练营】CloudStudio体验真正的现代化开发方式,双手插兜不知道什么叫对手!
CloudStudio体验真正的现代化开发方式,双手插兜不知道什么叫对手! 文章目录 CloudStudio体验真正的现代化开发方式,双手插兜不知道什么叫对手!前言出现的背景一、CloudStudio 是什么?二、CloudStudio 的特点三、CloudS…...

Pandas时序数据分析实践—时序数据集
1. 跑步运动为例,对运动进行时序分析 时序数据是指时间序列数据,是按照时间顺序排列的数据集合,每个数据点都与一个特定的时间戳相关联。在跑步活动中,我们可以将每次跑步的数据记录作为一个时序数据样本,每个样本都包…...

use strict 是什么意思?使用它区别是什么?
use strict 是什么意思?使用它区别是什么? use strict 代表开启严格模式,这种模式下使得 JavaScript 在更严格的条件下运行,实行更严格解析和错误处理。 开启“严格模式”的优点: 消除 JavaScript 语法的一些不合理…...

常见OOM异常分析排查
常见OOM异常分析排查 Java内存溢出Java堆溢出原因解决思路总结 Java内存溢出 java堆用于存储对象实例,如果不断地创建对象,并且保证GC Root到对象之间有可达路径,垃圾回收机制就不会清理这些对象,对象数量达到最大堆的容量限制后就会产生内存溢出异常. Java堆溢出原因 无法在…...

kubernetes网络之网络策略-Network Policies
Kubernetes 中,Network Policy(网络策略)定义了一组 Pod 是否允许相互通信,或者与网络中的其他端点 endpoint 通信。 NetworkPolicy 对象使用标签选择Pod,并定义规则指定选中的Pod可以执行什么样的网络通信࿰…...

交换机VLAN技术和实验(eNSP)
目录 一,交换机的演变 1.1,最小网络单元 1.2,中继器(物理层) 1.3,集线器(物理层) 1.4,网桥(数据链路层) 二,交换机的工作行为 2.…...

8.Winform界面打包成DLL提供给其他的项目使用
背景 希望集成一个Winform的框架,提供权限菜单,根据权限出现各个Winform子系统的菜单界面。不希望把所有的界面都放放在同一个解决方案下面。用各个子系统建立不同的解决方案,建立代码仓库,进行管理。 实现方式 将Winform的UI界…...

海量数据存储组件Hbase
hdfs hbase NoSQL数据库 支持海量数据的增删改查 基于Rowkey查询效率特别高 kudu 介于hdfs和hbase之间 hbase依赖hadoopzookeeper,同时整合框架phoenix(擅长读写),hive(分析数据) k,v 储存结构 稀疏的(为空的不存…...

(一)基于Spring Reactor框架响应式异步编程|道法术器
在执行程序时: 通常为了提供性能,处理器和编译器常常会对指令进行重排序。 从排序分为编译器重排序和处理器重排序两种 * (1)编译器重排序: 编译器保证不改变单线程执行结构的前提下,可以调整多线程语句执行顺序; * (2)处理器重排序: 如果不存在数据依赖…...

Vue3 让localstorage变响应式
Hook使用方式: import {useLocalStore} from "../js/hooks"const aauseLocalStore("aa",1) 需求一: 通过window.localStorage.setItem可以更改本地存储是,还可以更新aa的值 window.localStorage.setItem("aa&quo…...

【深度学习】InST,Inversion-Based Style Transfer with Diffusion Models,论文,风格迁移,实战
代码:https://github.com/zyxElsa/InST 论文:https://arxiv.org/abs/2211.13203 文章目录 AbstractIntroductionRelated WorkImage style transferText-to-image synthesisInversion of diffusion models MethodOverview ExperimentsComparison with Sty…...

【CSS】3D卡片效果
效果 index.html <!DOCTYPE html> <html><head><title> Document </title><link type"text/css" rel"styleSheet" href"index.css" /></head><body><div class"card"><img…...

OrderApplication
目录 1 OrderApplication 2 /// 查询订单 2.1.1 //补充商品单位 2.1.2 //补充门店名称 2.1.3 //补充门店名称 2.1.4 //订单售后 2.1.5 //订单项售后 OrderApplication...

如何在保健品行业运用IPD?
保健品是指能调节机体功能,不以治疗为目的,并且对人体不产生任何急性、亚急性或者慢性危害的产品。保健品是食品的一个种类,具有一般食品的共性,其含有一定量的功效成分,能调节人体的机能,具有特定的功效&a…...

Flink系列之:动态发现新增分区
Flink系列之:动态发现新增分区 一、动态发现新增分区二、Flink SQL动态发现新增分区三、Flink API动态发现新增分区 为了在不重新启动 Flink 作业的情况下处理主题扩展或主题创建等场景,可以将 Kafka 源配置为在提供的主题分区订阅模式下定期发现新分区。…...

eclipse版本与jdk版本对应关系
官网:Eclipse/Installation - Eclipsepedia eclipse历史版本(2007-):Older Versions Of Eclipse - Eclipsepedia Eclipse Packaging Project (EPP) Releases | Eclipse Packages...

File类的学习
java.io.File类 文件和目录路径的抽象表达形式是一个与操作系统无关的类,任何一个操作系统都可以使用这个类中的方法 File.pathSeparator 文件路径分隔符,windows是分号,linux是: File.separator 文件名分隔符,window…...

Linux 操作系统 Red Hat Enterprise Linux 安装教程
文章目录 笔者的操作环境: 制作环境: Win32 Disk Imager 1.0.0 Windows 10 教育版 ISO: Red Hat Enterprise Linux 9.2 x86_64 Red Hat Enterprise Linux(RHEL)是一种 Linux 操作系统。安装此操作系统的难题在于&a…...

关于拓扑排序
又重新学了一下拓扑排序,这次发现就十分简单了,拓扑排序的步骤 1.他必须是一个有向无环图,起点我们就是入度为0的点 2.我们首先要输出的就是入度为0的点,然后依次删除这些点连向的点,使这些点的入度-1,如果…...

【C++】开源:Boost库常用组件配置使用
😏★,:.☆( ̄▽ ̄)/$:.★ 😏 这篇文章主要介绍Boost库常用组件配置使用。 无专精则不能成,无涉猎则不能通。——梁启超 欢迎来到我的博客,一起学习,共同进步。 喜欢的朋友可以关注一下,…...

用python通过http实现文件传输,分为发送端和接收端
要使用Python通过HTTP实现文件传输,可以使用Python的 requests 库来发送和接收HTTP请求。以下是一个示例代码,其中包括发送端和接收端的实现。 发送端: import requestsdef send_file(file_path, url):with open(file_path, rb) as file:re…...

数据结构--图的遍历 DFS
数据结构–图的遍历 DFS 树的深度优先遍历 //树的先根遍历 void PreOrder(TreeNode *R) {if(R ! NULL){visit(R); //访问根节点while(R还有下一个子树T)PreOrder(T);//先根遍历下一棵子树} }图的深度优先遍历 bool visited [MAX_VERTEX_NUM]; //访问标记数组 void DFS(Grap…...

SpringBoot集成MyBatisPlus+MySQL(超详细)
前言 查看此文章前强烈建议先看这篇文章:Java江湖路 | 专栏目录 该文章纪录的是SpringBoot快速集成MyBatis Plus,每一步都有记录,争取每一位看该文章的小伙伴都能操作成功。达到自己想要的效果~ 文章目录 前言1、什么是MyBatisPlus2、Spring…...

一边是计算机就业哀鸿遍野,一边是高考生疯狂涌向计算机专业
在张雪峰推荐的几大专业里,计算机专业是其中之一。近几年,计算机专业报考热度不减,但就业前景却令人堪忧,互联网裁员接二连三,许多码农找不到工作。 一位网友感叹:一边是计算机就业哀鸿遍野,一…...

解决外部主机无法访问Docker容器的方法
使用Docker启动了一个tomcat容器,并做了端口映射,但是外部主机仍然无法访问。 编辑centos上的配置文件 vi /etc/sysctl.conf net.ipv4.ip_forward1 systemctl restart network保存以后即可生效,这个配置是开启linux的ip数据包转发功能&#…...

IDEA中修改类头的文档注释信息
IDEA中修改类头的文档注释信息 选择File--Settings--Editor--File and Code Templates--Includes,可以把文档注释写成这种的 /**author: Arbicoralcreate: ${YEAR}-${MONTH}-${DAY} ${TIME}Description: */这样回看就可以很清楚的看到自己创建脚本的时间ÿ…...