springboot mybatis-plus 亲自使用,手敲教程

springboot mybatis-plus使用教程

编写时间: 2022-11-07

基于mysql5.7、jdk8、mybatis-plus3.5.2

一、创建springboot工程,添加依赖

创建springboot工程后, pom.xml文件中添加maven依赖

<!-- pom.xml-->
<dependencies>
    <!--springboot-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
    <!-- config -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-configuration-processor</artifactId>
        <optional>true</optional>
    </dependency>
    <!-- web tomcat mvc -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <!--mysql-->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.22</version>
    </dependency>

    <!--lombok-->
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>
    <!-- mybatis-plus-->
    <dependency>
        <groupId>com.baomidou</groupId>
        <artifactId>mybatis-plus-boot-starter</artifactId>
        <version>3.5.2</version>
    </dependency>
    <!-- 打印sql执行时间-->
    <dependency>
        <groupId>p6spy</groupId>
        <artifactId>p6spy</artifactId>
        <version>3.9.1</version>
    </dependency>
</dependencies>

二、配置文件

  1. springboot工程配置文件,配置数据库链接和 sql日志打印
# application.yml
# DataSource Config mysql
spring:
  datasource:
    username: root
    password: root
#    driver-class-name: com.mysql.cj.jdbc.Driver
#    url: jdbc:mysql://localhost/mybatis_plus?userUnicode=true&characterEncoding=utf-8&serverTimezone=UTC
    ###慢sql记录日志,会影响性能,生产勿用 ###
    driver-class-name: com.p6spy.engine.spy.P6SpyDriver
    url: jdbc:p6spy:mysql://localhost/mybatis_plus?userUnicode=true&characterEncoding=utf-8&serverTimezone=UTC

#mybatis-plus配置日志
mybatis-plus:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
  global-config: # 配置逻辑删除
    db-config:
      logic-delete-field: deleted # 全局逻辑删除的实体字段名(since 3.3.0,配置后可以忽略不配置步骤2)
      logic-delete-value: 1 # 逻辑已删除值(默认为 1)
      logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)
  1. 配置乐观锁拦截器
package space.goldchen.mybatisplus.demo.config;

import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.annotation.EnableTransactionManagement;

/**
 * @author Goldchen
 * @create 2022-11-08 21:23
 */
@Configuration  //是配置类
@MapperScan("space.goldchen.mybatisplus.demo.mapper") //扫描mapper,相当于启动类上加配置
@EnableTransactionManagement
public class MybatisPlusConfig {
    /**
     * 注册乐观锁拦截器,用@Version去标记实体中的版本字段,如:@Version private version;
     * 乐观锁支持的字段:支持的数据类型只有:int,Integer,long,Long,Date,Timestamp,LocalDateTime
     * 原理:当要更新一条记录时,是希望这条记录没有被更新的,
     * update member name = "陈6" ,version = version +1  where id = 2 and version = 1
     */
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
        // 添加乐观锁插件
        mybatisPlusInterceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());

        // 添加分页插件
        PaginationInnerInterceptor paginationInnerInterceptor = new PaginationInnerInterceptor(DbType.MYSQL);
        // 设置请求的页面大于最大页后操作,true调回到首页,false继续请求。默认false
        paginationInnerInterceptor.setOverflow(false);
        // 单页分页条数限制,默认无限制
        paginationInnerInterceptor.setMaxLimit(500L);
        mybatisPlusInterceptor.addInnerInterceptor(paginationInnerInterceptor);

        return mybatisPlusInterceptor;
    }
}

三、数据库表设计

-- 创建会员表
DROP TABLE IF EXISTS member;
CREATE TABLE member(
    id BIGINT NOT NULL   COMMENT 'ID' ,
    name VARCHAR(255)    COMMENT '姓名' ,
    version int   DEFAULT 0 COMMENT '乐观锁版本' ,
    deleted char   DEFAULT '0' COMMENT '逻辑删除' ,
    created_time DATETIME    COMMENT '创建时间' ,
    updated_time DATETIME    COMMENT '更新时间' ,
    PRIMARY KEY (id)
)  COMMENT = '会员';
-- 插入5条数据
insert into member (id, name, version, created_time, updated_time)
values (1, '陈1', 0, now(), now()),
       (2, '陈2', 0, now(), now()),
       (3, '陈3', 0, now(), now()),
       (4, '陈4', 0, now(), now()),
       (5, '陈5', 0, now(), now())
