SpringBoot集成MyBatis-Plus框架详细方法

一、MyBatis

MyBatis前身是iBatis,是Clinton Begin在2001年发起的一个开源项目。最初侧重于码软件开发,后续发展成为一款基于java的持久层框架。Mybatis是一款优秀的持久层框架支持自定义SQL查询、存储过程和高级映射,消除了几乎所有的JDBC代码和参数的手动设置以及结果集的检索。MyBatis可以使用简单的XML或者注解进行映射和配置,通过将参数映射到配置的SQL最终解析为执行的SQL语句,查询后将SQl结果集映射成java对象返回。MyBatis提供的持久层框架包括SQL Maps(Mapper)和Data Access Objects(DAO),相对于Hibernate而言它提供的是一种把自动化的ORM实现。MyBatis中一级缓存会默认启用(本地缓存)且不受控制,一般说缓存时指的是MyBatis的二级缓存

主要使用的标签有:

1)、<select></select>对应注解@lSelect

2)、<update></update>对应注解@Update

3)、<insert></insert>对应注解@Insert

4)、<delete></delete>对应注解@Delete

5)、<where></where>:在某些条件根据入参有无决定是可使用以避免1=1这种写法,也会根据是否为where条件后第一个条件参数自动去除and

6)、<if></if>:类似于java中的条件判断if,没有<else>标签

7)、<choose>标签

<choose>

    <when></when>

    <otherwise></otherwise>

</choose>

8)、<foreach></forwach>:可以对数组、Map或实现了Iterable接口(如List、Set)的对象遍历。可实现in、批量更新、批量插入等。

9)、<resultMap></resultMap>:映射结果集

10)、<resultType></resultType>:映射结果类型,可是java实体类或Map、List等类型。

优点:

1)MyBatis封装了JBDC底层访问数据库的细节,使我们程序猿不需要与JDBC API打交道,就可以访问数据库。
2)MyBatis简单易学,程序猿直接编写SQL语句,适合于对SQL语句性能要求比较高的项目。
3)SQL语句封装在配置文件中,便于统一管理与维护,降低了程序的耦合度。
4)SQL代码从程序代码中彻底分离出来,可重用。
5)提供了动态SQL标签,支持编写动态SQL。
6)提供映射标签,支持对象与数据库的ORM字段关系映射。

缺点:

1)过于依赖数据库SQL语句,导致数据库移植性差,更换数据库,如果SQL语句有差异,SQL语句工作量大。
2)由于xml里标签id必须唯一,导致DAO中方法不支持方法重载。
3)字段映射标签和对象关系映射标签仅仅是对映射关系的描述,具体实现仍然依赖于sql。(比如配置了一对多Collection标签,如果sql里没有join子表或查询子表的话,查询后返回的对象是不具备对象关系的,即Collection的对象为null)
4)DAO层过于简单,对象组装的工作量较大。
5)不支持级联更新、级联删除。
6)编写动态sql时,不方便调试,尤其逻辑复杂时。
7)提供的写动态sql的xml标签功能简单(连struts都比不上),编写动态sql仍然受限,且可读性低。
8)使用不当,容易导致N+1的sql性能问题。
9)使用不当,关联查询时容易产生分页bug。
10)若不查询主键字段,容易造成查询出的对象有“覆盖”现象。
11)参数的数据类型支持不完善。(如参数为Date类型时,容易报没有get、set方法,需在参数上加@param)
12)多参数时,使用不方便,功能不够强大。(目前支持的方法有map、对象、注解@param以及默认采用012索引位的方式)
13)缓存使用不当,容易产生脏数据。

二、MyBatis-plus

MyBatis-plus是一款MyBatis的增强工具,在MyBatis 的基础上只做增强不做改变。其是国内团队苞米豆在MyBatis基础上开发的增强框架,扩展了一些功能,以提高效率。引入 Mybatis-Plus 不会对现有的 Mybatis 构架产生任何影响,而且 MyBatis-plus 支持所有 Mybatis 原生的特性

优点:

1)依赖少:仅仅依赖 Mybatis 以及 Mybatis-Spring 。

2)损耗小:启动即会自动注入基本 CURD,性能基本无损耗,直接面向对象操作 。

