Spring Boot系列三 MyBatis-Plus集成

目录

  • Mybatis-Plus介绍
  • Mybatis 和 Mybatis-Plus 区别
  • Spring Boot与MyBatis-Plus集成

运行环境:JDK 8,Maven 3.0+

技术栈:SpringBoot 2.5+

一、Mybatis Plus 介绍

MyBatis-Plus (opens new window)(简称 MP)是一个 MyBatis (opens new window)的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。

愿景:

我们的愿景是成为 MyBatis 最好的搭档,就像 魂斗罗 中的 1P2P,基友搭配,效率翻倍。

特性:

  • 无侵入:只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑
  • 损耗小:启动即会自动注入基本 CURD,性能基本无损耗,直接面向对象操作
  • 强大的 CRUD 操作:内置通用 Mapper、通用 Service,仅仅通过少量配置即可实现单表大部分 CRUD 操作,更有强大的条件构造器,满足各类使用需求
  • 支持 Lambda 形式调用:通过 Lambda 表达式,方便的编写各类查询条件,无需再担心字段写错
  • 支持主键自动生成:支持多达 4 种主键策略(内含分布式唯一 ID 生成器 - Sequence),可自由配置,完美解决主键问题
  • 支持 ActiveRecord 模式:支持 ActiveRecord 形式调用,实体类只需继承 Model 类即可进行强大的 CRUD 操作
  • 支持自定义全局通用操作:支持全局通用方法注入( Write once, use anywhere )
  • 内置代码生成器:采用代码或者 Maven 插件可快速生成 Mapper 、 Model 、 Service 、 Controller 层代码,支持模板引擎,更有超多自定义配置等您来使用
  • 内置分页插件:基于 MyBatis 物理分页,开发者无需关心具体操作,配置好插件之后,写分页等同于普通 List 查询
  • 分页插件支持多种数据库:支持 MySQL、MariaDB、Oracle、DB2、H2、HSQL、SQLite、Postgre、SQLServer 等多种数据库
  • 内置性能分析插件:可输出 SQL 语句以及其执行时间,建议开发测试时启用该功能,能快速揪出慢查询
  • 内置全局拦截插件:提供全表 delete 、 update 操作智能分析阻断,也可自定义拦截规则,预防误操作

支持数据库:

任何能使用 MyBatis 进行 CRUD, 并且支持标准 SQL 的数据库,具体支持情况如下,

MySQLOracleDB2H2HSQLSQLitePostgreSQLSQLServerPhoenixGauss ClickHouseSybaseOceanBaseFirebirdCubridGoldilockscsiidbinformixTDengineredshift达梦数据库,虚谷数据库,人大金仓数据库,南大通用(华库)数据库,南大通用数据库,神通数据库,瀚高数据库,优炫数据库

框架结构:

二、Mybatis和Mybatis-Plus区别

MyBatis:

  1. 所有SQL语句全部自己写
  2. 手动解析实体关系映射转换为MyBatis内部对象注入容器
  3. 不支持Lambda形式调用

Mybatis Plus:

  1. 强大的条件构造器,满足各类使用需求
  2. 内置的Mapper,通用的Service,少量配置即可实现单表大部分CRUD操作
  3. 支持Lambda形式调用
  4. 提供了基本的CRUD功能,SQL语句都不需要编写
  5. 自动解析实体关系映射转换为MyBatis内部对象注入容器

三、Spring Boot与MyBatis-Plus集成

数据库及表创建

  • 数据库创建:

create database  sopbase;

  • 表创建:
create table  sys_user