;

四、使用插件生成代码

使用了mybatisX和mybatisPlus 插件生成 entity,mapper,service层;

使用 EasyCode插件生成了controller

当然,我感觉这三个插件,并没有达到我的预期,欢迎给我推荐

  1. 实体类
package space.goldchen.mybatisplus.demo.domain;

import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.IdType;
import java.time.LocalDateTime;
import com.baomidou.mybatisplus.annotation.TableId;
import java.io.Serializable;

import com.baomidou.mybatisplus.annotation.Version;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;

/**
 * <p>
 * 会员
 * </p>
 *
 * @author author123
 * @since 2022-11-08
 */
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("member")
public class Member implements Serializable {

    private static final long serialVersionUID = 1L;

    /**
     * ID 尽量使用Long型,默认是雪花算法
     */
    @TableId(value = "id", type = IdType.ASSIGN_ID)
    private Long id;

    /**
     * 姓名
     */
    private String name;

    /**
     * 乐观锁版本
     */
    @Version
    private Integer version;

    /**
     * 创建时间
     */
    private LocalDateTime createdTime;

    /**
     * 更新时间
     */
    private LocalDateTime updatedTime;

}

  1. Mapper相关
package space.goldchen.mybatisplus.demo.mapper;

import space.goldchen.mybatisplus.demo.domain.Member;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;

/**
 * <p>
 * 会员 Mapper 接口
 * </p>
 *
 * @author author123
 * @since 2022-11-08
 */
public interface MemberMapper extends BaseMapper<Member> {

}

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="space.goldchen.mybatisplus.demo.mapper.MemberMapper">

    <!-- 通用查询映射结果 -->
    <resultMap id="BaseResultMap" type="space.goldchen.mybatisplus.demo.domain.Member">
        <id column="id" property="id" />
        <result column="name" property="name" />
        <result column="version" property="version" />
        <result column="created_time" property="createdTime" />
        <result column="updated_time" property="updatedTime" />
    </resultMap>

</mapper>

  1. service层
package space.goldchen.mybatisplus.demo.service;

import space.goldchen.mybatisplus.demo.domain.Member;
import com.baomidou.mybatisplus.extension.service.IService;

/**
 * <p>
 * 会员 服务类
 * </p>
 *
 * @author author123
 * @since 2022-11-08
 */
public interface MemberService extends IService<Member> {

}

package space.goldchen.mybatisplus.demo.service.impl;

import space.goldchen.mybatisplus.demo.domain.Member;
import space.goldchen.mybatisplus.demo.mapper.MemberMapper;
import space.goldchen.mybatisplus.demo.service.MemberService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;

/**
 * <p>
 * 会员 服务实现类
 * </p>
 *
 * @author author123
 * @since 2022-11-08
 */
@Service
public class MemberServiceImpl extends ServiceImpl<MemberMapper, Member> implements MemberService {

}

  1. controller层

    修改接口,可以验证乐观锁version的变化,已经生效了

package space.goldchen.mybatisplus.demo.controller;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import space.goldchen.mybatisplus.demo.domain.Member;
import space.goldchen.mybatisplus.demo.service.MemberService;

import javax.annotation.Resource;
import java.io.Serializable;
import java.util.List;

/**
 * 会员(Member)表控制层
 *
 * @author makejava
 * @since 2022-11-08 23:05:37
 */
@RestController
@RequestMapping("member")
public class MemberController {
    /**
     * 服务对象
     */
    @Resource
    private MemberService memberService;

    /**
     * 分页查询所有数据
     *
     * @param page 分页对象
     * @param member 查询实体
     * @return 所有数据
     */
    @GetMapping
    public ResponseEntity selectAll(Page<Member> page, Member member) {
        return new ResponseEntity<>(this.memberService.page(page, new QueryWrapper<>(member)), HttpStatus.OK);
    }

    /**
     * 通过主键查询单条数据
     *
     * @param id 主键
     * @return 单条数据
     */
    @GetMapping("{id}")
    public ResponseEntity selectOne(@PathVariable Serializable id) {
        return new ResponseEntity<>(this.memberService.getById(id),HttpStatus.OK);
    }