3)预防Sql注入:内置 Sql 注入剥离器,有效预防Sql注入攻击 。

4)通用CRUD操作:内置通用 Mapper、通用 Service,仅仅通过少量配置即可实现单表大部分 CRUD 操作,更有强大的条件构造器,满足各类使用需求 。

5)多种主键策略:支持多达4种主键策略(内含分布式唯一ID生成器),可自由配置,完美解决主键问题 。

6)支持热加载:Mapper 对应的 XML 支持热加载,对于简单的 CRUD 操作,甚至可以无 XML 启动

7)支持ActiveRecord:支持 ActiveRecord 形式调用,实体类只需继承 Model 类即可实现基本 CRUD 操作

8)支持代码生成:采用代码或者 Maven 插件可快速生成 Mapper 、 Model 、 Service 、 Controller 层代码(生成自定义文件,避免开发重复代码),支持模板引擎、有超多自定义配置等。

9)支持自定义全局通用操作:支持全局通用方法注入( Write once, use anywhere )。

10)支持关键词自动转义:支持数据库关键词(order、key…)自动转义,还可自定义关键词 。

11)内置分页插件:基于 Mybatis 物理分页,开发者无需关心具体操作,配置好插件之后,写分页等同于普通List查询。

12)内置性能分析插件:可输出 Sql 语句以及其执行时间,建议开发测试时启用该功能,能有效解决慢查询 。

13)内置全局拦截插件:提供全表 delete 、 update 操作智能分析阻断,预防误操作。

14)默认将实体类的类名查找数据库中的表,使用@TableName(value="table1")注解指定表名,@TableId指定表主键,若字段与表中字段名保持一致可不加注解。

三、二者区别

MyBatis:

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

Mybatis Plus:

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

总结:

Mybatis Plus的宗旨是简化开发,但是它在提供方便的同时却容易造成代码层次混乱,我们可能会把大量数据逻辑写到service层甚至contoller层中,使代码难以阅读。凡事过犹不及,在使用Mybatis Plus时一定要做分析,不要将所有数据操作都交给Mybatis Plus去实现。毕竟Mybatis Plus只是Mybatis的增强工具,它并没有侵入Mybatis的原生功能,在使用Mybatis Plus的增强功能的同时,原生Mybatis的功能依然是可以正常使用的。

-------------------------------------

一、MyBatis Plus 介绍

MyBatis Plus 是国内人员开发的 MyBatis 增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。

MyBatis Plus 的核心功能有:支持通用的 CRUD、代码生成器与条件构造器。

通用 CRUD:定义好 Mapper 接口后,只需要继承 BaseMapper<T> 接口即可获得通用的增删改查功能,无需编写任何接口方法与配置文件条件构造器:通过 EntityWrapper<T> (实体包装类),可以用于拼接 SQL 语句,并且支持排序、分组查询等复杂的 SQL代码生成器:支持一系列的策略配置与全局配置,比 MyBatis 的代码生成更好用

BaseMapper<T> 接口中通用的 CRUD 方法:

这里写图片描述

二、MyBatis Plus 集成 Spring

数据表结构