(

    user_id     bigint auto_increment

        primary key,

    username    varchar(50not null comment '用户名',

    password    varchar(100) null comment '密码',

    salt        varchar(20null comment '盐',

    email       varchar(100) null comment '邮箱',

    mobile      varchar(100) null comment '手机号',

    status      tinyint      null comment '状态  0:禁用   1:正常',

    dept_id     bigint       null comment '部门ID',

    create_time datetime     null comment '创建时间',

    constraint username

        unique (username)

)

    comment '系统用户' charset = utf8mb4;

项目工程结构及源码介绍

项目工程结构

核心源码介绍

  1. controller
/**

 * 系统用户

 *

 * @author lxj

 */

@RestController

@RequestMapping("user")

public class UserController {

    @Autowired

    private UserService userService;



    /**

     * 用户信息列表

     */

    @GetMapping("/list")

    public R list(@RequestParam Map<String, Object> params){

        PageUtils page = userService.queryPage(params);

        return R.ok().put("page", page);

    }



    /**

     * 查询用户信息

     */

    @GetMapping("/info/{userId}")

    public R info(@PathVariable("userId") Long userId){

        User user = userService.getUserById(userId);

        return R.ok().put("user", user);

    }



    /**

     * 保存用户信息

     */

    @PostMapping("/save")

    public R save(@RequestBody User user){

        userService.stroe(user);

        return R.ok();

    }



    /**

     * 修改用户信息

     */

    @PostMapping("/update")

    public R update(@RequestBody User user){

        userService.update(user);

        return R.ok();

    }



    /**

     * 删除用户

     */

    @PostMapping("/delete")

    public R delete(@RequestBody Long[] userIds){

        userService.removeByIds(Arrays.asList(userIds));

        return R.ok();

    }



}

2.dao 数据操作层 DAO

@Mapper

//表明这是一个Mapper,也可以在启动类上加上包扫描

//Mapper 继承该接口后,无需编写 mapper.xml 文件,即可获得CRUD功能

public interface UserMapper extends BaseMapper<User> {



}

3.entity 实体类

@Data

@TableName(value = "sys_user")

@ApiModel(description = "用户信息")

public class User implements Serializable {

    private static final long serialVersionUID = -5644799954031156649L;



    //value与数据库主键列名一致,若实体类属性名与表主键列名一致可省略value

    @TableId(value = "user_id", type = IdType.AUTO)//指定自增策略

    @ApiModelProperty(value = "用户ID",required=true)

    private Long userId;

    /**

     * 用户名

     */

    @ApiModelProperty(value = "用户名",required=true)

    private String username;

    /**

     * 密码

     */

    @ApiModelProperty(value = "用户密码",required=true)

    private String password;

    /**

     * 盐

     */

    private String salt;

    /**

     * 邮箱

     */

    @ApiModelProperty(value = "用户邮箱",required=true)

    private String email;

    /**

     * 手机号

     */

    private String mobile;

    /**

     * 状态  0:禁用   1:正常

     */

    private Integer status;

    /**

     * 部门ID

     */

    private Long deptId;



    /**

     * 部门名称

     */

    @TableField(exist=false)

    private String deptName;



    /**

     * 角色ID列表

     */

    @TableField(exist=false)

    private List<Long> roleIdList;



    /**

     * 创建时间

     */

    @TableField(fill= FieldFill.INSERT_UPDATE)

    private Date createTime;



}

4.service 业务逻辑层

接口类:

public interface UserService extends IService<User> {

    /**

     * 分页查询

     * @param params

     * @return

     */

    PageUtils queryPage(Map<String, Object> params);



    /**

     * 根据姓名查询

     * @param name

     * @return

     */

    User queryByName(String name);



    boolean stroe(User user);



    void update(User user);



    User getUserById(Long userId);





}

实现类:

@Service("userService")

public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {



    @Override

    public PageUtils queryPage(Map<String, Object> params) {

        String name = (String)params.get("username");

        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();

        userQueryWrapper.like(StringUtils.isNotEmpty(name),"username",name);

        Query<User> query = new Query<>();

        IPage<User> page= this.page(query.getPage(params),userQueryWrapper);

        return  new PageUtils(page);

    }



    @Override

    public User queryByName(String name) {

        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();

        userQueryWrapper.eq("username",name);

        return this.getOne(userQueryWrapper);

    }



    @Override

    @Transactional(rollbackFor = Exception.class)

    public boolean stroe(User user) {

        String salt =  RandomStringUtils.randomAlphanumeric(20);

        String pwd = user.getPassword()+salt;

        user.setSalt(salt);

        user.setPassword(DigestUtils.md5Hex(pwd));

        this.save(user);

        return true;

    }



    @Override

    @Transactional(rollbackFor = Exception.class)

    public void update(User user) {

        if(org.apache.commons.lang.StringUtils.isBlank(user.getPassword())){

            user.setPassword(null);

        }else{

            String salt =  RandomStringUtils.randomAlphanumeric(20);

            String pwd = user.getPassword()+salt;

            user.setSalt(salt);

            user.setPassword(DigestUtils.md5Hex(pwd));

        }

        this.updateById(user);



    }



    @Override

    public User getUserById(Long userId) {

        User user = this.getById(userId);

        return user;

    }

}

5.Application 应用启动类

/**

 * 启动类

 *

 * @author lxj

 */

@SpringBootApplication

public class LearnMybatisApplication {

    public static void main(String[] args) {

        SpringApplication.run(LearnMybatisApplication.class, args);

    }

}
  1. Mapper配置
<?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="com.learn.springboot.dao.UserMapper">



   <!-- 可根据自己的需求,是否要使用 -->

    <resultMap type="com.learn.springboot.entity.User" id="userMap">

        <result property="userId" column="user_id"/>

        <result property="username" column="username"/>

        <result property="password" column="password"/>

        <result property="salt" column="salt"/>

        <result property="email" column="email"/>

        <result property="mobile" column="mobile"/>

        <result property="status" column="status"/>

        <result property="deptId" column="dept_id"/>

        <result property="createTime" column="create_time"/>

    </resultMap>



</mapper>

6.application.yml 应用配置文件,应用启动会自动读取配置

server:

  port: 80

  servlet:

    context-path: /



  tomcat:

    # tomcat的URI编码

    uri-encoding: UTF-8

    # tomcat最大线程数,默认为200

    max-threads: 800

    # Tomcat启动初始化的线程数,默认值25

    min-spare-threads: 30



spring:

  datasource:

    type: com.alibaba.druid.pool.DruidDataSource

    druid:

      driver-class-name: com.mysql.cj.jdbc.Driver

      username: sopbase

      password: sopbase

      url: jdbc:mysql://localhost:3306/sopbase?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=UTC

      initial-size: 10   #连接池初始大小

      max-active: 100   #连接池中最大的活跃连接数

      min-idle: 10   #连接池中最小的活跃连接数

      max-wait: 60000  #配置获取连接等待超时的时间

      pool-prepared-statements: true   #打开PSCache,并且指定每个连接上PSCache的大小

      max-pool-prepared-statement-per-connection-size: 20

      time-between-eviction-runs-millis: 60000

      min-evictable-idle-time-millis: 300000

      #Oracle需要打开注释

      #validation-query: SELECT 1 FROM DUAL

      test-while-idle: true   #是否在连接空闲一段时间后检测其可用性

      test-on-borrow: false   #是否在获得连接后检测其可用性

      test-on-return: false   #是否在连接放回连接池后检测其可用性

      stat-view-servlet:

        enabled: true

        url-pattern: /druid/*

        #login-username: admin

        #login-password: admin

      filter:

        stat:

          log-slow-sql: true

          slow-sql-millis: 1000

          merge-sql: false

        wall:

          config:

            multi-statement-allow: true



#mybatis

mybatis-plus:

  mapper-locations: classpath*:/mapper/**/*.xml

  #实体扫描,多个package用逗号或者分号分隔 com.example.*.entity

  typeAliasesPackage: com.learn.springboot.entity

  global-config:

    #数据库相关配置

    db-config:

      #主键类型  AUTO:"数据库ID自增", INPUT:"用户输入ID", ID_WORKER:"全局唯一ID (数字类型唯一ID)", UUID:"全局唯一ID UUID";

      id-type: AUTO

      logic-delete-value: -1

      logic-not-delete-value: 0

    banner: false

  #原生配置

  configuration:

    #开启sql日志

    #log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

    log-impl: org.apache.ibatis.logging.slf4j.Slf4jImpl

    #log-impl: org.apache.ibatis.logging.log4j2.Log4j2Impl

    # 该配置就是将带有下划线的表字段映射为驼峰格式的实体类属性

    map-underscore-to-camel-case: true

    cache-enabled: false

    call-setters-on-nulls: true

    jdbc-type-for-null: 'null'

项目配置说明

  1. 项目pom.xml添加mybatis-plus依赖
<dependency>

    <groupId>com.baomidou</groupId>

    <artifactId>mybatis-plus-boot-starter</artifactId>

    <version>${mybatisplus.version}</version>

</dependency>

2.application.yml数据源配置

3.application.ymlMybatis-plus配置

4.加载Mybatis配置

MapperScan 注解加载扫描持久层包路径,来增加配置。该配置也可以加在工程application启动类。无自定配置,只需通过持久层接口加@Mapper注解,可不引用@MapperScan注解。
/**

 * MybatisPlus插件加载

 *

 * @author lxj

 */

@Configuration

@MapperScan("com.learn.springboot.dao")

public class MybatisPlusConfig {



    /**

     * 新的分页插件

     */

    @Bean

    public MybatisPlusInterceptor mybatisPlusInterceptor() {

        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();

        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));

        return interceptor;

    }

}
 