    /**
     * 新增数据
     *
     * @param member 实体对象
     * @return 新增结果
     */
    @PostMapping
    public ResponseEntity insert(@RequestBody Member member) {
        return new ResponseEntity<>(this.memberService.save(member),HttpStatus.OK);
    }

    /**
     * 修改数据
     *
     * @param member 实体对象
     * @return 修改结果
     */
    @PutMapping
    public ResponseEntity update(@RequestBody Member member) {
        return new ResponseEntity<>(this.memberService.updateById(member),HttpStatus.OK);
    }

    /**
     * 删除数据
     *
     * @param idList 主键结合
     * @return 删除结果
     */
    @DeleteMapping
    public ResponseEntity delete(@RequestParam("idList") List<Long> idList) {
        return new ResponseEntity<>(this.memberService.removeByIds(idList),HttpStatus.OK);
    }
}

五、配置乐观锁

    /**
     * 乐观锁版本,实体和数据库加此字段,注意int类型,字符串不行
     */
    @Version
    private Integer version;

六、自动填充

比如创建时间、修改时间这些操作一般都是自动化完成的,是不用去手动更新

  1. 配置处理器
package space.goldchen.mybatisplus.demo.config;

import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;

/**
 * @author Goldchen
 * @create 2022-11-09 0:30
 */
@Slf4j
@Component
public class MyBatisPlusMetaObjectHandler implements MetaObjectHandler {
    /**
     * 插入时的填充策略
     */
    @Override
    public void insertFill(MetaObject metaObject) {
        log.info("start insert fill ....");
        //strictInsertFill(MetaObject metaObject, String fieldName, Class<T> fieldType, E fieldVal)
        // 起始版本 3.3.0(推荐使用)
        this.strictInsertFill(metaObject, "createdTime", LocalDateTime.class, LocalDateTime.now());
        this.strictInsertFill(metaObject, "updatedTime", LocalDateTime.class, LocalDateTime.now());
    }

    /**
     * 更新时的填充策略
     *
     * @param metaObject
     */
    @Override
    public void updateFill(MetaObject metaObject) {
        log.info("start update fill ....");
        // 起始版本 3.3.0(推荐)
        this.strictUpdateFill(metaObject, "updatedTime", LocalDateTime.class, LocalDateTime.now());
    }
}

  1. 实体字段使用
    /**
     * 创建时间
     * 注解填充字段 @TableField(.. fill = FieldFill.INSERT) 生成器策略部分也可以配置!
     */
    @TableField(fill = FieldFill.INSERT)
    private LocalDateTime createdTime;

    /**
     * 更新时间
     */
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private LocalDateTime updatedTime;

七、逻辑删除

  1. 步骤一,配置,我使用的是3.5.5版本,只需要步骤一的全局配置就可以了。
mybatis-plus:
  global-config:
    db-config:
      logic-delete-field: flag # 全局逻辑删除的实体字段名(since 3.3.0,配置后可以忽略不配置步骤2)
      logic-delete-value: 1 # 逻辑已删除值(默认为 1)
      logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)
  1. 步骤二,此步骤可以省去,可以省去@TableLogic注解
    /**
     * 逻辑删除,当然,如果不需要逻辑删除,去掉此deleted字段即可
     */
    @TableLogic
    private Integer deleted;

八、分页

配置分页拦截器

        // 添加分页插件
        mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
    /**
     * 分页查询所有数据:请求示意
     * http://localhost:8080/member?current=1&size=111
     *
     * @param page   分页对象 current: 当前页; size:每页数量
     * @param member 查询实体
     * @return 所有数据
     */
    @GetMapping
    public ResponseEntity selectAll(Page<Member> page, Member member) {
                Page<Member> memberPage = new Page<>();
        memberPage.setCurrent(1);
        memberPage.setSize(5);
        // 分页结果会到memberPage和page对象中
        Page<Member> page = memberService.page(memberPage);
        memberPage.getRecords().forEach(System.out::println);
        page.getRecords().forEach(System.out::println);

        //page的其他方法
        System.out.println("当前页:" + page.getCurrent());
        System.out.println("总页数:" + page.getPages());
        System.out.println("记录数:" + page.getTotal());
        System.out.println("是否有上一页:" + page.hasPrevious());
        System.out.println("是否有下一页:" + page.hasNext());
        
        return new ResponseEntity<>(this.memberService.page(page, new QueryWrapper<>(member)), HttpStatus.OK);
    }

