> 文章列表 > Springboot入门之集成MybatisPlus

Springboot入门之集成MybatisPlus

Springboot入门之集成MybatisPlus

MybatisPlus是一个 Mybatis的增强工具,在Mybatis的基础上只做增强不做改变,为简化开发、提高效率而生。 

1.添加依赖【pom.xml】

        <!-- mysql db --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5.1</version></dependency><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-annotation</artifactId><version>3.5.1</version><scope>compile</scope></dependency><!--代码生成器--><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-generator</artifactId><version>3.5.1</version></dependency>

2.配置数据源信息[application.yml]

# 数据源配置
spring:datasource:url: jdbc:mysql://xxx:3306/xxx?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&useSSL=false&allowMultiQueries=trueusername: xxxpassword: xxxxxdbcp2:validation-query: SELECT 1time-between-eviction-runs-millis: 18800hikari:max-lifetime: 30000validation-timeout: 3000connection-timeout: 18800idle-timeout: 18800# sql日志输出配置
mybatis-plus:configuration:log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

3.MybatisPlus拦截器配置

配置后MybatisPlus增加功能生效【如分页等】。

@Configuration
@MapperScan(value = {"com.{company}.{model}.mapper"})
public class MybatisPlusConfig {@Beanpublic MybatisPlusInterceptor mybatisPlusInterceptor() {MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));return interceptor;}}

4.编写XxxMapper

extends BaseMapper<XxxDo>;

/*** <p>* Mapper 接口* </p>** @author ocean* @since 2023-03-17*/
@Mapper
public interface XxxMapper extends BaseMapper<XxxDo> {}

5.编写XxxService

extends ServiceImpl<XxxMapper, XxxDo>

@Service
public class XxxServiceImpl extends ServiceImpl<XxxMapper, XxxDo> implements XxxService {@Resourceprivate XxxMapper XxxMapper;public void test(){XxxMapper.insert(new XxxDo());XxxMapper.deleteById(1L);XxxMapper.updateById(new XxxDo());XxxMapper.selectPage(new Page<XxxDo>(1, 10), new QueryWrapper<>());}
}

6.Wapper查询

1.查询Wrapper
QueryWrapper<XxxDo> queryWrapper = Wrappers.query();
LambdaQueryWrapper<XxxDo> lambdaQueryWrapper = Wrappers.lambdaQuery();

2.更新Wrapper
UpdateWrapper<XxxDo> updateWrapper = Wrappers.update();
LambdaUpdateWrapper<XxxDo> lambdaUpdateWrapper = Wrappers.lambdaUpdate();

7.配置安全

7.1)生成数据源加密信息

import com.baomidou.mybatisplus.core.toolkit.AES;public class JdbcEncodeUtil {public static final String URL = "jdbc:mysql://xxx:3306/xxx?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&useSSL=false&allowMultiQueries=true";public static final String USERNAME = "xxx";public static final String PASSWORD = "xxxx";public static void main(String[] args) {// 生成 16 位随机 AES 密钥String randomKey = AES.generateRandomKey();// 随机密钥加密String url = AES.encrypt(URL, randomKey);String username = AES.encrypt(USERNAME, randomKey);String password = AES.encrypt(PASSWORD, randomKey);System.out.println("randomKey = " + randomKey);System.out.println("url = " + url);System.out.println("username = " + username);System.out.println("password = " + password);}}

7.2)配置数据源加密【application.yml】

// 加密配置 mpw: 开头紧接加密内容( 非数据库配置专用 YML 中其它配置也是可以使用的 )
spring:datasource:url: mpw:qRhvCwF4GOqjessEB3G+a5okP+uXXr96wcucn2Pev6Bf1oEMZ1gVpPPhdDmjQqoMpassword: mpw:Hzy5iliJbwDHhjLs1L0j6w==username: mpw:Xb+EgsyuYRXw7U7sBJjBpA==

7.3)配置秘钥

7.3.1)jar包运行 java -jar xxx.jar --mpw.key=1111111111111 

7.3.2)IDEA 设置 Program arguments,如下图:

7.4)实现原理

SpringBoot 提供修改Spring环境后置处理器【EnvironmentPostProcessor】,允许在应用程序之前操作环境属性值。