1
2
3
4
5
6
7
8
9
DROP TABLE IF EXISTS `tbl_employee`;
CREATE TABLE `tbl_employee` (
 `id` int(11) NOT NULL AUTO_INCREMENT,
 `last_name` varchar(50) DEFAULT NULL,
 `email` varchar(50) DEFAULT NULL,
 `gender` char(1) DEFAULT NULL,
 `age` int(11) DEFAULT NULL,
 PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8;

 

pom 文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
<dependencies>
<!-- MP -->
<dependency>
 <groupId>com.baomidou</groupId>
 <artifactId>mybatis-plus</artifactId>
 <version>2.3</version>
</dependency>
<!-- 测试 -->
<dependency>
 <groupId>junit</groupId>
 <artifactId>junit</artifactId>
 <version>4.12</version>
</dependency>
<!-- 数据源 -->
<dependency>
 <groupId>com.alibaba</groupId>
 <artifactId>druid</artifactId>
 <version>1.1.10</version>
</dependency>
<!-- 数据库驱动 -->
<dependency>
 <groupId>mysql</groupId>
 <artifactId>mysql-connector-java</artifactId>
 <version>5.1.39</version>
</dependency>
<!-- Spring 相关 -->
<dependency>
 <groupId>org.springframework</groupId>
 <artifactId>spring-context</artifactId>
 <version>4.3.9.RELEASE</version>
</dependency>
<dependency>
 <groupId>org.springframework</groupId>
 <artifactId>spring-orm</artifactId>
 <version>4.3.9.RELEASE</version>
</dependency>
</dependencies>

 

MyBatis 全局配置文件 mybatis-config.xml

1
2
3
4
5
6
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
 PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
 "http://mybatis.org/dtd/mybatis-3-config.dtd">
<!-- 不作任何配置 -->
<configuration />

 

数据源 db.properties

1
2
3
jdbc.url=jdbc:mysql://localhost:3306/mp
jdbc.username=root
jdbc.password=1234

 

Spring 配置文件 applicationContext.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
<!-- 数据源 -->
 <context:property-placeholder location="classpath:db.properties"/>
 <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
 <property name="url" value="${jdbc.url}"></property>
 <property name="username" value="${jdbc.username}"></property>
 <property name="password" value="${jdbc.password}"></property>
 </bean>
 
 <!-- MP 提供的 MybatisSqlSessionFactoryBean -->
 <bean id="sqlSessionFactoryBean"
  class="com.baomidou.mybatisplus.spring.MybatisSqlSessionFactoryBean">
 <!-- 数据源 -->
 <property name="dataSource" ref="dataSource"></property>
 <!-- mybatis 全局配置文件 -->
 <property name="configLocation" value="classpath:mybatis-config.xml"></property>
 <!-- 别名处理 -->
 <property name="typeAliasesPackage" value="com.jas.bean"></property>
 <!-- 注入全局MP策略配置 -->
 <property name="globalConfig" ref="globalConfiguration"></property>
 <!-- 插件注册 -->
 <property name="plugins">
  <list>
  <!-- 注册分页插件 -->
  <bean class="com.baomidou.mybatisplus.plugins.PaginationInterceptor" />
  <!-- 注入 SQL 性能分析插件,建议在开发环境中使用,可以在控制台查看 SQL 执行日志 -->
  <bean class="com.baomidou.mybatisplus.plugins.PerformanceInterceptor">
   <property name="maxTime" value="1000" />
   <!--SQL 是否格式化 默认false-->
   <property name="format" value="true" />
  </bean>
  </list>
 </property>
 </bean>
 
 <!-- 定义 MybatisPlus 的全局策略配置-->
 <bean id ="globalConfiguration" class="com.baomidou.mybatisplus.entity.GlobalConfiguration">
 <!-- 在 2.3 版本以后,dbColumnUnderline 默认值是 true -->
 <property name="dbColumnUnderline" value="true"></property>
 <!-- 全局的主键策略 -->
 <property name="idType" value="0"></property>
 <!-- 全局的表前缀策略配置 -->
 <property name="tablePrefix" value="tbl_"></property>
 </bean>
  
 <!-- 配置mybatis 扫描mapper接口的路径 -->
 <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
 <property name="basePackage" value="com.jas.mapper"></property>
 </bean>

三、快速体验 MyBatis Plus

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
@TableName(value = "tbl_employee")
public class Employee {
 @TableId(value = "id", type = IdType.AUTO)
 private Integer id;
 @TableField(value = "last_name")
 private String lastName;
 private String email;
 private Integer gender;
 private Integer age;
  
 public Employee() {
 super();
 }
   
 public Employee(Integer id, String lastName, String email, Integer gender, Integer age) {
 this.id = id;
 this.lastName = lastName;
 this.email = email;
 this.gender = gender;
 this.age = age;
 }
 // 省略 set、get 与 toString() 方法

mapper 接口

1
2
3
4
/**
* 不定义任何接口方法
*/
public interface EmployeeMapper extends BaseMapper<Employee> {}

 

在测试类中生成测试的 mapper 对象

1
2
3
4
5
private ApplicationContext context =
  new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
   
 private EmployeeMapper employeeMapper =
  context.getBean("employeeMapper", EmployeeMapper.class);

 

简单查询测试

1
2
3
4
5
6
@Test
public void getEmpByIdTest() {
Employee employee = employeeMapper.selectById(1);
 
System.out.println(employee);
}

 

分页查询测试

1
2
3
4
5
6
7
8
9
@Test
public void getEmpByPage() {
Page<?> page = new Page<>(1, 5);
List<Employee> list = employeeMapper.selectPage(page, null);
 
System.out.println("总记录数:" + page.getTotal());
System.out.println("总页数" + page.getPages());
System.out.println(list);
}

 

条件构造器测试

1
2
3
4
5
6
7
8
9
10
11
@Test
 public void getEmpByName() {
 EntityWrapper<Employee> wrapper = new EntityWrapper<>();
  
 // 'last_name' 与 'age' 对应数据库中的字段
 wrapper.like("last_name", "张");
 wrapper.eq("age", 20);
  
 List<Employee> list = employeeMapper.selectList(wrapper);
 System.out.println(list);
 }
 

 

控制台输出的 SQL 分析日志

这里写图片描述

上面几个例子中,并没有在 EmployeeMapper 接口中定义任何方法,也没有在配置文件中编写 SQL 语句,而是通过继承 BaseMapper<T> 接口获得通用的的增删改查方法,复杂的 SQL 也可以使用条件构造器拼接。

通过这两种方式已经能够满足很多的开发需求了,不过复杂的业务需求还是要编写 SQL 语句的,流程和 MyBatis 一样。

Mybatis-plus之springboot用法详解

pom.xml配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
<dependencies>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter</artifactId>
    </dependency>
    <!--springboot程序测试依赖,如果是自动创建项目默认添加-->
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-test</artifactId>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>org.projectlombok</groupId>
      <artifactId>lombok</artifactId>
      <version>1.16.10</version>
      <scope>provided</scope>
    </dependency>
    <!-- 包含spirng Mvc ,tomcat的包包含requestMapping restController 等注解 -->
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
      <groupId>com.alibaba</groupId>
      <artifactId>druid-spring-boot-starter</artifactId>
      <version>1.1.10</version>
    </dependency>
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
    </dependency>
    <!-- druid依赖 -->
    <dependency>
      <groupId>com.alibaba</groupId>
      <artifactId>druid</artifactId>
      <version>1.1.0</version>
    </dependency>
    <!-- mybatisPlus 核心库 -->
    <dependency>
      <groupId>com.baomidou</groupId>
      <artifactId>mybatis-plus-boot-starter</artifactId>
      <version>3.1.0</version>
    </dependency>
  </dependencies>

application.yml配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
server:
  port: 10100   #  配置启动端口号
  
mybatis:
  config-location: classpath:mybatis.cfg.xml    #  mybatis主配置文件所在路径
  type-aliases-package: com.demo.drools.entity  #  定义所有操作类的别名所在包
  mapper-locations:                                     #  所有的mapper映射文件
    - classpath:mapper/*.xml
  
  
spring: #springboot的配置
  datasource: #定义数据源
    #127.0.0.1为本机测试的ip,3306是mysql的端口号。serverTimezone是定义时区,照抄就好,mysql高版本需要定义这些东西
    #useSSL也是某些高版本mysql需要问有没有用SSL连接
    url: jdbc:mysql://127.0.0.1:3306/test?serverTimezone=GMT%2B8&useSSL=FALSE
    username: root  #数据库用户名,root为管理员
    password: 123456 #该数据库用户的密码
    # 使用druid数据源
    type: com.alibaba.druid.pool.DruidDataSource
  
# mybatis-plus相关配置
mybatis-plus:
  # xml扫描,多个目录用逗号或者分号分隔(告诉 Mapper 所对应的 XML 文件位置)
  mapper-locations: classpath:mapper/*.xml
  # 以下配置均有默认值,可以不设置
  global-config:
    db-config:
      #主键类型 AUTO:"数据库ID自增" INPUT:"用户输入ID",ID_WORKER:"全局唯一ID (数字类型唯一ID)", UUID:"全局唯一ID UUID";
      id-type: auto
      #字段策略 IGNORED:"忽略判断"  NOT_NULL:"非 NULL 判断")  NOT_EMPTY:"非空判断"
      field-strategy: NOT_EMPTY
      #数据库类型
      db-type: MYSQL
  configuration:
    # 是否开启自动驼峰命名规则映射:从数据库列名到Java属性驼峰命名的类似映射
    map-underscore-to-camel-case: true
    # 如果查询结果中包含空值的列,则 MyBatis 在映射的时候,不会映射这个字段
    call-setters-on-nulls: true
    # 这个配置会将执行的sql打印出来,在开发或测试的时候可以用
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

 

用户信息实体

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
package com.demo.drools.entity;
  
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
  
/**
 * TODO your comment
 *
 * @author Yujiaqi
 * @date 2020/12/2 19:14
 */
@Data
@TableName("user_info")//@TableName中的值对应着表名
public class UserInfoEntity {
    /**
     * 主键
     * @TableId中可以决定主键的类型,不写会采取默认值,默认值可以在yml中配置
     * AUTO: 数据库ID自增
     * INPUT: 用户输入ID
     * ID_WORKER: 全局唯一ID,Long类型的主键
     * ID_WORKER_STR: 字符串全局唯一ID
     * UUID: 全局唯一ID,UUID类型的主键
     * NONE: 该类型为未设置主键类型
     */
    @TableId(type = IdType.AUTO)
    private Long id;
    /**
     * 姓名
     */
    private String name;
    /**
     * 年龄
     */
    private Integer age;
    /**
     * 技能
     */
    private String skill;
    /**
     * 评价
     */
    private String evaluate;
    /**
     * 分数
     */
    private Long fraction;
}

config类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
package com.demo.drools.config;
  
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import com.baomidou.mybatisplus.extension.plugins.PerformanceInterceptor;
import org.springframework.context.annotation.Bean;
  
/**
 * TODO your comment
 *
 * @author Yujiaqi
 * @date 2020/12/2 19:14
 */
public class MybatisPlusConfig {
    /**
     * mybatis-plus SQL执行效率插件【生产环境可以关闭】
     */
    @Bean
    public PerformanceInterceptor performanceInterceptor() {
        return new PerformanceInterceptor();
    }
    /**
     * 分页插件
     */
    @Bean
    public PaginationInterceptor paginationInterceptor() {
        return new PaginationInterceptor();
    }
}
————————————————
spring boot启动类
package com.demo.drools;
  
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
  
/**
 * @author 于嘉琪
 */
@SpringBootApplication
//@MapperScan和dao层添加@Mapper注解意思一样
@MapperScan(basePackages = "com.demo.drools.dao")
public class DroolsApplication {
    public static void main(String[] args) {
        SpringApplication.run(DroolsApplication.class, args);
    }
}
————————————————
dao层
package com.demo.drools.dao;
  
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.demo.drools.entity.UserInfoEntity;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
  
/**
 * 用户信息DAO
 *
 * @author Yujiaqi
 * @date 2020/12/2 19:16
 */
@Mapper
public interface UserInfoDao extends BaseMapper<UserInfoEntity> {
    
}
————————————————
service层
package com.demo.drools.service;
  
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.IService;
import com.demo.drools.entity.UserInfoEntity;
  
/**
 * TODO your comment
 *
 * @author Yujiaqi
 * @date 2020/12/2 19:17
 */
public interface UserInfoService extends IService<UserInfoEntity> {
     
}

serviceImpl实现类层

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package com.demo.drools.service.impl;
  
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.demo.drools.dao.UserInfoDao;
import com.demo.drools.entity.UserInfoEntity;
import com.demo.drools.service.UserInfoService;
import org.springframework.stereotype.Service;
  
import javax.annotation.Resource;
  
/**
 * TODO your comment
 *
 * @author Yujiaqi
 * @date 2020/12/2 19:18
 */
@Service
public class UserInfoSerivceImpl extends ServiceImpl<UserInfoDao, UserInfoEntity> implements UserInfoService {
     
}

controller控制层

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
package com.demo.drools.controller;
  
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.demo.drools.entity.UserInfoEntity;
import com.demo.drools.service.UserInfoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
  
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
  
/**
 * TODO your comment
 *
 * @author Yujiaqi
 * @date 2020/12/2 19:20
 */
@RestController
@RequestMapping("/userInfo")
public class UserInfoController {
    @Autowired
    private UserInfoService userInfoService;
     
    /**
     * 根据ID获取用户信息
     * @Author Sans
     * @CreateTime 2019/6/8 16:34
     * @Param  userId  用户ID
     * @Return UserInfoEntity 用户实体
     */
    @RequestMapping("/getInfo")
    public UserInfoEntity getInfo(String userId){
        UserInfoEntity userInfoEntity = userInfoService.getById(userId);
        return userInfoEntity;
    }
    /**
     * 查询全部信息
     * @Author Sans
     * @CreateTime 2019/6/8 16:35
     * @Param  userId  用户ID
     * @Return List<UserInfoEntity> 用户实体集合
     */
    @RequestMapping("/getList")
    public List<UserInfoEntity> getList(){
        List<UserInfoEntity> userInfoEntityList = userInfoService.list();
        return userInfoEntityList;
    }
    /**
     * 分页查询全部数据
     * @Author Sans
     * @CreateTime 2019/6/8 16:37
     * @Return IPage<UserInfoEntity> 分页数据
     */
    @RequestMapping("/getInfoListPage")
    public IPage<UserInfoEntity> getInfoListPage(){
        //需要在Config配置类中配置分页插件
        IPage<UserInfoEntity> page = new Page<>();
        page.setCurrent(5); //当前页
        page.setSize(1);    //每页条数
        page = userInfoService.page(page);
        return page;
    }
    /**
     * 根据指定字段查询用户信息集合
     * @Author Sans
     * @CreateTime 2019/6/8 16:39
     * @Return Collection<UserInfoEntity> 用户实体集合
     */
    @RequestMapping("/getListMap")
    public Collection<UserInfoEntity> getListMap(){
        Map<String,Object> map = new HashMap<>();
        //kay是字段名 value是字段值
        map.put("age",20);
        Collection<UserInfoEntity> userInfoEntityList = userInfoService.listByMap(map);
        return userInfoEntityList;
    }
    /**
     * 新增用户信息
     * @Author Sans
     * @CreateTime 2019/6/8 16:40
     */
    @RequestMapping("/saveInfo")
    public void saveInfo(){
        UserInfoEntity userInfoEntity = new UserInfoEntity();
        userInfoEntity.setName("小龙");
        userInfoEntity.setSkill("JAVA");
        userInfoEntity.setAge(18);
        userInfoEntity.setFraction(59L);
        userInfoEntity.setEvaluate("该学生是一个在改BUG的码农");
        userInfoService.save(userInfoEntity);
    }
    /**
     * 批量新增用户信息
     * @Author Sans
     * @CreateTime 2019/6/8 16:42
     */
    @RequestMapping("/saveInfoList")
    public void saveInfoList(){
        //创建对象
        UserInfoEntity sans = new UserInfoEntity();
        sans.setName("Sans");
        sans.setSkill("睡觉");
        sans.setAge(18);
        sans.setFraction(60L);
        sans.setEvaluate("Sans是一个爱睡觉,并且身材较矮骨骼巨大的骷髅小胖子");
        UserInfoEntity papyrus = new UserInfoEntity();
        papyrus.setName("papyrus");
        papyrus.setSkill("JAVA");
        papyrus.setAge(18);
        papyrus.setFraction(58L);
        papyrus.setEvaluate("Papyrus是一个讲话大声、个性张扬的骷髅,给人自信、有魅力的骷髅小瘦子");
        //批量保存
        List<UserInfoEntity> list =new ArrayList<>();
        list.add(sans);
        list.add(papyrus);
        userInfoService.saveBatch(list);
    }
    /**
     * 更新用户信息
     * @Author Sans
     * @CreateTime 2019/6/8 16:47
     */
    @RequestMapping("/updateInfo")
    public void updateInfo(){
        //根据实体中的ID去更新,其他字段如果值为null则不会更新该字段,参考yml配置文件
        UserInfoEntity userInfoEntity = new UserInfoEntity();
        userInfoEntity.setId(1L);
        userInfoEntity.setAge(19);
        userInfoService.updateById(userInfoEntity);
    }
    /**
     * 新增或者更新用户信息
     * @Author Sans
     * @CreateTime 2019/6/8 16:50
     */
    @RequestMapping("/saveOrUpdateInfo")
    public void saveOrUpdate(){
        //传入的实体类userInfoEntity中ID为null就会新增(ID自增)
        //实体类ID值存在,如果数据库存在ID就会更新,如果不存在就会新增
        UserInfoEntity userInfoEntity = new UserInfoEntity();
        userInfoEntity.setId(1L);
        userInfoEntity.setAge(20);
        userInfoService.saveOrUpdate(userInfoEntity);
    }
    /**
     * 根据ID删除用户信息
     * @Author Sans
     * @CreateTime 2019/6/8 16:52
     */
    @RequestMapping("/deleteInfo")
    public void deleteInfo(String userId){
        userInfoService.removeById(userId);
    }
    /**
     * 根据ID批量删除用户信息
     * @Author Sans
     * @CreateTime 2019/6/8 16:55
     */
    @RequestMapping("/deleteInfoList")
    public void deleteInfoList(){
        List<String> userIdlist = new ArrayList<>();
        userIdlist.add("12");
        userIdlist.add("13");
        userInfoService.removeByIds(userIdlist);
    }
    /**
     * 根据指定字段删除用户信息
     * @Author Sans
     * @CreateTime 2019/6/8 16:57
     */
    @RequestMapping("/deleteInfoMap")
    public void deleteInfoMap(){
        //kay是字段名 value是字段值
        Map<String,Object> map = new HashMap<>();
        map.put("skill","删除");
        map.put("fraction",10L);
        userInfoService.removeByMap(map);
    }
}
————————————————
controller层用到lambda语法
package com.demo.drools.controller;
  
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.demo.drools.entity.UserInfoEntity;
import com.demo.drools.service.UserInfoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
  
import java.util.HashMap;
import java.util.List;
import java.util.Map;
  
/**
 * TODO your comment
 *
 * @author Yujiaqi
 * @date 2020/12/2 19:28
 */
public class UserInfoPlusController {
    @Autowired
    private UserInfoService userInfoService;
     
    /**
     * MP扩展演示
     * @Author Sans
     * @CreateTime 2019/6/8 16:37
     * @Return Map<String,Object> 返回数据
     */
    @RequestMapping("/getInfoListPlus")
    public Map<String,Object> getInfoListPage(){
        //初始化返回类
        Map<String,Object> result = new HashMap<>();
        //查询年龄等于18岁的学生
        //等价SQL: SELECT id,name,age,skill,evaluate,fraction FROM user_info WHERE age = 18
        QueryWrapper<UserInfoEntity> queryWrapper1 = new QueryWrapper<>();
        queryWrapper1.lambda().eq(UserInfoEntity::getAge,18);
        List<UserInfoEntity> userInfoEntityList1 = userInfoService.list(queryWrapper1);
        result.put("studentAge18",userInfoEntityList1);
        //查询年龄大于5岁的学生且小于等于18岁的学生
        //等价SQL: SELECT id,name,age,skill,evaluate,fraction FROM user_info WHERE age > 5 AND age <= 18
        QueryWrapper<UserInfoEntity> queryWrapper2 = new QueryWrapper<>();
        queryWrapper2.lambda().gt(UserInfoEntity::getAge,5);
        queryWrapper2.lambda().le(UserInfoEntity::getAge,18);
        List<UserInfoEntity> userInfoEntityList2 = userInfoService.list(queryWrapper2);
        result.put("studentAge5",userInfoEntityList2);
        //模糊查询技能字段带有"画"的数据,并按照年龄降序
        //等价SQL: SELECT id,name,age,skill,evaluate,fraction FROM user_info WHERE skill LIKE '%画%' ORDER BY age DESC
        QueryWrapper<UserInfoEntity> queryWrapper3 = new QueryWrapper<>();
        queryWrapper3.lambda().like(UserInfoEntity::getSkill,"画");
        queryWrapper3.lambda().orderByDesc(UserInfoEntity::getAge);
        List<UserInfoEntity> userInfoEntityList3 = userInfoService.list(queryWrapper3);
        result.put("studentAgeSkill",userInfoEntityList3);
        //模糊查询名字带有"小"或者年龄大于18的学生
        //等价SQL: SELECT id,name,age,skill,evaluate,fraction FROM user_info WHERE name LIKE '%小%' OR age > 18
        QueryWrapper<UserInfoEntity> queryWrapper4 = new QueryWrapper<>();
        queryWrapper4.lambda().like(UserInfoEntity::getName,"小");
        queryWrapper4.lambda().or().gt(UserInfoEntity::getAge,18);
        List<UserInfoEntity> userInfoEntityList4 = userInfoService.list(queryWrapper4);
        result.put("studentOr",userInfoEntityList4);
        //查询评价不为null的学生,并且分页
        //等价SQL: SELECT id,name,age,skill,evaluate,fraction FROM user_info WHERE evaluate IS NOT NULL LIMIT 0,5
        IPage<UserInfoEntity> page = new Page<>();
        page.setCurrent(1);
        page.setSize(5);
        QueryWrapper<UserInfoEntity> queryWrapper5 = new QueryWrapper<>();
        queryWrapper5.lambda().isNotNull(UserInfoEntity::getEvaluate);
        page = userInfoService.page(page,queryWrapper5);
        result.put("studentPage",page);
        return result;
    }
}
————————————————

以上就是mybatis-plus的小案例,mybatis-plus它像我之前使用的spring data jpa框架不用写sql语句,就可以实现简单的增删改查、批量操作、分页mybatis-plus功能还是比较强大,能减少我们写很多代码,我个人还是比较喜欢用这个mybatis-plus的

mybatis-plus只是mybatis的增强版,它不影响mybatis的使用,我们可以写我们自定的方法以及sql,接下来我们看一个小案例

dao层新增方法

1
2
3
4
5
6
7
8
9
10
11
/**
     * 查询大于该分数的学生
     * @Author Sans
     * @CreateTime 2019/6/9 14:28
     * @Param  page  分页参数
     * @Param  fraction  分数
     * @Return IPage<UserInfoEntity> 分页数据
     */
    IPage<UserInfoEntity> selectUserInfoByGtFraction(
            @Param(value = "page") IPage<UserInfoEntity> page,
            @Param(value = "fraction")Long fraction);

service新增方法

1
2
3
4
5
6
7
8
9
/**
     * 查询大于该分数的学生
     * @Author Sans
     * @CreateTime 2019/6/9 14:27
     * @Param  page  分页参数
     * @Param  fraction  分数
     * @Return IPage<UserInfoEntity> 分页数据
     */
    IPage<UserInfoEntity> selectUserInfoByGtFraction(IPage<UserInfoEntity> page,Long fraction);

serviceImpl层新增方法

1
2
3
4
5
6
7
8
9
10
11
12
/**
     * 查询大于该分数的学生
     * @Author Sans
     * @CreateTime 2019/6/9 14:27
     * @Param  page  分页参数
     * @Param  fraction  分数
     * @Return IPage<UserInfoEntity> 分页数据
     */
    @Override
    public IPage<UserInfoEntity> selectUserInfoByGtFraction(IPage<UserInfoEntity> page, Long fraction) {
        return userInfoDao.selectUserInfoByGtFraction(page,fraction);
    }

controller层新增方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/**
     * MP自定义SQL
     * @Author Sans
     * @CreateTime 2019/6/9 14:37
     * @Return IPage<UserInfoEntity> 分页数据
     */
    @RequestMapping("/getInfoListSQL")
    public IPage<UserInfoEntity> getInfoListSQL(){
        //查询大于60分以上的学生,并且分页
        IPage<UserInfoEntity> page = new Page<>();
        page.setCurrent(1);
        page.setSize(5);
        page = userInfoService.selectUserInfoByGtFraction(page,60L);
        return page;
    }

配置我们的mybatis的xml

1
2
3
4
5
6
7
8
<?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.demo.drools.dao.UserInfoDao">
  <!-- Sans 2019/6/9 14:35 -->
  <select id="selectUserInfoByGtFraction" resultType="com.demo.drools.entity.UserInfoEntity">
    SELECT * FROM user_info WHERE fraction > #{fraction}
    </select>
</mapper>

mybatis plus强大的条件构造器queryWrapper、updateWrapper
1.QueryWrapper: Entity 对象封装操作类
2.UpdateWrapper : Update 条件封装,用于Entity对象更新操作
3.条件构造器使用中的各个方法格式和说明

 

posted @   hanease  阅读(1494)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
点击右上角即可分享
微信分享提示