九、增删改查

package space.goldchen.mybatisplus.demo.controller;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.*;
import space.goldchen.mybatisplus.demo.domain.Member;
import space.goldchen.mybatisplus.demo.service.MemberService;

import javax.annotation.Resource;
import java.io.Serializable;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

/**
 * 会员(Member)表控制层
 *
 * @author makejava
 * @since 2022-11-08 23:05:37
 */
@RestController
@RequestMapping("member")
public class MemberController {
    /**
     * 服务对象
     */
    @Resource
    private MemberService memberService;

    /**
     * 分页查询所有数据
     * http://localhost:8080/member?current=1&size=111
     *
     * @param page   分页对象 current: 当前页; size:每页数量
     * @param member 查询实体
     * @return 所有数据
     */
    @GetMapping
    public ResponseEntity selectAll(Page<Member> page, Member member) {
        return new ResponseEntity<>(this.memberService.page(page, new QueryWrapper<>(member)), HttpStatus.OK);
    }

    /**
     * 通过主键查询单条数据
     *
     * @param id 主键
     * @return 单条数据
     */
    @GetMapping("{id}")
    public ResponseEntity selectOne(@PathVariable Serializable id) {
        return new ResponseEntity<>(this.memberService.getById(id), HttpStatus.OK);
    }

    /**
     * 新增数据
     *
     * @param member 实体对象
     * @return 新增结果
     */
    @PostMapping
    public ResponseEntity insert(@RequestBody Member member) {
        return new ResponseEntity<>(this.memberService.save(member), HttpStatus.OK);
    }

    /**
     * 修改数据
     *
     * @param member 实体对象
     * @return 修改结果
     */
    @PutMapping
    public ResponseEntity update(@RequestBody Member member) {
        return new ResponseEntity<>(this.memberService.updateById(member), HttpStatus.OK);
    }

    /**
     * 删除数据
     *
     * @param idList 主键结合
     * @return 删除结果
     */
    @DeleteMapping
    public ResponseEntity delete(@RequestParam("idList") List<Long> idList) {
        return new ResponseEntity<>(this.memberService.removeByIds(idList), HttpStatus.OK);
    }

    /**
     * 增删改查Demo
     */
    @GetMapping("/crud")
    public void testCRUD() {
        Member params = new Member();
        params.setName("新增");
        boolean save = memberService.save(params);
        Assert.isTrue(save, "新增成功");

        //params.setId(1L);
        //boolean b = memberService.removeById(params);
        //Assert.isTrue(b,"删除成功");

        params.setId(2L);
        params.setName("New 姓名");
        boolean b1 = memberService.updateById(params);
        Assert.isTrue(b1, "修改成功");

        Member params2 = new Member();
        params2.setName("陈");
        List<Member> memberList = memberService.list(new QueryWrapper<Member>().like("name", params2.getName()));
        Assert.notNull(memberList, "查询成功");

        List<Member> membersListBatch = memberService.listByIds(Arrays.asList(1, 2, 3));
        Assert.notNull(membersListBatch, "批量查询成功");

        Page<Member> memberPage = new Page<>();
        memberPage.setCurrent(1);
        memberPage.setSize(5);
        // 分页结果会到memberPage和page对象中
        Page<Member> page = memberService.page(memberPage);
        memberPage.getRecords().forEach(System.out::println);
        page.getRecords().forEach(System.out::println);

        //page的其他方法
        System.out.println("当前页:" + page.getCurrent());
        System.out.println("总页数:" + page.getPages());
        System.out.println("记录数:" + page.getTotal());
        System.out.println("是否有上一页:" + page.hasPrevious());
        System.out.println("是否有下一页:" + page.hasNext());


        // 条件查询
        //1. 查询name不为空且ID大于等于20的会员
        QueryWrapper<Member> wrapper = new QueryWrapper<>();
        wrapper.isNotNull("name").ge("id", 20);
        List<Member> list = memberService.list(wrapper);
        list.forEach(System.out::println);

        //2 查询name=陈2的会员
        QueryWrapper<Member> wrapper1 = new QueryWrapper<>();
        wrapper1.eq("name","陈2");
        Member one = memberService.getOne(wrapper1, false);
        System.out.println(one);

        //3 查询ID在1-10之间
        QueryWrapper<Member> wrapper2 = new QueryWrapper<>();
        wrapper2.between("id",1,10);
        List<Member> list1 = memberService.list(wrapper2);
        list1.forEach(System.out::println);

        //4 查询ID在1-10之间的 记录条数
        long count = memberService.count(wrapper2);
        System.out.println(count);

        //5 模糊查询
        QueryWrapper<Member> wrapper3 = new QueryWrapper<>();
        wrapper3.notLike("name","陈");
        wrapper3.like("id",1);
        List<Member> list2 = memberService.list(wrapper3);
        list2.forEach(System.out::println);

        //6 连表IN查询 :SELECT * FROM member WHERE deleted=0 AND (id IN (select id from member where id < 10))
        QueryWrapper<Member> wrapper4 = new QueryWrapper<>();
        wrapper4.inSql("id","select id from member where id < 10");
        List<Object> objects = memberService.listObjs(wrapper4);
        objects.forEach(System.out::println);

        //7 通过ID排序 SELECT * FROM member WHERE deleted=0 ORDER BY id DESC
        QueryWrapper<Member> wrapper5 = new QueryWrapper<>();
        wrapper5.orderByDesc("id");
        List<Map<String, Object>> maps = memberService.listMaps(wrapper5);
        maps.forEach(System.out::println);
    }
}