public class SafetyEncryptProcessor implements EnvironmentPostProcessor {public SafetyEncryptProcessor() {}public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {String mpwKey = null;Iterator var4 = environment.getPropertySources().iterator();while(var4.hasNext()) {PropertySource<?> ps = (PropertySource)var4.next();if (ps instanceof SimpleCommandLinePropertySource) {SimpleCommandLinePropertySource source = (SimpleCommandLinePropertySource)ps;mpwKey = source.getProperty("mpw.key");break;}}if (StringUtils.isNotBlank(mpwKey)) {HashMap<String, Object> map = new HashMap();Iterator var15 = environment.getPropertySources().iterator();while(true) {PropertySource ps;do {if (!var15.hasNext()) {if (CollectionUtils.isNotEmpty(map)) {environment.getPropertySources().addFirst(new MapPropertySource("custom-encrypt", map));}return;}ps = (PropertySource)var15.next();} while(!(ps instanceof OriginTrackedMapPropertySource));OriginTrackedMapPropertySource source = (OriginTrackedMapPropertySource)ps;String[] var8 = source.getPropertyNames();int var9 = var8.length;for(int var10 = 0; var10 < var9; ++var10) {String name = var8[var10];Object value = source.getProperty(name);if (value instanceof String) {String str = (String)value;if (str.startsWith("mpw:")) {map.put(name, AES.decrypt(str.substring(4), mpwKey));}}}}}}
}

8.自动填充功能

8.1)实现元对象处理器接口【com.baomidou.mybatisplus.core.handlers.MetaObjectHandler】

@Slf4j
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {@Overridepublic void insertFill(MetaObject metaObject) {log.info("start insert fill ....");// 起始版本 3.3.3(推荐)this.strictInsertFill(metaObject, "createTime", () -> new Date(), Date.class);// 起始版本 3.3.0(推荐使用)// this.strictInsertFill(metaObject, "createTime", LocalDateTime.class, LocalDateTime.now());//// this.fillStrategy(metaObject, "createTime", LocalDateTime.now());}@Overridepublic void updateFill(MetaObject metaObject) {log.info("start update fill ....");// 起始版本 3.3.3(推荐)this.strictUpdateFill(metaObject, "updateTime", () -> new Date(), Date.class);// 起始版本 3.3.0(推荐)// this.strictUpdateFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now());// 也可以使用(3.3.0 该方法有bug)// this.fillStrategy(metaObject, "updateTime", LocalDateTime.now()); // 也可以使用(3.3.0 该方法有bug)}}

8.2)注解填充字段【@TableField(fill = FieldFill.INSERT/.INSERT_UPDATE/.UPDATE) 】

/*** 基础 [entity]** @author ocean.liu*/
@Data
public class BaseEntity {/*** 创建时间*/@TableField(value = "create_time", fill = FieldFill.INSERT)protected Date createTime;/*** 修改时间*/@TableField(value = "update_time", fill = FieldFill.INSERT_UPDATE)protected Date updateTime;/*** 是否删除*/@TableField(value = "is_deleted")protected Integer isDeleted;}

9.代码生成器

public class CodeGenerator {/*** 数据库链接地址**/private static final String JDBC_URL_MAN = "jdbc:mysql://xxxxx:3306/xxx?useUnicode=true&characterEncoding=UTF-8";/*** 数据库登录账号**/private static final String JDBC_USER_NAME = "xx";/*** 数据库登录密码**/private static final String JDBC_PASSWORD = "xxxx";public static void main(String[] args) {String dir = "\\\\xx\\\\xxx";String tablePrefix = "t_";List<String> tables = new ArrayList<>();tables.add("t_doctor");FastAutoGenerator.create(JDBC_URL_MAN, JDBC_USER_NAME, JDBC_PASSWORD).globalConfig(builder -> {builder.author("ocean")                                                           // 作者.outputDir(System.getProperty("user.dir") + dir + "\\\\src\\\\main\\\\java")    // 输出路径(写到java目录).enableSwagger()                                                          // 开启swagger.commentDate("yyyy-MM-dd").fileOverride();                                                          // 开启覆盖之前生成的文件}).packageConfig(builder -> {builder.parent("com.{company}").moduleName("{model}").entity("entity").service("service").serviceImpl("serviceImpl").controller("api").mapper("mapper").xml("mapper").pathInfo(Collections.singletonMap(OutputFile.mapperXml, System.getProperty("user.dir") + dir + "\\\\src\\\\main\\\\resources\\\\mapper"));}).strategyConfig(builder -> {builder.addInclude(tables).addTablePrefix(tablePrefix).serviceBuilder().formatServiceFileName("%sService").formatServiceImplFileName("%sServiceImpl").entityBuilder().enableLombok().logicDeleteColumnName("deleted").enableTableFieldAnnotation().controllerBuilder().formatFileName("%sController").enableRestStyle().mapperBuilder().enableBaseResultMap()               // 生成通用的resultMap.superClass(BaseMapper.class).formatMapperFileName("%sMapper").enableMapperAnnotation().formatXmlFileName("%sMapper");})//.templateEngine(new FreemarkerTemplateEngine()) // 使用Freemarker引擎模板,默认的是Velocity引擎模板.execute();}}

MyBatisPlus官方指南