官网:MyBatis-Plus
依赖
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.1</version>
</dependency>
配置
配置 MapperScan 注解
@SpringBootApplication
@MapperScan("com.mybatisplus.mapper")
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
配置application.yml
mybatis-plus:
mapper-locations: classpath:mapper/*.xml
configuration:
map-underscore-to-camel-case: true
auto-mapping-behavior: full
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
# 逻辑删除配置
global-config:
db-config:
logic-delete-value: 1
logic-not-delete-value: 0
其他参数参照:基本配置
使用
实体类
@Data
@AllArgsConstructor
@NoArgsConstructor
@TableName(value = "user")//和实体类名不一致
public class User {
//标记该属性为主键。value:属性名和列名不一样
@TableId(value = "id")
private Integer id;
@TableField(value = "name")
private String name;
private Integer age;
private String email;
}
注解
@TableName
表名注解,标识实体类对应的表,用在实体类上。
属性 | 类型 | 必须指定 | 默认值 | 描述 |
value | String | 否 | "" | 表名 |
schema | String | 否 | "" | schema |
keepGlobalPrefix | boolean | 否 | false | 是否保持使用全局的 tablePrefix 的值(当全局 tablePrefix 生效时) |
resultMap | String | 否 | "" | xml 中 resultMap 的 id(用于满足特定类型的实体类对象绑定) |
autoResultMap | boolean | 否 | false | 是否自动构建 resultMap 并使用(如果设置 resultMap 则不会进行 resultMap 的自动构建与注入) |
excludeProperty | String[] | 否 | {} | 需要排除的属性名 @since 3.3.1 |
@TableId
实体类主键字段
属性 | 类型 | 必须指定 | 默认值 | 描述 |
value | String | 否 | "" | 主键字段名 |
type | Enum | 否 | IdType.NONE | 指定主键类型 |
IdType
值 | 描述 |
AUTO | 数据库 ID 自增 |
NONE | 无状态,该类型为未设置主键类型(注解里等于跟随全局,全局里约等于 INPUT) |
INPUT | insert 前自行 set 主键值 |
ASSIGN_ID | 分配 ID(主键类型为 Number(Long 和 Integer)或 String)(since 3.3.0),使用接口IdentifierGenerator的方法nextId(默认实现类为DefaultIdentifierGenerator雪花算法) |
ASSIGN_UUID | 分配 UUID,主键类型为 String(since 3.3.0),使用接口IdentifierGenerator的方法nextUUID(默认 default 方法) |
@TableField
字段注解(非主键)
属性 | 类型 | 必须指定 | 默认值 | 描述 |
value | String | 否 | "" | 数据库字段名 |
exist | boolean | 否 | true | 是否为数据库表字段 |
condition | String | 否 | "" | 字段 where 实体查询比较条件,有值设置则按设置的值为准,没有则为默认全局的 %s=#{%s} |
update | String | 否 | "" | 字段 update set 部分注入,例如:当在version字段上注解update="%s+1" 表示更新时会 set version=version+1 (该属性优先级高于 el 属性) |
insertStrategy | Enum | 否 | FieldStrategy.DEFAULT | 举例:NOT_NULL insert into table_a(<if test="columnProperty != null">column</if>) values (<if test="columnProperty != null">#{columnProperty}</if>) |
updateStrategy | Enum | 否 | FieldStrategy.DEFAULT | 举例:IGNORED update table_a set column=#{columnProperty} |
whereStrategy | Enum | 否 | FieldStrategy.DEFAULT | 举例:NOT_EMPTY where <if test="columnProperty != null and columnProperty!=''">column=#{columnProperty}</if> |
fill | Enum | 否 | FieldFill.DEFAULT | 字段自动填充策略 |
select | boolean | 否 | true | 是否进行 select 查询 |
keepGlobalFormat | boolean | 否 | false | 是否保持使用全局的 format 进行处理 |
jdbcType | JdbcType | 否 | JdbcType.UNDEFINED | JDBC 类型 (该默认值不代表会按照该值生效) |
typeHandler | Class<? extends TypeHandler> | 否 | UnknownTypeHandler.class | 类型处理器 (该默认值不代表会按照该值生效) |
numericScale | String | 否 | "" | 指定小数点后保留的位数 |
FieldStrategy
值 | 描述 |
IGNORED | 忽略判断 |
NOT_NULL | 非 NULL 判断 |
NOT_EMPTY | 非空判断(只对字符串类型字段,其他类型字段依然为非 NULL 判断) |
DEFAULT | 追随全局配置 |
NEVER | 不加入SQL |
FieldFill
值 | 描述 |
DEFAULT | 默认不处理 |
INSERT | 插入时填充字段 |
UPDATE | 更新时填充字段 |
INSERT_UPDATE | 插入和更新时填充字段 |
@Version
乐观锁注解、标记 @Version 在字段上
@EnumValue
普通枚举类注解(注解在枚举字段上)
@TableLogic
表字段逻辑处理注解(逻辑删除)
属性 | 类型 | 必须指定 | 默认值 | 描述 |
value | String | 否 | "" | 逻辑未删除值 |
delval | String | 否 | "" | 逻辑删除值 |
@KeySequence
序列主键策略 oracle
属性 | 类型 | 必须指定 | 默认值 | 描述 |
value | String | 否 | "" | 序列名 |
dbType | Enum | 否 | DbType.OTHER | 数据库类型,未配置默认使用注入 IKeyGenerator 实现,多个实现必须指定 |
@InterceptorIgnore
value 值为 1 | yes | on 视为忽略,例如 @InterceptorIgnore(tenantLine = "1")
value 值为 0 | false | off | 空值不变 视为正常执行。
@OrderBy
内置 SQL 默认指定排序,优先级低于 wrapper 条件查询
属性 | 类型 | 必须指定 | 默认值 | 描述 |
isDesc | boolean | 否 | true | 是否倒序查询 |
sort | short | 否 | Short.MAX_VALUE | 数字越小越靠前 |
Service CRUD 接口
参考官网接口,官网:CRUD 接口
save
boolean save(T entity);// 插入一条记录(选择字段,策略插入)
boolean saveBatch(Collection<T> entityList);// 插入(批量)
boolean saveBatch(Collection<T> entityList, int batchSize);// 插入(批量)
saveOrUpdate
boolean saveOrUpdate(T entity);// TableId 注解属性值存在则更新记录,否插入一条记录
boolean saveOrUpdate(T entity, Wrapper<T> updateWrapper);// 根据updateWrapper尝试更新,否继续执行saveOrUpdate(T)方法
boolean saveOrUpdateBatch(Collection<T> entityList);// 批量修改插入
boolean saveOrUpdateBatch(Collection<T> entityList, int batchSize);// 批量修改插入
remove
boolean remove(Wrapper<T> queryWrapper);// 根据 queryWrapper 设置的条件,删除记录
boolean removeById(Serializable id);// 根据 ID 删除
boolean removeByMap(Map<String, Object> columnMap);// 根据 columnMap 条件,删除记录
boolean removeByIds(Collection<? extends Serializable> idList);// 删除(根据ID 批量删除)
update
boolean update(Wrapper<T> updateWrapper);// 根据 UpdateWrapper 条件,更新记录 需要设置sqlset
boolean update(T updateEntity, Wrapper<T> whereWrapper);// 根据 whereWrapper 条件,更新记录
boolean updateById(T entity);// 根据 ID 选择修改
boolean updateBatchById(Collection<T> entityList);// 根据ID 批量更新
boolean updateBatchById(Collection<T> entityList, int batchSize);// 根据ID 批量更新
get
T getById(Serializable id);// 根据 ID 查询
T getOne(Wrapper<T> queryWrapper);// 根据 Wrapper,查询一条记录。结果集,如果是多个会抛出异常,随机取一条加上限制条件 wrapper.last("LIMIT 1")
T getOne(Wrapper<T> queryWrapper, boolean throwEx);// 根据 Wrapper,查询一条记录
Map<String, Object> getMap(Wrapper<T> queryWrapper);// 根据 Wrapper,查询一条记录
<V> V getObj(Wrapper<T> queryWrapper, Function<? super Object, V> mapper);// 根据 Wrapper,查询一条记录
list
List<T> list();// 查询所有
List<T> list(Wrapper<T> queryWrapper);// 查询列表
Collection<T> listByIds(Collection<? extends Serializable> idList);// 查询(根据ID 批量查询)
Collection<T> listByMap(Map<String, Object> columnMap);// 查询(根据 columnMap 条件)
List<Map<String, Object>> listMaps();// 查询所有列表
List<Map<String, Object>> listMaps(Wrapper<T> queryWrapper);// 查询列表
List<Object> listObjs();// 查询全部记录
<V> List<V> listObjs(Function<? super Object, V> mapper);// 查询全部记录
List<Object> listObjs(Wrapper<T> queryWrapper);// 根据 Wrapper 条件,查询全部记录
<V> List<V> listObjs(Wrapper<T> queryWrapper, Function<? super Object, V> mapper);// 根据 Wrapper 条件,查询全部记录
page
IPage<T> page(IPage<T> page);// 无条件分页查询
IPage<T> page(IPage<T> page, Wrapper<T> queryWrapper);// 条件分页查询
IPage<Map<String, Object>> pageMaps(IPage<T> page);// 无条件分页查询
IPage<Map<String, Object>> pageMaps(IPage<T> page, Wrapper<T> queryWrapper);// 条件分页查询
count
int count();// 查询总记录数
int count(Wrapper<T> queryWrapper);// 根据 Wrapper 条件,查询总记录数
long count();// 查询总记录数(自3.4.3.2开始,返回值修改为long
long count(Wrapper<T> queryWrapper);// 根据 Wrapper 条件,查询总记录数
1、service接口-继承Iservice
public interface IUserService extends IService<User> {
}
2、接口实现类
@Service
public class IUserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {
}
Mapper CRUD 接口
insert
int insert(T entity);// 插入一条记录
delete
int delete(@Param(Constants.WRAPPER) Wrapper<T> wrapper);// 根据 entity 条件,删除记录
int deleteBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList);// 删除(根据ID 批量删除)
int deleteById(Serializable id);// 根据 ID 删除
int deleteByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap);// 根据 columnMap 条件,删除记录
update
int update(@Param(Constants.ENTITY) T updateEntity, @Param(Constants.WRAPPER) Wrapper<T> whereWrapper);// 根据 whereWrapper 条件,更新记录
int updateById(@Param(Constants.ENTITY) T entity);// 根据 ID 修改
select
T selectById(Serializable id);// 根据 ID 查询
T selectOne(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);// 根据 entity 条件,查询一条记录
List<T> selectBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList);// 查询(根据ID 批量查询)
List<T> selectList(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);// 根据 entity 条件,查询全部记录
List<T> selectByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap);// 查询(根据 columnMap 条件)
List<Map<String, Object>> selectMaps(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);// 根据 Wrapper 条件,查询全部记录
List<Object> selectObjs(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);// 根据 Wrapper 条件,查询全部记录。注意: 只返回第一个字段的值
IPage<T> selectPage(IPage<T> page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper);// 根据 entity 条件,查询全部记录(并翻页)
IPage<Map<String, Object>> selectMapsPage(IPage<T> page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper);// 根据 Wrapper 条件,查询全部记录(并翻页)
Integer selectCount(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);// 根据 Wrapper 条件,查询总记录数
参考
MyBatis-Plus 之selectMaps、selectObjs、selectCount、selectOne的使用 - Python技术站
MyBatis-Plus 之selectMaps、selectObjs、selectCount、selectOne的使用_java_脚本之家
//BaseMapper接口中提供了单表的所有操作,连表不行,需要自己实现
@Repository
public interface UserMapper extends BaseMapper<User> {
}
扩展使用
QueryWrapper与LambdaQueryWrapper
参考
QueryWrapper 是的列名匹配使用的是数据库中的字段名
LambdaQueryWrapper 的列名匹配使用的是“Lambda的语法,偏向于对象”,不用写死字段名
使用limit
// 查询单条
Article article = articleService.lambdaQuery().last("limit 1").one();
// 查询多条
List<Teacher> list = teacherService.lambdaQuery().last("limit 5").list();
去重
new QueryWrapper<T>().select("DISTINCT user_id");
自动填充功能
注解填充字段 @TableField(.. fill = FieldFill.INSERT)
public class User {
@TableField(fill = FieldFill.INSERT)
private Date createTime;
@TableField(fill = FieldFill.INSERT_UPDATE)
private Date updateTime;
....
}
@Slf4j
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
@Override
public void insertFill(MetaObject metaObject) {
this.setFieldValByName("createTime", new Date(), metaObject);
this.setFieldValByName("updateTime", new Date(), metaObject);
}
@Override
public void updateFill(MetaObject metaObject) {
this.setFieldValByName("updateTime", LocalDateTime.now(), metaObject);
}
}
分页查询
参考
mybatis-plus分页查询三种方法_mybatisplus分页查询_李长渊哦的博客-CSDN博客
MybatisPlus自定义对象查询和分页方法_mybatis-plus mapper 自定义方法 page对象_LinMain_copy的博客-CSDN博客
配置类
@Configuration
public class MybatisPlusConfig {
/**
* 分页插件。如果你不配置,分页插件将不生效
*/
@Bean
public MybatisPlusInterceptor paginationInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
// 指定数据库方言为 MYSQL
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
return interceptor;
}
}
调用通用方法-selectPage
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.isNotNull("account");
// 创建分页对象(1表示第一页;4表示每页大小为4)
Page<User> page = new Page<>(1, 10);
Page<User> result = userMapper.selectPage(page, wrapper);
for(Usern user : result.getRecords()) {
System.out.println(user);
}
自定义分页查询
如果返回类型是 IPage 则入参的 IPage 不能为null
如果想临时不分页,可以在初始化IPage时size参数传 <0 的值
service
public IPage<PlanVO> getMaintenancePlanList(PlanPageDTO PlanDTO) {
IPage<PlanVO> page = new Page<>(PlanDTO.getPageNo(), PlanDTO.getPageSize());
IPage<PlanVO> result = planMapper.queryPlanList(page, PlanVO);
return result;
}
mapper
传递参数 Page即自动分页,必须放在第一位
IPage<PlanVO> queryPlanList(@Param("page") IPage<PlanVO> page,@Param("PlanDTO") PlanPageDTO PlanDTO);
xml
<select id="queryPlanList" resultType="com.entity.vo.PlanVO">
select
p.id as id,
p.plan_code as planCode,
p.plan_name as planName
from plan p
order by p.id desc
</select>
处理json数据
对象
@Data
@Accessors(chain = true)
@TableName(autoResultMap = true)
public class User {
/**
* 必须开启映射注解
* @TableName(autoResultMap = true)
* 以下两种类型处理器,二选一 也可以同时存在,
* 选择对应的 JSON 处理器也必须存在对应 JSON 解析依赖包
*/
@TableField(typeHandler = JacksonTypeHandler.class)
// @TableField(typeHandler = FastjsonTypeHandler.class)
private OtherInfo otherInfo;
}
集合
自定义处理器,继承 FastjsonTypeHandler ,重载parse方法
public class JSONTypeHandler extends FastjsonTypeHandler {
private final Class<? extends Object> type;
public JSONTypeHandler(Class<?> type) {
super(type);
this.type = type;
}
@Override
protected List parse(String json) {
return JSON.parseArray(json, type);
// return JSON.parseObject(json, type);
}
@Override
protected String toJson(Object obj) {
return super.toJson(obj);
}
}
实体类
@TableName(autoResultMap = true)
public class User {
@TableField(typeHandler = JSONTypeHandler.class)
private List<Address> address;
}
在对应的xml中新增typeHandler、javaType
<mapper namespace="com.mapper.UserMapper">
<resultMap id="BaseResultMap" type="com.entiry.User">
<result property="address" column="address" typeHandler="com.handler.JSONTypeHandler" javaType="com.entiry.Address"/>
</resultMap>
</mapper>
下划线驼峰转换
参考
在mybatis-plus中,默认开启了下滑线-驼峰转换
可以通过配置文件修改
mybatis-plus.configuration.map-underscore-to-camel-case=true
批量新增
参考
1、【MyBatis-Plus】之批量插入_mybatisplus批量insert_王廷云的博客的博客-CSDN博客
2、MyBatis-plus 批量新增方法性能测试及优化学习_mybatisplus savebatch_找了一圈尾巴的博客-CSDN博客3、mybatis以及mybatisplus批量插入问题_mybatisplus 批量插入_又 欠的博客-CSDN博客
IService-saveBatch
自定义批量新增
pom
<!-- mybatis plus 与 springboot 整合的依赖 -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.0</version>
</dependency>
<!-- mybatis plus extension 包含了 mybatis plus core -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-extension</artifactId>
<version>3.4.0</version>
</dependency>
自定义SQL注入类
public class CustomSqlInjector extends DefaultSqlInjector {
@Override
public List<AbstractMethod> getMethodList(Class<?> mapperClass) {
// 获取父类SQL注入方法列表
List<AbstractMethod> methodList = super.getMethodList(mapperClass);
// 将批量插入方法添加进去
methodList.add(new InsertBatchSomeColumn());
return methodList;
}
}
mybatis-plus配置类
@Configuration
public class MybatisPlusConfig {
@Bean
public CustomSqlInjector customSqlInjector() {
return new CustomSqlInjector();
}
}
扩展BaseMapper
/**
* 添加批量插入接口
*/
public interface CustomMapper<T> extends BaseMapper<T> {
/**
* 批量插入
* @param entityList 实体列表
* @return 影响行数
*/
Integer insertBatchSomeColumn(Collection<T> entityList);
}
批量更新
参考
Mybatis-plus通过其他字段批量更新或新增_mybatisplus批量更新指定的字段_帅宇Yeah~的博客-CSDN博客mybatisplus 根据非主键字段批量更新内容_mybatis plus 非主键更新_白衣渡江-吕子明的博客-CSDN博客1、Mybatis-plus通过其他字段批量更新或新增_mybatisplus批量更新指定的字段_帅宇Yeah~的博客-CSDN博客
根据id更新
IService-updateBatchById、saveOrUpdateBatch
自定义更新
扩展BaseServiceImpl
public boolean updateBatchByQueryWrapper(final Collection<T> entityList, final Function<T, QueryWrapper> function) {
entityList.forEach(BaseEntity::preUpdate);
final int batchSize = 1000;
final String sqlStatement = this.sqlStatement(SqlMethod.UPDATE);
try (final SqlSession batchSqlSession = this.sqlSessionBatch()) {
int i = 0;
for (final T entity : entityList) {
final Map<String, Object> map = new HashMap<String, Object>(1);
map.put("ew", function.apply(entity));
map.put("et", entity);
batchSqlSession.update(sqlStatement, (Object)map);
if (i >= 1 && i % batchSize == 0) {
batchSqlSession.flushStatements();
}
++i;
}
batchSqlSession.flushStatements();
}
return true;
}
使用
Function<User, QueryWrapper> function = user -> {
QueryWrapper<SpatialStructureNodeTag> queryWrapper = new QueryWrapper();
queryWrapper.lambda().eq(User::getUserId, user.getUserId());
return queryWrapper;
};
BaseServiceImpl.updateBatchByQueryWrapper(userList, function);
逻辑删除
参考
MyBatis Plus 逻辑删除_mybatisplus逻辑删除_我有一只肥螳螂的博客-CSDN博客
Mybatis Plus 3.x 注入逻辑删除 LogicSqlInjector 报错_mybatis-plus 3.5 没有 logicsqlinjector 了_拄杖忙学轻声码的博客-CSDN博客
3.x需要在配置类新增
@Bean
public ISqlInjector sqlInjector() {
return new LogicSqlInjector();
}
实体类
@ApiModelProperty("是否删除标识 0:未删除 1:删除")
@TableLogic(value = "0",delval = "1")
private int isDel;
表字段为数据库关键字
@TableField(value="`group`")
private String group;
不能更新空值字段
参考
Mybatis-Plus不能更新对象字段为空值问题解决_mybatisplus空值不更新_lgily-1225的博客-CSDN博客Mybatis-Plus更新对象时字段更新为空值的问题 - 知乎
Mybatis-Plus中字段的更新策略是通过FieldStrategy属性控制的。
在实体字段上,如果不通过@TableField注解指定字段的更新策略,字段默认的更新策略是FieldStrategy.DEFAULT,即跟随全局策略。而Mybatis-Plus的全局配置中,字段的默认更新策略是FieldStrategy.NOT_NULL,即进行空值判断,不对NULL值数据进行处理。
设置字段级别的更新策略
@TableField(updateStrategy = FieldStrategy.IGNORED)
private String email;
设置全局更新策略
mybatis-plus.global-config.db-config.update-strategy=ignored
代码生成器
参考
依赖
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.1.2</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>3.2.0</version>
</dependency>
<!-- 模板引擎 -->
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity-engine-core</artifactId>
<version>2.0</version>
</dependency>
配置代码
public class Code {
public static void main(String[] args) {
//需要构建一个 代码自动生成器 对象
// 代码生成器
AutoGenerator mpg = new AutoGenerator();
//配置策略
//1、全局配置
GlobalConfig gc = new GlobalConfig();
String projectPath = System.getProperty("user.dir");
gc.setOutputDir(projectPath + "\\mybatis-plus\\src\\main\\java");
gc.setAuthor("xxxx");
gc.setOpen(false);
gc.setFileOverride(false); //是否覆盖
gc.setServiceName("%sService"); //去Service的I前缀
gc.setIdType(IdType.ID_WORKER);
gc.setDateType(DateType.ONLY_DATE);
gc.setSwagger2(true);
mpg.setGlobalConfig(gc);
//2、设置数据源
DataSourceConfig dsc = new DataSourceConfig();
dsc.setUrl("jdbc:mysql://111.11.11.11:111/aaa?useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2B8");
dsc.setDriverName("com.mysql.cj.jdbc.Driver");
dsc.setUsername("root");
dsc.setPassword("root");
dsc.setDbType(DbType.MYSQL);
mpg.setDataSource(dsc);
//3、包的配置
PackageConfig pc = new PackageConfig();
// pc.setModuleName("mybatis-plus");
pc.setParent("com.test");
pc.setEntity("pojo");
pc.setMapper("mapper");
pc.setService("service");
pc.setController("controller");
mpg.setPackageInfo(pc);
//4、策略配置
StrategyConfig strategy = new StrategyConfig();
strategy.setInclude("plan"); //设置要映射的表名
strategy.setNaming(NamingStrategy.underline_to_camel);
strategy.setColumnNaming(NamingStrategy.underline_to_camel);
strategy.setEntityLombokModel(true); //自动lombok
strategy.setLogicDeleteFieldName("del_flag");
//自动填充配置
TableFill createTime = new TableFill("create_date", FieldFill.INSERT);
TableFill updateTime = new TableFill("update_date", FieldFill.UPDATE);
ArrayList<TableFill> tableFills = new ArrayList<>();
tableFills.add(createTime);
tableFills.add(updateTime);
strategy.setTableFillList(tableFills);
//乐观锁
// strategy.setVersionFieldName("version");
// strategy.setRestControllerStyle(true);
// strategy.setControllerMappingHyphenStyle(true); //localhost:8080/hello_id_2
mpg.setStrategy(strategy);
mpg.execute(); //执行代码构造器
}
}
多数据源配置
依赖
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>dynamic-datasource-spring-boot-starter</artifactId>
<version>3.5.0</version>
</dependency>
配置文件
spring:
# 配置数据源信息
datasource:
dynamic:
# 设置默认的数据源或者数据源组,默认值即为master
primary: master
# 严格匹配数据源,默认false.true未匹配到指定数据源时抛异常,false使用默认数据源
strict: false
datasource:
master:
url: jdbc:mysql://localhost:3306/mybatis_plus?characterEncoding=utf-8&useSSL=false
driver-class-name: com.mysql.cj.jdbc.Driver
username: root
password: 123456
slave_1:
url: jdbc:mysql://localhost:3306/mybatis_plus_1?characterEncoding=utf-8&useSSL=false
driver-class-name: com.mysql.cj.jdbc.Driver
username: root
password: 123456
使用
DS注解既可以写在类上,也可以写在方法上,方法上的优先级高于类。
如果没有指定DS的属性值或者没有使用DS注解,就自动走master主库。
@DS("slave_1")//指定所操作的数据源
@Service
public class ProductServiceImpl extends ServiceImpl<ProductMapper, Product>
implements ProductService {
}
参考:https://baijiahao.baidu.com/s?id=1754519454163819416&wfr=spider&for=pc