十、性能分析插件

  1. 引入maven坐标
<dependency>
    <groupId>p6spy</groupId>
    <artifactId>p6spy</artifactId>
    <version>3.9.1</version>
</dependency>
  1. spy.properties
### sql耗时打印:该插件有性能损耗,不建议生产环境使用。 ###
#3.2.1以上使用
modulelist=com.baomidou.mybatisplus.extension.p6spy.MybatisPlusLogFactory,com.p6spy.engine.outage.P6OutageFactory
#3.2.1以下使用或者不配置
#modulelist=com.p6spy.engine.logging.P6LogFactory,com.p6spy.engine.outage.P6OutageFactory
# 自定义日志打印
logMessageFormat=com.baomidou.mybatisplus.extension.p6spy.P6SpyLogger
#日志输出到控制台
appender=com.baomidou.mybatisplus.extension.p6spy.StdoutLogger
# 使用日志系统记录 sql
#appender=com.p6spy.engine.spy.appender.Slf4JLogger
# 设置 p6spy driver 代理
deregisterdrivers=true
# 取消JDBC URL前缀
useprefix=true
# 配置记录 Log 例外,可去掉的结果集有error,info,batch,debug,statement,commit,rollback,result,resultset.
excludecategories=info,debug,result,commit,resultset
# 日期格式
dateformat=yyyy-MM-dd HH:mm:ss
# 实际驱动可多个
#driverlist=org.h2.Driver
# 是否开启慢SQL记录
outagedetection=true
# 慢SQL记录标准 2 秒
outagedetectioninterval=1
  1. yml配置文件,更换数据库连接驱动

    当不需要打印时,就注释掉驱动和url,更换为之前正常的mysql的

# DataSource Config mysql
spring:
  datasource:
    username: root
    password: root
#    driver-class-name: com.mysql.cj.jdbc.Driver
#    url: jdbc:mysql://localhost/mybatis_plus?userUnicode=true&characterEncoding=utf-8&serverTimezone=UTC
    ###慢sql记录日志,会影响性能,生产勿用 ###
    driver-class-name: com.p6spy.engine.spy.P6SpyDriver
    url: jdbc:p6spy:mysql://localhost/mybatis_plus?userUnicode=true&characterEncoding=utf-8&serverTimezone=UTC

​ 配置完成了,

  1. 打印效果:会打印时间和sql,超过2秒,程序就会报错了,
 Consume Time7 ms 2022-11-10 09:10:40
 Execute SQLSELECT COUNT(*) AS total FROM member WHERE deleted = 0
 
 Consume Time0 ms 2022-11-10 09:10:40
 Execute SQLSELECT id,name,version,deleted,created_time,updated_time FROM member WHERE deleted=0 LIMIT 500

十一、数据安全保护

这个用在部署或发行的时候,会比较实用

  1. 获取随机key和加密账号密码
package space.goldchen.mybatisplus.demo.utils;

import com.baomidou.mybatisplus.core.toolkit.AES;
import org.apache.tomcat.Jar;

