以前在开发的时候,使用mybatis的时候,经常都需要先配置xml映射文件,然后每条sql操作都需要自己进行手动编写,对于一些复杂的sql这么来操作确实有必要,但是如果只是一些非常简单的insert,update,delete,select这类型的语句而言,也需要开发人员花费额外的时间进行手动编写的话,确实费时又费力。能否为mybatis特别定制一套能够自动为我们生成一些简单sql功能,同时又支持我们进行自定义sql设置功能的强大框架呢?
mybatis plus因此诞生了。
mybatis plus是一款专门针对于传统MyBatis开发中sql需要手动进行映射配置繁琐缺点的一款框架技术,这款框架技术提供了十分丰富的api供开发者们使用,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。
Mybatis plus到底有多方便呢,我们闲话不多说,直接上手代码实例来进行演示:
首先我们需要导入一些相关的pom依赖配置
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.sise</groupId> <artifactId>mybatis-plus</artifactId> <version>1.0-SNAPSHOT</version> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.9.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatisplus-spring-boot-starter</artifactId> <version>1.0.5</version> </dependency> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus</artifactId> <version>2.3</version> </dependency> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>1.3.1</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> </dependencies> </project> 复制代码
导入了jar包之后,为了方便测试,我们首先在数据库里面搭建相关的数据表信息
CREATE TABLE `teacher` ( `id` int(11) NOT NULL AUTO_INCREMENT, `teacher_name` varchar(60) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL, `teacher_pwd` varchar(60) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=14 DEFAULT CHARSET=gbk; 复制代码
该表对应的实体类:
package com.sise.model; import com.baomidou.mybatisplus.annotations.TableName; /** * @author idea * @data 2019/5/24 */ @TableName(value = "teacher") public class Teacher { private int id; private String teacherName; private String teacherPwd; public int getId() { return id; } public Teacher() { } public Teacher(int id) { this.id = id; } public Teacher setId(int id) { this.id = id; return this; } public String getTeacherName() { return teacherName; } public Teacher setTeacherName(String teacherName) { this.teacherName = teacherName; return this; } public String getTeacherPwd() { return teacherPwd; } public Teacher setTeacherPwd(String teacherPwd) { this.teacherPwd = teacherPwd; return this; } @Override public String toString() { return "Teacher{" + "id=" + id + ", teacherName='" + teacherName + '\'' + ", teacherPwd='" + teacherPwd + '\'' + '}'; } } 复制代码
通常我们在开发的时候都会自定义一个Dao层,mybatis plus里面提供了一个叫做BaseMapper的接口,内部已经提供了相当多的crud操作函数的封装。可以来仔细查看一下该接口的内容:
/** * Copyright (c) 2011-2020, hubin (jobob@qq.com). * <p> * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at * <p> * http://www.apache.org/licenses/LICENSE-2.0 * <p> * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. */ package com.baomidou.mybatisplus.mapper; import java.io.Serializable; import java.util.Collection; import java.util.List; import java.util.Map; import org.apache.ibatis.annotations.Param; import org.apache.ibatis.session.RowBounds; /** * <p> * Mapper 继承该接口后,无需编写 mapper.xml 文件,即可获得CRUD功能 * </p> * <p> * 这个 Mapper 支持 id 泛型 * </p> * * @author hubin * @Date 2016-01-23 */ public interface BaseMapper<T> { /** * <p> * 插入一条记录 * </p> * * @param entity 实体对象 * @return int */ Integer insert(T entity); /** * <p> * 插入一条记录 * </p> * * @param entity 实体对象 * @return int */ Integer insertAllColumn(T entity); /** * <p> * 根据 ID 删除 * </p> * * @param id 主键ID * @return int */ Integer deleteById(Serializable id); /** * <p> * 根据 columnMap 条件,删除记录 * </p> * * @param columnMap 表字段 map 对象 * @return int */ Integer deleteByMap(@Param("cm") Map<String, Object> columnMap); /** * <p> * 根据 entity 条件,删除记录 * </p> * * @param wrapper 实体对象封装操作类(可以为 null) * @return int */ Integer delete(@Param("ew") Wrapper<T> wrapper); /** * <p> * 删除(根据ID 批量删除) * </p> * * @param idList 主键ID列表 * @return int */ Integer deleteBatchIds(@Param("coll") Collection<? extends Serializable> idList); /** * <p> * 根据 ID 修改 * </p> * * @param entity 实体对象 * @return int */ Integer updateById(@Param("et") T entity); /** * <p> * 根据 ID 修改 * </p> * * @param entity 实体对象 * @return int */ Integer updateAllColumnById(@Param("et") T entity); /** * <p> * 根据 whereEntity 条件,更新记录 * </p> * * @param entity 实体对象 * @param wrapper 实体对象封装操作类(可以为 null) * @return */ Integer update(@Param("et") T entity, @Param("ew") Wrapper<T> wrapper); /** * <p> * 根据 whereEntity 条件,更新记录 * </p> * * @param setStr set字符串 * @param wrapper 实体对象封装操作类(可以为 null) * @return */ Integer updateForSet(@Param("setStr") String setStr, @Param("ew") Wrapper<T> wrapper); /** * <p> * 根据 ID 查询 * </p> * * @param id 主键ID * @return T */ T selectById(Serializable id); /** * <p> * 查询(根据ID 批量查询) * </p> * * @param idList 主键ID列表 * @return List<T> */ List<T> selectBatchIds(@Param("coll") Collection<? extends Serializable> idList); /** * <p> * 查询(根据 columnMap 条件) * </p> * * @param columnMap 表字段 map 对象 * @return List<T> */ List<T> selectByMap(@Param("cm") Map<String, Object> columnMap); /** * <p> * 根据 entity 条件,查询一条记录 * </p> * * @param entity 实体对象 * @return T */ T selectOne(@Param("ew") T entity); /** * <p> * 根据 Wrapper 条件,查询总记录数 * </p> * * @param wrapper 实体对象 * @return int */ Integer selectCount(@Param("ew") Wrapper<T> wrapper); /** * <p> * 根据 entity 条件,查询全部记录 * </p> * * @param wrapper 实体对象封装操作类(可以为 null) * @return List<T> */ List<T> selectList(@Param("ew") Wrapper<T> wrapper); /** * <p> * 根据 Wrapper 条件,查询全部记录 * </p> * * @param wrapper 实体对象封装操作类(可以为 null) * @return List<T> */ List<Map<String, Object>> selectMaps(@Param("ew") Wrapper<T> wrapper); /** * <p> * 根据 Wrapper 条件,查询全部记录 * 注意: 只返回第一个字段的值 * </p> * * @param wrapper 实体对象封装操作类(可以为 null) * @return List<Object> */ List<Object> selectObjs(@Param("ew") Wrapper<T> wrapper); /** * <p> * 根据 entity 条件,查询全部记录(并翻页) * </p> * * @param rowBounds 分页查询条件(可以为 RowBounds.DEFAULT) * @param wrapper 实体对象封装操作类(可以为 null) * @return List<T> */ List<T> selectPage(RowBounds rowBounds, @Param("ew") Wrapper<T> wrapper); /** * <p> * 根据 Wrapper 条件,查询全部记录(并翻页) * </p> * * @param rowBounds 分页查询条件(可以为 RowBounds.DEFAULT) * @param wrapper 实体对象封装操作类 * @return List<Map<String, Object>> */ List<Map<String, Object>> selectMapsPage(RowBounds rowBounds, @Param("ew") Wrapper<T> wrapper); } 复制代码
这些内置的功能都是已经提前自定义好了的,因此对于一些常用的简单的sql我们可以避免使用手动拼接的方式来实现,大大提升了开发人员的开发效率,结合文章上边所说的教师对象,我们自定义一个Mapper接口用于实现crud的操作:
package com.sise.dao; import com.baomidou.mybatisplus.mapper.BaseMapper; import com.sise.model.Teacher; import org.apache.ibatis.annotations.Mapper; /** * @author idea * @data 2019/5/24 */ @Mapper public interface TeacherMapper extends BaseMapper<Teacher> { } 复制代码
为了方便测试,我直接选择了在controller里面引用dao函数的功能。
1.提前定义好的插入功能:
BaseMapper里面封装了已经定义好的insert语句,能够方便我们直接调用,无须自己手动编写sql
@GetMapping(value = "/insert") public void insert(){ Teacher teacher=new Teacher(); teacher.setTeacherName(createRandomStr(6)); teacher.setTeacherPwd(createRandomStr(6)); teacherMapper.insert(teacher); } /** * 生成随机字符串 * * @return */ private static String createRandomStr(int length){ String str="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; Random random=new Random(); StringBuffer sb=new StringBuffer(); for(int i=0;i<length;i++){ int number=random.nextInt(str.length()); sb.append(str.charAt(number)); } return sb.toString(); } 复制代码
生成的sql语句:
INSERT INTO teacher ( id, teacher_name, teacher_pwd ) VALUES ( 0, 'mNJXIf', 'LKTnam' ); 复制代码
2.提前定义好的删除功能
BaseMapper里面提供有已经定义好的delete功能,
@GetMapping(value = "/delete") public void delete(){ Teacher teacher=new Teacher(); teacher.setId(11); EntityWrapper entityWrapper=new EntityWrapper(teacher); teacherMapper.delete(entityWrapper); } 复制代码
生成的sql语句:
DELETE FROM teacher WHERE id=11; 复制代码
3.提前定义好的更新功能
BaseMapper里面定义了相关的update功能,但是在进行update的时候有个地方需要注意,来看看下边这段代码先
@GetMapping(value = "/update") public void update(){ //update的判断条件 EntityWrapper entityWrapper=new EntityWrapper(new Teacher(1)); //更新之后的对象 Teacher teacher=new Teacher(); teacher.setTeacherPwd("new-pwd"); teacherMapper.update(teacher,entityWrapper); } 复制代码
生成的sql语句:
UPDATE teacher SET teacher_pwd='new-pwd' WHERE id=1; 复制代码
mybatis-plus里面提供了一个叫做EntityWrapper的对象封装操作类,通过传入相关的Entity来判断传入的查询参数,这里的使用让我回想起了以前用hibernate的那种味道,不得不说这种功能的设计确实帮开发者的开发效率提升了很多。
以前写更新语句的时候,经常是需要在xml里面进行非常多繁琐耗时的sql拼接工作,现在mybatis-plus通过EntityWrapper这个封装类,大大节省了相应时间。
4.根据指定id进行查询
mybatis-plus也默认提供了关键字查询的功能,可以将查询参数通过对象Entity的形式注入,非常方便。
ps:mybatis-plus已经默认带有了sql注入的预防功能,因此这点可以放心使用。
@GetMapping(value = "/selectAllById") public Teacher selectByTeacherName(int id){ return teacherMapper.selectOne(new Teacher(id)); } 复制代码
生成的sql语句:
SELECT id,teacher_name AS teacherName,teacher_pwd AS teacherPwd FROM teacher WHERE id=0; 复制代码
5.使用Map来进行多关键字的查询
有些时候,除了使用查询时候使用Entity关键字来进行查询之外,还可以通过使用Map的形式来进行多关键字的搜索实现,相关代码如下所示:
@GetMapping(value = "/selectAllByMap") public List<Teacher> selectAllByEntity(String name){ Map<String,Object> hashMap=new HashMap<>(); hashMap.put("teacher_name",name); return teacherMapper.selectByMap(hashMap); } 复制代码
注意,这里的map放入的key值需要和表里面的字段命名一致。
生成的sql语句:
SELECT id,teacher_name AS teacherName,teacher_pwd AS teacherPwd FROM teacher WHERE teacher_name = 'qwe'; 复制代码