MyBatisPlus 常用知识点总结
@
完整的Mybatis-Plus项目
- 创建User类
package com.example.ssmpdemo.entity;
import com.baomidou.mybatisplus.annotation.*;
import com.example.ssmpdemo.enums.Status;
import lombok.Data;
import java.util.Date;
/**
* 使用@TableName定义时,忽略已定义的table前缀
* @author wangchao
*/
@Data
@TableName(value = "tb_book2")
public class Book {
@TableId(type = IdType.AUTO)
private Integer id;
private String type;
private String name;
private String description;
@TableField(fill = FieldFill.INSERT_UPDATE)
private Date updateTime;
@TableField(fill = FieldFill.INSERT)
private Date createTime;
/**
* 直接使用自定义的枚举类型
*/
private Status status;
/**
* 定义乐观锁
*/
@Version
private Integer version;
}
- 创建UserMapper
BaseMapper : Mapper 继承该接口后,无需编写 mapper.xml 文件,即可获得CRUD功能
package com.example.ssmpdemo.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.ssmpdemo.entity.Book;
/**
* 继承自BaseMapper后,不需要再编写常见的增删改查方法。
* @author wangchao
*/
public interface BookMapper extends BaseMapper<Book> {
}
- 在启动类上添加
@MapperScan(value = "com.example.ssmpdemo.mapper")
或在对应的mapper
类上添加@Mapper
package com.example.ssmpdemo;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@MapperScan(value = "com.example.ssmpdemo.mapper")
@SpringBootApplication
public class SsmpdemoApplication {
public static void main(String[] args) {
SpringApplication.run(SsmpdemoApplication.class, args);
}
}
service接口和实现类:
// 定义接口
package com.example.ssmpdemo.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.example.ssmpdemo.entity.Book;
/**
* 使用IService自动补全接口需要的函数,避免重复开发。
* @author wangchao
*/
public interface IBookService extends IService<Book> {
}
// 定义实现类
package com.example.ssmpdemo.service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.ssmpdemo.entity.Book;
import com.example.ssmpdemo.mapper.BookMapper;
import org.springframework.stereotype.Service;
/**
* 使用ServiceImpl自动实现Service
* @author wangchao
*/
@Service
public class BookServiceImpl extends ServiceImpl<BookMapper, Book> implements IBookService {
}
- 编写
application.yml
spring:
datasource:
druid:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:5506/ssmpdemo?serverTimezone=UTC
username: root
password: xxxxx
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
global-config:
db-config:
# 添加表名前缀
table-prefix: tb_
# 枚举类型所在包位置
type-enums-package: com.example.ssmpdemo.enums
- 编写测试类
package com.example.ssmpdemo.service;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class BookServiceImplTest {
@Autowired
IBookService bookService;
@Test
void test(){
bookService.list();
}
}
常用注解
- 自动映射字段名和表名
- 自动映射表字段的下划线(不包括中划线)和java对象中的驼峰命名
设置表名(@TableName)
映射数据库的表名,如果已经定义了表格前缀,则不受前缀的影响(即TableName中依然要加上前缀)。
@Data
@TableName(value="user")
public class Account {
private Integer id;
private String name;
private Integer age;
}
设置实体类字段 (@TableField)
- value 映射非主键字段名
- exist 表示是否为数据库字段,取值为
false
则忽略该属性 - select 是否查询该字段,取值为
false
则不查询该属性 - fill 监听修改数据的动作。将对象存入数据库的时候,自动赋值,比如
create_time
,update_time
通过 @TableField(fill=FieldFill.INSERT_UPDATE)
更新时间字段
可选枚举类型:
public enum FieldFill {
DEFAULT,
INSERT,
UPDATE,
INSERT_UPDATE;
private FieldFill() {
}
}
在需要更新的字段上添加 @TableField(fill = FieldFill.INSERT)
@Data
@TableName(value="user")
public class User {
@TableId(value="id", type = IdType.NONE)
private Long id;
private String name;
private Integer age;
@TableField(fill = FieldFill.INSERT)
private Date createTime;
@TableField(fill = FieldFill.INSERT_UPDATE)
private Date updateTime;
}
编写时间更新策略。
/**3.0 版本之前需要在application.yml中配置,新版本用注解注入即可
global-config:
meta-object-handler: top.twilight0319.mybatisplus.handler.TimeHandler
**/
@Component
public class TimeHandler implements MetaObjectHandler {
@Override
public void insertFill(MetaObject metaObject) {
setFieldValByName("createTime", new Date(), metaObject);
setFieldValByName("updateTime", new Date(), metaObject);
}
@Override
public void updateFill(MetaObject metaObject) {
setFieldValByName("updateTime", new Date(), metaObject);
}
}
测试
@Test
public void update(){
User user = new User();
user.setName("张三");
user.setId(1393736407226277889L);
userMapper.updateById(user);
}
设置主键字段和策略 (@TableId)
- value 映射主键字段的名字,把当前属性匹配到主键字段
- type 设置主键类型,主键的生成策略, 取值来自枚举类
IdType
@Data
@TableName(value="user")
public class User {
@TableId(value="id", type = IdType.ASSIGN_UUID)
private String id;
private String name;
private Integer age;
}
public enum IdType {
AUTO(0),
NONE(1),
INPUT(2),
ASSIGN_ID(3),
ASSIGN_UUID(4),
/** @deprecated */
@Deprecated
ID_WORKER(3),
/** @deprecated */
@Deprecated
ID_WORKER_STR(3),
/** @deprecated */
@Deprecated
UUID(4);
private final int key;
private IdType(int key) {
this.key = key;
}
public int getKey() {
return this.key;
}
}
策略 | 含义 |
---|---|
NONE | 默认。如果用户没有指定值,则自动分配(雪花算法) |
AUTO | 完全采用数据库的策略,忽略用户的输入。数据库自增 |
INPUT | 完全采用开发者的策略,需要开发者手动赋值,如果不赋值则传入NULL |
ASSIGN_ID | 自动分配(雪花算法)。Long、Integer、String |
ASSIGN_UUID | MP分配UUID。只能是String |
- 默认情况下(
NONE
),优先采用用户指定的值。雪花算法的值需要用Long
保存。数据库中的字段也需要足够大(bigint
)。==> Preparing: INSERT INTO user ( id, name, age ) VALUES ( ?, ?, ? )
==> Parameters: 100(Long), 小明(String), 15(Integer)
<== Updates: 1
INPUT
情况下,如果不传入主键,则生成的SQL
中ID
为NULL
。如果数据库设置了自增,那就使用自增策略,没有就报错 (Column 'id' cannot be null
)(这是数据库的策略)。==> Preparing: INSERT INTO user ( id, name, age ) VALUES ( ?, ?, ? )
==> Parameters: null, 小明(String), 15(Integer)
<== Updates: 1
AUTO
情况下,生成的SQl
根本没有ID
。所以能不能成功完全取决于数据库。==> Preparing: INSERT INTO user ( name, age ) VALUES ( ?, ? )
==> Parameters: 小明(String), 15(Integer)
ASSIGN_ID
和ASSIGN_UUID
都会优先考虑用户的输入。只要User对象中的字段类型和数据库保持一致就不会报错。ASSIGN_ID
生成的数值会自动转换成String
类型的id。所以他也可以保存到字符串字段中。ASSIGN_UUID
生成的值无法转换成数值,所以只能用String
乐观锁(@Version)
通过version字段保证数据的安全性,当修改数据的时候会以version作为条件,当条件成立才会修改成功。每次修改数据会自动修改version字段的值,update ... set version = 2 where version = 1
- 数据库中需要有一个字段用来记录乐观锁的version
- 在实体类中使用注解标记当前字段用于乐观锁。
@Version
private Integer version;
- 添加
mybatis-plus-extension 3.4.2
依赖。 - 通过设置拦截器的方式添加组件。
/**
* 通过设置拦截器的方式添加组件。OptimisticLockerInterceptor已弃用
* @return Mybatis-plus的拦截器 MybatisPlusInterceptor
*/
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor(){
MybatisPlusInterceptor interceptor= new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new PaginationInnerInterceptor()); // 分页
interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor()); // 乐观锁
return interceptor;
}
只会修改一条,因为version字段被修改了
User user1 = userMapper.selectById(1393736407226277889L);
user1.setName("李四");
User user2 = userMapper.selectById(1393736407226277889L);
user2.setName("王五");
userMapper.updateById(user1);
userMapper.updateById(user2);
==> Preparing: UPDATE user SET name=?, age=?, create_time=?, update_time=?, version=? WHERE id=? AND version=?
==> Parameters: 李四(String), 15(Integer), 2021-05-16 09:13:49.0(Timestamp), 2021-05-16 10:12:39.051(Timestamp), 2(Integer), 1393736407226277889(Long), 1(Integer)
<== Updates: 1
==> Preparing: UPDATE user SET name=?, age=?, create_time=?, update_time=?, version=? WHERE id=? AND version=?
==> Parameters: 王五(String), 15(Integer), 2021-05-16 09:13:49.0(Timestamp), 2021-05-16 10:12:39.058(Timestamp), 2(Integer), 1393736407226277889(Long), 1(Integer)
<== Updates: 0
使用枚举类型 (@EnumValue)
- 编写枚举类,注意将value字段(即与数据库中的数值对应的字段)加上
@EmunValue
注解 - 在
application.yml
中添加mybatis-plus.type-enums-package: com.example.ssmpdemo.enums
配置枚举类型所在的package
- 在实体类中将字段声明为枚举类型:
private MyEnum status;
编写枚举类,两者都需要在yml文件中配置包路径:
// 枚举类型
public enum MyEnum {
WORK(0, "上班"),
REST(1, "休息");
@EnumValue
private Integer code;
private String msg;
MyEnum(Integer code, String msg){
this.code = code;
this.msg = msg;
}
}
// 或者使用mybatisplus提供的IEnum接口
public enum MyEnum2 implements IEnum<Integer> {
WORK(0, "上班"),
REST(1, "休息");
@EnumValue
private Integer code;
private String msg;
MyEnum2(Integer code, String msg){
this.code = code;
this.msg = msg;
}
@Override
public Integer getValue() {
return this.code;
}
}
配置枚举类型所在的package
mybatis-plus:
type-enums-package: top.twilight0319.mybatisplus.enums
实体类:
@Data
@TableName(value="user")
public class User {
@TableId(value="id", type = IdType.NONE)
private Long id;
private String name;
private Integer age;
@TableField(fill = FieldFill.INSERT)
private Date createTime;
@TableField(fill = FieldFill.INSERT_UPDATE)
private Date updateTime;
@TableField(value = "version")
@Version
private int versionNumber;
// 自动把数据库中的值转化为枚举类型
private MyEnum status;
}
逻辑删除(@TableLogic)
用一个字段表示该记录是否被删除,删除记录时不会真的删除记录,而是修改删除标记位。
- 1.数据表添加deleted字段
- 2.实体类添加注解
@TableLogic
@TableField(value="deleted")
private int deleted;
- 添加配置
mybatis-plus:
global-config:
db-config:
logic-not-delete-value: 0
logic-delete-value: 1
删除操作变成了 update
操作,如果没有@TableLogic
就会执行 delete
操作
==> Preparing: UPDATE user SET deleted=1 WHERE id=? AND deleted=0
==> Parameters: 1(Integer)
<== Updates: 1
查询语句也会忽略已删除的记录(通过添加where条件):
==> Preparing: SELECT id,name,age,create_time,update_time,version AS versionNumber,status,deleted FROM user WHERE deleted=0
==> Parameters:
<== Columns: id, name, age, create_time, update_time, versionNumber, status, deleted
增删改查
查询
// 不加任何条件全部查询
userMapper.selectList(null).forEach(System.out::println);
// 用wrapper 包装查询条件
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.eq("name", "小明");
wrapper.gt("age", 15);
userMapper.selectList(wrapper).forEach(System.out::println);
// allEq 多条件, ne 不等于, lt 小于, gt 大于, ge,
QueryWrapper<User> wrapper = new QueryWrapper<>();
Map<String, Object> map = new HashMap<>();
map.put("name", "小明");
map.put("age", 15);
wrapper.allEq(map);
userMapper.selectList(wrapper).forEach(System.out::println);
// 模糊查询
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.like("name", "小"); // %小%
wrapper.likeLeft(); // %小
wrapper.linkRight(); // 小%
userMapper.selectList(wrapper);
// 联合查询 inSQL
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.inSql("id", "select id from user where id > 200");
wrapper.inSql("id", "select id from user where id < 1393839033125179394");
userMapper.selectList(wrapper).forEach(System.out::println);
==> Preparing: SELECT id,name,age,create_time,update_time,version AS versionNumber,status,deleted FROM user WHERE deleted=0 AND (id IN (select id from user where id > 200) AND id IN (select id from user where id < 1393839033125179394))
==> Parameters:
// 排序
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.orderByDesc("id");
userMapper.selectList(wrapper).forEach(System.out::println);
// 先筛选再排序
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.orderByDesc("id");
wrapper.gt("id", 200);
userMapper.selectList(wrapper).forEach(System.out::println);
==> Preparing: SELECT id,name,age,create_time,update_time,version AS versionNumber,status,deleted FROM user WHERE deleted=0 AND (id > ?) ORDER BY id DESC
==> Parameters: 200(Integer)
// 根据指定id查询
User user = userMapper.selectById(100);
System.out.println(user);
// 查询批量的id,不存在的id会跳过
userMapper.selectBatchIds(Arrays.asList(100, 101, 102));
// 只能做等值判断,逻辑判断需要wrapper
Map<String, Object> map = new HashMap<>();
map.put("name", "小明");
map.put("age", 15);
userMapper.selectByMap(map);
// 查询数量
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.eq("age", 15);
userMapper.selectCount(wrapper); // 筛选后的计数
userMapper.selectCount(null); // 所有数量
// 将查询的结果封装到Map中
mapper.selectMaps(wrapper).forEach(...);
mapper.selectList(wrapper).forEach(...);
分页查询
// 帮助自动完成分页
@Bean
public PaginationInterceptor paginationInterceptor(){
return new PaginationInterceptor();
}
// 返回第一页的数据,每页数据两条
Page<User> page = new Page<>(1, 2);
Page<User> userPage = userMapper.selectPage(page, null);
System.out.println(userPage.getCurrent()); // 返回当前页位置,从0开始
System.out.println(userPage.getSize()); // 返回分页的大小
System.out.println(userPage.getTotal()); // 返回表记录的总数
userPage.getRecords().forEach(System.out::println); // 返回当前页的记录
// 将返回结果封装成Map
Page<Map<String, Object>> page = new Page<>(1, 2);
List<Map<String, Object>> records = userMapper.selectMapsPage(page, null).getRecords();
records.forEach(System.out::println);
==> Preparing: SELECT id,name,age,create_time,update_time,version AS versionNumber,status,deleted FROM user WHERE deleted=0 LIMIT ?,?
==> Parameters: 0(Long), 2(Long)
<== Columns: id, name, age, create_time, update_time, versionNumber, status, deleted
<== Row: 1, tom, 10, null, null, 0, 0, 0
<== Row: 100, 小明, 15, null, null, 0, 0, 0
<== Total: 2
// 返回所有主键
userMapper.selectObjs(null).forEach(System.out::println);
// 查询一个,结果只能是一条记录,否则会报错。
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.eq("id", 100);
userMapper.selectOne(wrapper);
org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.exceptions.TooManyResultsException: Expected one result (or null) to be returned by selectOne(), but found: 10
添加
只有这一个方法
User user = new User();
user.setId(11111L);
user.setName("小红");
user.setAge(25);
userMapper.insert(user);
System.out.println(user);
删除
@Test
public void delete(){
// 根据id删除
int i1 = userMapper.deleteById(1);
// 根据id列表删除
int i2 = userMapper.deleteBatchIds(Arrays.asList(1393605031051239426L, 11111L));
// 根据wrapper的条件删除
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.eq("age", 15);
int i3 = userMapper.delete(wrapper);
// 根据map指定的等式删除
Map<String, Object> map = new HashMap<>();
map.put("name", "李四");
int i4 = userMapper.deleteByMap(map);
}
修改
- 只有在传入user对象的时候,才会调用
fill
的Handler
和乐观锁@Version
。(即使user所有属性都为null也是一样) - 空的
user
对象,version
默认是0
, 所以会被update
成1
。
1. 根据id修改
User user = new User();
user.setId(1L);
mapper.updateById(user);
2. 根据 wrapper 修改
根据wrapper中的条件, 把指定行的值修改为user中的属性值。
User user = userMapper.selectById(1);
user.setName("小红");
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.eq("age", 25);
userMapper.update(user, wrapper);
==> Preparing: UPDATE user SET name=?, age=?, update_time=?, version=?, status=? WHERE deleted=0 AND (age = ? AND version = ?)
==> Parameters: 小红(String), 10(Integer), 2021-05-25 01:03:38.129(Timestamp), 1(Integer), 0(Integer), 25(Integer), 0(Integer)
<== Updates: 1
对于只有一个属性的实体,会忽略其他的属性值。(
update_time
和乐观锁version
除外)User user = new User();
user.setName("小红");
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.eq("age", 25);
userMapper.update(user, wrapper);
==> Preparing: UPDATE user SET name=?, update_time=?, version=? WHERE deleted=0 AND (age = ? AND version = ?)
==> Parameters: 小红(String), 2021-05-25 01:07:16.463(Timestamp), 1(Integer), 25(Integer), 0(Integer)
<== Updates: 0
使用
UpdateWrapper
替换实体类的赋值。(会忽略update_time
和乐观锁version
)UpdateWrapper<User> wrapper = new UpdateWrapper<>();
wrapper.set("age", 30).eq("name", "小红");
userMapper.update(null, wrapper);
==> Preparing: UPDATE user SET age=? WHERE deleted=0 AND (name = ?)
==> Parameters: 30(Integer), 小红(String)
<== Updates: 1
User
类和Wrapper中出现了重复的条件时,各个条件都会被依次追加到set
语句中。顺序是先追加User的非空属性,再追加wrapper中定义的属性,所以wrapper中的属性会覆盖User. 即User
中的属性会被wrapper覆盖。UpdateWrapper<User> wrapper = new UpdateWrapper<>();
wrapper.set("age", 30).eq("name", "小红");
User user = new User();
user.setAge(50);
userMapper.update(user, wrapper);
// 有两个age
==> Preparing: UPDATE user SET age=?, update_time=?, version=?, age=? WHERE deleted=0 AND (name = ? AND version = ?)
==> Parameters: 50(Integer), 2021-05-25 01:19:17.147(Timestamp), 1(Integer), 30(Integer), 小红(String), 0(Integer)
<== Updates: 0
3. 使用 lambda构造器
LambdaUpdateWrapper<User> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
lambdaUpdateWrapper.eq(User::getName, "小红").set(User::getAge, 30);
User user = new User();
user.setAge(50);
Integer rows = userMapper.update(user, lambdaUpdateWrapper);
和之前一样会覆盖User中的属性
==> Preparing: UPDATE user SET age=?, update_time=?, version=?, age=? WHERE deleted=0 AND (name = ? AND version = ?)
==> Parameters: 50(Integer), 2021-05-25 01:29:57.392(Timestamp), 1(Integer), 30(Integer), 小红(String), 0(Integer)
<== Updates: 0
自定义SQL
注解
- 编写
DeviceVO
. 属性名和字段名要保持一致,这样才能对应上。@Data
public class DeviceVO {
private int id;
private String name;
private BigInteger userId;
private String userName;
}
- 编写mapper方法
@Select(value="select device.*, user.name user_name from device, user where device.user_id=user.id and user.id=#{id};")
List<DeviceVO> deviceList(Integer id);
- 测试
userMapper.deviceList(100).forEach(System.out::println);
在 mapper.xml文件中定义自定义语句
- IDEA中不会将src下的配置文件复制到target目录下。所以最好放在resources目录下。默认目录是
resources/mapper/*.xml
,可以手动配置所需要的xml
文件mybatis-plus:
# 默认是/mapper/*.xml
mapper-locations: /mapper/*.xml
#{user.name}
和${eq.customSqlSegment}
不同。#是占位符?
,之后的可以将变量的值替换?
,而$是字符串拼接。比如select * from user WHERE (id = ?)
中的WHERE (id = ?)
就是select * from user ${eq.customSqlSegment}
的结果#{}
可以直接填属性名,而${}
需要加上@Param
才可以。
select
- 如果返回单条结果,那么方法的返回值不能写
List<User>
。但是反过来是可以的,用List<User>
也能接受一个对象。org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.exceptions.TooManyResultsException: Expected one result (or null) to be returned by selectOne(), but found: 10
- 返回List时,xml中的
resultType="top.twilight0319.mybatisplus.entity.DeviceVO"
直接写到对应实体类就行。
// 返回多表查询的List
List<DeviceVO> deviceList(Integer id);
// 返回单表的List
List<User> userList();
// 使用wrapper
List<User> userListWrapper(@Param(Constants.WRAPPER) Wrapper<User> wrapper);
// 使用Map保存结果
Map<String, Object> userListMap(@Param(Constants.WRAPPER) Wrapper<User> wrapper);
<select id="deviceList" resultType="top.twilight0319.mybatisplus.entity.DeviceVO">
select device.*, user.name user_name
from device, user
where device.user_id=user.id
and user.id=#{id};
</select>
<select id="userList" resultType="top.twilight0319.mybatisplus.entity.User">
select *
from user
where deleted=0;
</select>
<select id="userListWrapper" resultType="top.twilight0319.mybatisplus.entity.User">
select *
from user
${ew.customSqlSegment}
</select>
<select id="userListMap" resultType="java.util.Map">
select *
from user
${ew.customSqlSegment}
</select>
insert、update、delete
<insert>
中不用加返回类型,接口中可以返回 int
, long
, boolean
。如果返回值大于0则boolean为true,否则为false
// 可以在mapper.xml中使用 #{user.attrname}
// 如果不加 @Param 就直接写user的属性名
int insertUser(@Param("user") User user);
<insert id="insertUser" >
INSERT INTO user
(id, name, age)
VALUES(#{user.id}, #{user.name}, #{user.age});
</insert>
代码生成器
根据数据表自动生成实体类,Mapper, Service,ServiceImpl, Controller
- pom.xml 导入 Mybatisplus generator
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>3.3.1</version>
</dependency>
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity</artifactId>
<version>1.7</version>
</dependency>
使用时直接修改参数即可
package top.twilight0319.mybatisplus;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
import com.baomidou.mybatisplus.generator.config.GlobalConfig;
import com.baomidou.mybatisplus.generator.config.PackageConfig;
import com.baomidou.mybatisplus.generator.config.StrategyConfig;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
public class Main {
public static void main(String[] args) {
//创建generator对象
AutoGenerator autoGenerator = new AutoGenerator();
//数据源
DataSourceConfig dataSourceConfig = new DataSourceConfig();
dataSourceConfig.setDbType(DbType.MYSQL);
dataSourceConfig.setUrl("jdbc:mysql://localhost:3306/dbtest?useUnicode=true&characterEncoding=UTF-8");
dataSourceConfig.setUsername("root");
dataSourceConfig.setPassword("123456");
dataSourceConfig.setDriverName("com.mysql.cj.jdbc.Driver");
autoGenerator.setDataSource(dataSourceConfig);
//全局配置
GlobalConfig globalConfig = new GlobalConfig();
globalConfig.setOutputDir(System.getProperty("user.dir")+"/src/main/java");
globalConfig.setOpen(false); // true时会打开一个windows资源管理器
globalConfig.setAuthor("twilight");
globalConfig.setServiceName("%sService"); // 避免接口前出现I
autoGenerator.setGlobalConfig(globalConfig);
//包信息
PackageConfig packageConfig = new PackageConfig();
packageConfig.setParent("top.twilight0319.mybatisplus.generate");
packageConfig.setController("controller");
packageConfig.setService("service");
packageConfig.setServiceImpl("service.impl");
packageConfig.setMapper("mapper");
packageConfig.setEntity("entity");
autoGenerator.setPackageInfo(packageConfig);
//配置策略
StrategyConfig strategyConfig = new StrategyConfig();
strategyConfig.setEntityLombokModel(true);
strategyConfig.setInclude("user", "device"); // 只映射部分表
strategyConfig.setNaming(NamingStrategy.underline_to_camel);
strategyConfig.setColumnNaming(NamingStrategy.underline_to_camel);
autoGenerator.setStrategy(strategyConfig);
autoGenerator.execute();
}
}
注意下面两个包的版本要一致:
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.3.1</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>3.3.1</version>
</dependency>
MyBatisPlus 常用知识点总结的更多相关文章
- DB2_SQL_常用知识点&实践
DB2_SQL_常用知识点&实践 一.删除表中的数据(delete或truncate) 1 truncate table T_USER immediate; 说明:Truncate是一个能够快 ...
- JAVA常用知识点及面试题总结
1. String.StringBuffer.StringBuilder三者区别? (1)三者在执行速率上的比较: String<StringBuffer<StringBuilder 原因 ...
- HTML常用知识点代码演示
1 HTML部分常用知识点 <!-- 版本声明 --> <!DOCTYPE html> <!-- 唯一根元素 --> <html> <!-- 对网 ...
- Java 常用知识点
Java 常用知识点 1.日期格式化 SimpleDateFormat Date date=new Date(System.currentTimeMillis()) ; SimpleDateForma ...
- Less常用知识点
上篇文章介绍了如何安装Less,我们将所有东西都写在.less里面,最后通过命令将.less转换成.css文件,就可以放入到项目里用了.今天了解一些less常用知识点. 1.变量:声明两个变量,一个是 ...
- BIOS备忘录之EC常用知识点
BIOS工程师眼中常用的EC知识点汇总: EC的硬件架构 EC硬件结构上主要分为两部分:Host Domain和EC Domain Host Domain就是通过LPC与CPU通信的部分(LPC部分需 ...
- YII2常用知识点总结
YII2常用知识点总结 (一)总结性语句 (1)经常看看yii源码比如vendor\yiisoft\yii2\web这个目录(很重要)下的文件中的方法(这些文件中的公共方法,大致看了下基本上都可以通过 ...
- CSS3常用知识点
CSS3常用知识点 1 css3选择器 1.1 属性选择器 /* E[attr~=val] 表示的一个单独的属性值 这个属性值是以空格分隔的*/ .attr2 a[class~="kawa& ...
- javaScript常用知识点有哪些
javaScript常用知识点有哪些 一.总结 一句话总结:int = ~~myVar, // to integer | 是二进制或, x|0 永远等于x:^为异或,同0异1,所以 x^0 还是永远等 ...
随机推荐
- [WPF]WPF设置单实例启动
WPF设置单实例启动 使用Mutex设置单实例启动 using System; using System.Threading; using System.Windows; namespace Test ...
- screen -中断保留-屏幕同步
工作中经常用到 screen 用处: 中断保留 和屏幕同步. yum install screen screen -S name 创建 -ls 查看 -r 恢复 -x 同屏
- C++ IO流_数据的旅行之路
1. 前言 程序中的数据总是在流动着,既然是流动就会有方向.数据从程序的外部流到程序内部,称为输入:数据从程序内部流到外部称为输出. C++提供有相应的API实现程序和外部数据之间的交互,统称这类AP ...
- python随机值生成的常用方法
一.随机整数1.包含上下限:[a, b] import random #1.随机整数:包含上下限:[a, b] for i in range(10): print(random.randint(0,5 ...
- webpack打包优化点
目录 1. noParse 2. 包含和排除目录 3. IgnorePlugin 4. happypack 5. DllPlugin动态链接库 6. 热更新 7. 开发环境 tree-shaking ...
- 关于 JavaScript 中 null 的一切
原文地址:Everything about null in JavaScript 原文作者:Dmitri Pavlutin 译者:Gopal JavaScript 有两种类型:原始类型(strings ...
- 【SQLServer】并行的保留线程和已使用线程
我们都知道SQL Server的并行执行.为了快速处理一个请求,SQL Server会使用多个线程来处理一个请求.并行执行涉及两个重要的参数设置:·maxdop:最大并行度·并行度的成本阈值:如果任何 ...
- WindowsApps目录占用大量空间
WindowsApps目录占用大量空间今天遇到一个客户端的问题.Windows 10的电脑100G的C盘空间几乎耗尽.但是选取所有文件后总大小只有不到40G.按常规,肯定是有一些没有权限的文件夹的体积 ...
- MySQL数据备份 mysqldump 详解
MySQL数据备份流程 1 打开cmd窗口 通过命令进行数据备份与恢复: 需要在Windows的命令行窗口中进行: l 开始菜单,在运行中输入cmd回车: l 或者win+R,然后输入cmd回车,即可 ...
- 阿里云SLB的http强制转https
公司的要求:要求强制http转https 我的环境是: 域名<--->slb的ip<-->源服务器nginx 具体做法是: 第一步:证书放到slb的https上,通过443端口 ...