/**
 * @author Goldchen
 * @create 2022-11-10 11:35
 */
public class MybatisPlusUtil {
    /**
     * 数据库账号密码连接加密
     * 加密配置 mpw: 开头紧接加密内容( 非数据库配置专用 YML 中其它配置也是可以使用的 )
     * 使用:
     * Jar 启动参数( idea 设置 Program arguments , 服务器可以设置为启动环境变量 )
     * --mpw.key=d1104d7c3b616f0b
     * *
     * * 举例:
     * * datasource:
     * * url: mpw:qRhvCwF4GOqjessEB3G+a5okP+uXXr96wcucn2Pev6Bf1oEMZ1gVpPPhdDmjQqoM
     * * password: mpw:Hzy5iliJbwDHhjLs1L0j6w==
     * * username: mpw:Xb+EgsyuYRXw7U7sBJjBpA==
     */
    public static void main(String[] args) {
        // 配置生成的randomKey: Jar 启动参数( idea 设置 Program arguments , 服务器可以设置为启动环境变量 )
        String randomKey = AES.generateRandomKey();
        System.out.println(randomKey);
        String data = "root";
        String result = AES.encrypt(data, randomKey);
        // l/Lda+gQDhgSVp+yiPwxKg==
        System.out.println(result);
        // 使用前边加mpw:
        // root
        // mpw:acac306d8b444138
        // mpw:R+UhjA9/vpn8Dc8cOli2lA==
    }
}

  1. 配置到yml
# DataSource Config mysql
spring:
  datasource:
    username: mpw:R+UhjA9/vpn8Dc8cOli2lA==
    password: mpw:R+UhjA9/vpn8Dc8cOli2lA==
    # key: acac306d8b444138
#    driver-class-name: com.mysql.cj.jdbc.Driver
#    url: jdbc:mysql://localhost/mybatis_plus?userUnicode=true&characterEncoding=utf-8&serverTimezone=UTC
    ###慢sql记录日志,会影响性能,生产勿用 ###
    driver-class-name: com.p6spy.engine.spy.P6SpyDriver
    url: jdbc:p6spy:mysql://localhost/mybatis_plus?userUnicode=true&characterEncoding=utf-8&serverTimezone=UTC

  1. 项目启动配置参数
#Jar 启动参数( idea 设置 Program arguments , 服务器可以设置为启动环境变量 )
java -jar xxx.jar --mpw.key=d1104d7c3b616f0b

十二、多数据源

  1. 添加依赖
<!-- 多数据源-->
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>dynamic-datasource-spring-boot-starter</artifactId>
    <version>2.5.8</version>
</dependency>
  1. 配置多数据源
## 多数据源配置
spring:
  datasource:
    dynamic:
      primary: master #设置默认的数据源或者数据源组,默认值即为master
      strict: false #严格匹配数据源,默认false. true未匹配到指定数据源时抛异常,false使用默认数据源
      datasource:
        master:
          username: mpw:R+UhjA9/vpn8Dc8cOli2lA==
          password: mpw:R+UhjA9/vpn8Dc8cOli2lA==
          driver-class-name: com.mysql.cj.jdbc.Driver
          url: jdbc:mysql://localhost/mybatis_plus?userUnicode=true&characterEncoding=utf-8&serverTimezone=UTC
        slave_1:
          username: mpw:R+UhjA9/vpn8Dc8cOli2lA==
          password: mpw:R+UhjA9/vpn8Dc8cOli2lA==
          driver-class-name: com.mysql.cj.jdbc.Driver
          url: jdbc:mysql://localhost/mybatis_plus?userUnicode=true&characterEncoding=utf-8&serverTimezone=UTC

  1. 注解使用,类上或方法上
package space.goldchen.mybatisplus.demo.service.impl;

import com.baomidou.dynamic.datasource.annotation.DS;
import space.goldchen.mybatisplus.demo.domain.Member;
import space.goldchen.mybatisplus.demo.mapper.MemberMapper;
import space.goldchen.mybatisplus.demo.service.MemberService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;

/**
 * <p>
 * 会员 服务实现类
 * </p>
 *
 * @author author123
 * @since 2022-11-08
 */
@Service
@DS("slave_1")
public class MemberServiceImpl extends ServiceImpl<MemberMapper, Member> implements MemberService {

}

The End

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Goldchenn

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值