数据表字段自动填充实现
/**

 * 定义写数据入库默认值

 *

 * @author lxj

 */

@Component

public class CTMetaObjectHandler implements MetaObjectHandler {

    @Override

    public void insertFill(MetaObject metaObject) {

        this.setFieldValByName("createTime",new Date(),metaObject);

    }



    @Override

    public void updateFill(MetaObject metaObject) {

      //自定元数据处理逻辑

    }

}

工程演示

1.右键运行 Application 应用启动类的 main 函数,然后在浏览器访问:

http://127.0.0.1/user/list

2.可以看到返回的是JSON结果

{"msg":"success","code":0,"page":{"totalCount":3,"pageSize":10,"totalPage":1,"currPage":1,"list":[{"userId":1,"username":"admin","pass*word":"417edea33a741473996ef2329b47d646","salt":"JjZ042ziJvEkQIrbdAq1","email":"12345678@sop.com","mobile":"13899990000","status":1,"deptId":1,"deptName":null,"roleIdList":null,"createTime":"2022-04-22T11:11:11.000+00:00"},{"userId":2,"username":"ct001","pass*word":"9038970c5c35c93cd49dd129d89ac414","salt":"JgStBJenBWBHgspepy0g","email":"123123@qq.com","mobile":"13899998888","status":1,"deptId":null,"deptName":null,"roleIdList":null,"createTime":null},{"userId":3,"username":"ct002","pass*word":"f37904c75832a4028850ebb7a4d042d7","salt":"tdsMJD0xJhz2rLsZ3X2A","email":"123123@qq.com","mobile":"13899998888","status":1,"deptId":null,"deptName":null,"roleIdList":null,"createTime":"2023-01-16T11:30:15.000+00:00"}]}}​​​​​​​

需要工程源码,可以留言,私发。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值