一、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
@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配置
<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配置
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
用户信息实体
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类
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实现类层
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控制层
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层新增方法
/** * 查询大于该分数的学生 * @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新增方法
/** * 查询大于该分数的学生 * @Author Sans * @CreateTime 2019/6/9 14:27 * @Param page 分页参数 * @Param fraction 分数 * @Return IPage<UserInfoEntity> 分页数据 */ IPage<UserInfoEntity> selectUserInfoByGtFraction(IPage<UserInfoEntity> page,Long fraction);
serviceImpl层新增方法
/** * 查询大于该分数的学生 * @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层新增方法
/** * 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
<?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.条件构造器使用中的各个方法格式和说明