SpringBoot整合mybatis-plus

官网: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 接口

1、service接口-继承Iservice


public interface IUserService extends IService<User> {
}

2、接口实现类


@Service
public class IUserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {
}

Mapper CRUD 接口

参考

MyBatis-Plus 之selectMaps、selectObjs、selectCount、selectOne的使用 - Python技术站



MyBatis-Plus 之selectMaps、selectObjs、selectCount、selectOne的使用_java_脚本之家


//BaseMapper接口中提供了单表的所有操作,连表不行,需要自己实现
@Repository
public interface UserMapper extends BaseMapper<User> {
}

新增

int insert(T entity); // 插入一条记录,entity 为 实体对象

修改

int update(T entity, Wrapper<T> updateWrapper); // 根据 whereEntity 条件,更新记录

int updateById(T entity); // 根据 ID 修改

删除

int delete(Wrapper<T> wrapper); // 根据 entity 条件,删除记录,wrapper 可以为 null

int deleteBatchIds(Collection idList); // 根据ID 批量删除

int deleteById(Serializable id); // 根据 ID 删除

int deleteByMap(Map<String, Object> map); // 根据 columnMap 条件,删除记录

查询

T selectById(Serializable id); // 根据 ID 查询

T selectOne(Wrapper<T> queryWrapper); // 根据 entity 条件,查询一条记录

List<T> selectBatchIds(Collection idList); // 根据ID 批量查询

List<T> selectList(Wrapper<T> queryWrapper); // 根据 entity 条件,查询全部记录

List<T> selectByMap(Map<String, Object> columnMap); // 根据 columnMap 条件

List<Map<String, Object>> selectMaps(Wrapper<T> queryWrapper); // 根据 Wrapper 条件,查询全部记录

List<Object> selectObjs( Wrapper<T> queryWrapper); // 根据 Wrapper 条件,查询全部记录。注意: 只返回第一个字段的值

IPage<T> selectPage(IPage<T> page, Wrapper<T> queryWrapper); // 根据 entity 条件,查询全部记录(并翻页)

IPage<Map<String, Object>> selectMapsPage(IPage<T> page, Wrapper<T> queryWrapper); // 根据 Wrapper 条件,查询全部记录(并翻页)

Integer selectCount(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper); // 根据 Wrapper 条件,查询总记录数

扩展使用

QueryWrapper与LambdaQueryWrapper

参考

【java】Maybatis-Plus 数据库查询 lambdaQuery和mapper中EQ、NE、GT、LT、GE、LE、select、like、in、leftjoin的用法及详解_mybatisplus的ne_svt_井木的博客-CSDN博客

QueryWrapper 是的列名匹配使用的是数据库中的字段名
LambdaQueryWrapper 的列名匹配使用的是“Lambda的语法,偏向于对象”,不用写死字段名

自动填充功能

注解填充字段 @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踩坑之下划线驼峰转换_mybatisplus下划线与驼峰_Echoo华地的博客-CSDN博客

在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

代码生成器

参考

https://www.cnblogs.com/lv1024/p/16086460.html

依赖

        <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();  //执行代码构造器
    }
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是使用SpringBootMybatis-plus配置多数据源的步骤: 1. 首先,在pom.xml文件中添加Mybatis-plus和数据库驱动的依赖: ```xml <dependencies> <!-- Mybatis-plus依赖 --> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>最新版本</version> </dependency> <!-- 数据库驱动依赖 --> <dependency> <groupId>数据库驱动的groupId</groupId> <artifactId>数据库驱动的artifactId</artifactId> <version>数据库驱动的版本</version> </dependency> </dependencies> ``` 2. 在application.yml或application.properties文件中配置数据源信息: ```yaml spring: datasource: # 主数据源配置 url: 主数据源的URL username: 主数据源的用户名 password: 主数据源的密码 driver-class-name: 主数据源的驱动类名 # 其他数据源配置 datasources: 数据源1的名称: url: 数据源1的URL username: 数据源1的用户名 password: 数据源1的密码 driver-class-name: 数据源1的驱动类名 数据源2的名称: url: 数据源2的URL username: 数据源2的用户名 password: 数据源2的密码 driver-class-name: 数据源2的驱动类名 ``` 3. 创建多数据源配置类,继承AbstractRoutingDataSource,并重写determineCurrentLookupKey方法,根据注解选择使用哪个数据源: ```java @Configuration public class MultipleDataSourceConfig extends AbstractRoutingDataSource { @Override protected Object determineCurrentLookupKey() { return DataSourceContextHolder.getDataSource(); } } ``` 4. 创建数据源上下文类,用于设置和获取当前使用的数据源: ```java public class DataSourceContextHolder { private static final ThreadLocal<String> contextHolder = new ThreadLocal<>(); public static void setDataSource(String dataSource) { contextHolder.set(dataSource); } public static String getDataSource() { return contextHolder.get(); } public static void clearDataSource() { contextHolder.remove(); } } ``` 5. 创建数据源切换注解,用于在方法或类上标注使用哪个数据源: ```java @Target({ElementType.METHOD, ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface DataSource { String value() default "主数据源"; } ``` 6. 创建数据源切面类,用于根据注解切换数据源: ```java @Aspect @Component public class DataSourceAspect { @Before("@annotation(dataSource)") public void switchDataSource(JoinPoint joinPoint, DataSource dataSource) { String dataSourceName = dataSource.value(); DataSourceContextHolder.setDataSource(dataSourceName); } @After("@annotation(dataSource)") public void restoreDataSource(JoinPoint joinPoint, DataSource dataSource) { DataSourceContextHolder.clearDataSource(); } } ``` 7. 在需要使用多数据源的方法或类上使用@DataSource注解,指定使用哪个数据源: ```java @DataSource("数据源1的名称") public void method1() { // 使用数据源1执行操作 } @DataSource("数据源2的名称") public void method2() { // 使用数据源2执行操作 } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值