目录

目录

1 Mybatis调用流程

2 Mybatis与MybatisPlus

2.1 MybatisPlus特点

2.2 Mybatis与MybatisPlus区别

区别1:MybatisPlus自动注入基本 CURD

区别2:MybatisPlus只增强不改变

3 Mybatis与MybatisPlus对比

3.1 准备数据表demo_user

3.2 项目结构

3.2.1 导入依赖包

3.2.2 创建对象关系映射User类

3.2.3 创建配置文件

3.2.4 创建Mapper层接口文件

3.3 对比测试

3.3.1 创建测试类

3.3.2 MybatisPlus实现原理

为什么不建议你使用Mybatis-plus


1 Mybatis调用流程

  1. Spring容器为接口创建代理对象. Spring容器启动对象立即创建
  2. 根据 @Autowired 注解动态注入Mapper接口的代理对象
  3. 用户通过Mapper接口调用方法.(执行业务操作)
  4. Mybatis根据接口方法动态匹配xml的映射文件

(1.根据Mapper的接口路径匹配xml映射文件中的 com.jt.mapper.UserMapper
(2.根据接口的方法匹配xml映射文件中的sql id 之后执行Sql语句
(3.Mybatis将结果集封装为对象之后返回.

2 Mybatis与MybatisPlus

2.1 MybatisPlus特点

  • 无侵入:只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑
  • 损耗小:启动即会自动注入基本 CURD,性能基本无损耗,直接面向对象操作

2.2 Mybatis与MybatisPlus区别

区别1:MybatisPlus自动注入基本 CURD

Mybatis是一种操作数据库的框架,提供一种Mapper类,支持让你用java代码进行增删改查的数据库操作,前提是你得先在xml中写好sql语句,但是每当要写一个业务逻辑的时候都要在DAO层写一个方法,再对应一个SQL,即使是简单的条件查询、或者是仅仅改变了一个条件都要在DAO层新增一个方法,还是有点麻烦。而MybatisPlus自动为Mybatis生成简单的增删改查SQL语句的工具,可以省去手写简单SQL语句的时间,只在XML中编写其它需要的SQL语句,所以MP与mybatis配合使用的话可以很好的提高开发效率。

区别2:MybatisPlus只增强不改变

Mybatis-Plus是一个Mybatis的增强工具,它在Mybatis的基础上做了增强,却不做改变。我们在使用Mybatis-Plus之后既可以使用Mybatis-Plus的特有功能,又能够正常使用Mybatis的原生功能。Mybatis-Plus是为简化开发、提高开发效率而生,但它也提供了一些很有意思的插件,比如SQL性能监控、乐观锁、执行分析等。

3 Mybatis与MybatisPlus对比

3.1 准备数据表demo_user

3.2 项目结构

3.2.1 导入依赖包

向pom.xml中导入相关依赖包

   <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.5.2</version><relativePath/> <!-- lookup parent from repository --></parent><properties><java.version>1.8</java.version><!--跳过测试类打包--><skipTests>true</skipTests></properties><!--原则:按需导入--><dependencies><dependency><groupId>org.springframework.boot</groupId><!--springboot启动项(器),在包的内部springboot已经完成了项目的“整合”(配置)用户拿来就能用--><artifactId>spring-boot-starter-web</artifactId></dependency><!--数据库驱动--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-jdbc</artifactId></dependency><!--springboot数据库连接--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.4.3</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency></dependencies><!--springboot项目与Maven整合的一个插件可以通过插件 执行项目打包/测试/文档生成等操作注意事项:该插件不能省略,如果省略启动时报错(省略时)项目发布时:java -jar xxxx.jar 报错没有主清单信息!!--><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build>

3.2.2 创建对象关系映射User类

注意user类是与demo_user表对应,属性与字段对应。

package com.jt.pojo;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serializable;
@Data//使用了lombok插件,不用手写set、get、tostring等方法
@Accessors(chain = true)
@TableName("demo_user")
public class User implements Serializable {//ID代表主键,不是id字段@TableId(type=IdType.AUTO)//主键自增//@TableField("name")//如果属性与字段同名(包括驼峰规则)注解可以省略private Integer id;private String name;private Integer age;private String sex;
}

3.2.3 创建配置文件

创建UserMapper.xml文件,里面包含大量的SQL语句

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.jt.mapper.UserMapper"><!--查询表中所有数据--><select id="getAll" resultType="User">select * from demo_user</select><!--查询指定id的数据--><select id="getById" resultType="User">select * from demo_user where id = #{id}</select><!--查询指定sex和age的数据--><select id="getByAgeSex" resultType="User">select * from demo_user where sex = #{sex} and age = #{age}</select><!--查询name包含指定字符的数据--><select id="getNameContain" parameterType="String" resultType="User">select * from demo_user where name like "%"#{str}"%"</select><!--查询按照age>xx,并按照age和sex排序的数据--><select id="toSort" resultType="User">select * from demo_user where age &gt; #{age} order by age asc ,sex desc</select><!--根据name/age动态查询数据,如果name/age不为null则拼接where条件--><select id="getByNameAge" resultType="User">select * from demo_user<if test="name!=null">where name=#{name} <if test="age!=null">and age=#{age}</if></if></select><!--随机查询5个id的数据--><select id="getByIdS" resultType="User">select * from demo_user where id in<foreach collection="array" index="index" item="id" open="(" separator="," close=")">#{id}</foreach></select><!--查询指定sex=xx和age>xx的数据--><select id="getBySexAge" resultType="User">select * from demo_user where sex = #{sex} and age &gt; #{age}</select><!--根据name更新数据--><update id="updateByName">update demo_user set name = #{aftername},age = #{age} where name = #{beforename}</update><!--根据id主键删除单个数据--><delete id="delById">delete from demo_user where id = #{id}</delete><!--根据id主键删除多条数据--><delete id="delByIdS">delete from demo_user where id in<foreach collection="arr" item="id" index="index" open="(" separator="," close=")">#{id}</foreach></delete><!--根据指定name删除数据--><delete id="delByName">delete from demo_user where name = #{name}</delete><!--根据指定id主键更新数据--><update id="updateById1">update demo_user set name = #{name},sex = #{sex},age = #{age} where id = #{id}</update><!--插入数据--><insert id="insertInto">insert into demo_user (name,sex,age) values (#{name},#{sex},#{age})</insert>
</mapper>

创建application.yml文件,里面包含要连接数据库、驱动器、用户名与密码等配置信息

server:port: 8090spring:datasource:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://127.0.0.1:3306/jt?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf8&autoReconnect=true&allowMultiQueries=trueusername: rootpassword: root#如果数据库密码以数字0开头 则必须使用""号包裹#password: "01234"#SpringBoot整合Mybatis配置
#定义别名包:实现对象映射
#只做增强不做改变
mybatis-plus:type-aliases-package: com.jt.pojo#映射文件加载路径mapper-locations: classpath:/mybatisplus/*.xml#开启驼峰映射configuration:map-underscore-to-camel-case: true
#不打印日志
debug: false
logging:level:com.jt.mapper: debug

3.2.4 创建Mapper层接口文件

包路径要与xml配置文件的namespace值要一致,方法名和返回值类型分别要与xml文件的id和返回值类型要一致。

package com.jt.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.jt.pojo.User;
import org.apache.ibatis.annotations.Param;
import java.util.List;
//继承接口时必须添加泛型对象,否则映射表报错
public interface UserMapper extends BaseMapper<User> {//查询表中所有数据List<User> getAll();//询指定id的数据List<User> getById(Integer id);//查询指定sex和age的数据List<User> getByAgeSex(@Param("sex") String sex,@Param("age") Integer age);//查询name包含指定字符的数据List<User> getNameContain(String str);//按年龄排序和性别排序List<User> toSort(Integer age);//根据name/age动态查询数据,如果name/age不为null则拼接where条件List<User> getByNameAge(@Param("name") String name, @Param("age") Integer age);//随机查询5个id的数据List<User> getByIdS(@Param("array") int[] id);//查询按照age>xx,并按照age和sex排序的数据List<User> getBySexAge(@Param("sex") String sex,@Param("age") Integer age);//根据name更新数据void updateByName(@Param("beforename") String beforename,@Param("aftername") String aftername,@Param("age") Integer age);//根据id主键删除单个数据void delById(Integer id);//根据id主键删除多条数据void delByIdS(@Param("arr") Integer[] id);//根据指定name删除数据void delByName(String name);//根据指定id主键更新数据void updateById1(@Param("id") Integer id,@Param("name") String name,@Param("sex") String sex,@Param("age") Integer age);//插入数据(主键自增)void insertInto(@Param("name") String name,@Param("sex") String sex,@Param("age") Integer age);
}

3.3 对比测试

3.3.1 创建测试类

注释里的(MP)代表该方法是使用MybatisPlus实现的。

说明:以下的所有方法都经过测试,并未出现错误结果,请根据实际情况向对应方法中传入合适参数。

package com.jt;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.jt.mapper.UserMapper;
import com.jt.pojo.User;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.util.StreamUtils;
import org.springframework.util.StringUtils;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/*
* 测试注解只能在test包下使用
* 此注解表示可以从spring容器里面拿对象
* */
@SpringBootTest
public class TestSpringBoot {@Autowiredprivate UserMapper userMapper;//代理对象@Test//查询表中所有数据public void testGetAll(){
//        System.out.println(userMapper.getClass());List<User> userList = userMapper.getAll();System.out.println(userList);}@Test//查询指定id的数据public void testGetById(){System.out.println(userMapper.getById(50));}@Test//(MP)查询指定id的数据public void getByID(){User user = userMapper.selectById(1);System.out.println(user);}@Test//查询指定sex和age的数据public void testGetByAgeSex(){System.out.println(userMapper.getByAgeSex("男",18));}@Test//(MP)查询指定sex和age的数据public void getByAS(){User user = new User();user.setSex("女").setAge(18);QueryWrapper queryWrapper = new QueryWrapper(user);List<User> userList = userMapper.selectList(queryWrapper);System.out.println(userList);}@Test//查询指定sex=xx和age>xx的数据public void getBySexAge(){List<User> userlist = userMapper.getBySexAge("男", 18);System.out.println(userlist);}@Test//(MP)查询指定sex=xx和age>xx的数据public void getBygtAS(){QueryWrapper<User> queryWrapper = new QueryWrapper<>();queryWrapper.gt("age", 18).eq("sex","女");List<User> userList = userMapper.selectList(queryWrapper);System.out.println(userList);}@Test//查询name包含指定字符的数据public void testGetNameContain(){System.out.println(userMapper.getNameContain("孙"));}@Test//(MP)查询name包含指定字符的数据public void getContain1(){QueryWrapper<User> queryWrapper = new QueryWrapper<>();queryWrapper.like("name", "君");List<User> userList = userMapper.selectList(queryWrapper);System.out.println(userList);}@Test//查询按照age>xx,并按照age和sex排序的数据public void testToSort(){System.out.println(userMapper.toSort(18));}@Test//(MP)查询按照age>xx,并按照age和sex排序的数据public void testOrderBy(){QueryWrapper<User> queryWrapper = new QueryWrapper<>();queryWrapper.gt("age", 18).orderByDesc("age").orderByAsc("sex");List<User> userList = userMapper.selectList(queryWrapper);System.out.println(userList);}@Test//随机查询5个id的数据public void testGetByIdS(){int[] arr = {5,6,7,8,9};System.out.println(userMapper.getByIdS(arr));}@Test//(MP)随机查询5个id的数据public void testIn(){QueryWrapper<User> queryWrapper = new QueryWrapper<>();queryWrapper.in("id",1,3,5,7,6);List<User> userList = userMapper.selectList(queryWrapper);System.out.println(userList);Integer[] ids = new Integer[]{1,3,5,7,6};List<Integer> idList = Arrays.asList(ids);List<User> userList1 = userMapper.selectBatchIds(idList);System.out.println(userList1);}@Test//根据name/age动态查询数据,如果name/age不为null则拼接where条件public void testGetByNameAge(){System.out.println(userMapper.getByNameAge("如花",null));}@Test//(MP)根据name/age动态查询数据,如果name/age不为null则拼接where条件public void testSelectNS(){String name = "小乔";String sex = "女";QueryWrapper<User> queryWrapper = new QueryWrapper<>();boolean nameFlag = StringUtils.hasLength(name);boolean sexFlag = StringUtils.hasLength(sex);queryWrapper.eq(nameFlag,"name", name).eq(sexFlag,"sex", sex);List<User> userList = userMapper.selectList(queryWrapper);System.out.println(userList);}@Test//根据name更新数据public void updateByName(){userMapper.updateByName("云英", "吴饭饭", 18);System.out.println("成功");}@Test//(MP)根据name更新数据public void updateTest(){User user = new User();user.setAge(100).setName("祝君好运");UpdateWrapper<User> updateWrapper = new UpdateWrapper<>();updateWrapper.eq("name", "吴反反");userMapper.update(user,updateWrapper);}@Test//根据id主键删除单个数据public void delById(){userMapper.delById(235);System.out.println("成功");}@Test//(MP)根据id主键删除单个数据public void testDel(){userMapper.deleteById(232);System.out.println("成功");}@Test//根据id主键删除多条数据public void delByIds(){Integer[] arr = {233,234};userMapper.delByIdS(arr);System.out.println("成功");}@Test//(MP)根据id主键删除多条数据public void testDelIds(){Integer[] ids = new Integer[]{231,227};List<Integer> integers = Arrays.asList(ids);userMapper.deleteBatchIds(integers);System.out.println("成功");}@Test//根据指定name删除数据public void delByName(){userMapper.delByName("吴饭饭");System.out.println("成功");}@Test//(MP)根据指定name删除数据public void testDelNA(){QueryWrapper<User> queryWrapper = new QueryWrapper<>();queryWrapper.eq("name", "吴亦凡").eq("age", 30);userMapper.delete(queryWrapper);System.out.println("成功");}@Test//根据指定id主键更新数据public void updateById1(){userMapper.updateById1(196, "饭饭", "男", 1000);System.out.println("成功");}@Test//(MP)根据指定id主键更新数据public void updateByIdMP(){User user = new User();user.setName("云英").setSex("男").setAge(16).setId(196);userMapper.updateById(user);System.out.println("成功");}@Test//插入数据public void insertUser(){userMapper.insertInto("凡凡", "男", 222);System.out.println("成功");}@Test//(MP)插入数据public void testInsert(){User user = new User();user.setId(555).setName("吴亦凡").setAge(30).setSex("男");userMapper.insert(user);System.out.println("成功");}
}

3.3.2 MybatisPlus实现原理

  1. 用户执行User对象入库操作 userMapper.insert(user);
  2. 由于接口方法中需要传递泛型对象,则根据用户配置查找对应的泛型对象
  3. 根据用户的接口获取Mapper接口的父级接口BaseMapper,根据BaseMapper中的泛型对象 获取信息User.class类型
  4. 根据User.class 动态获取@TableName(“demo_user”) 获取对象对应的表名.之后通过@TableField(“name”)绑定与之对应的字段. 至此对象与表完成了映射.
  5. 根据上述的映射关系,动态的拼接Sql语句.
  6. MP将动态生成的Sql交给Mybatis执行最终实现数据入库操作!!!

为什么不建议你使用Mybatis-plus

代码整洁本身是为了降低修改成本的,MP本末倒置。
整洁的代码意味着阅读代码的时间成本降低,但是如果使用MP,在你阅读service层代码时,还会看到在代码中拼装SQL执行条件的部分。这样一来,service层代码和数据库访问层代码混淆在一起,让程序员很难专注的关心某一细节。常见的SQL操作MP可以通过Wrapper构造SQL执行条件,程序员就看不到一条条SQL语句,而阅读和检查SQL逻辑是比较耗费精力的事,MP只不过是以后期维护成本为代价换取开发时貌似整洁的优势。

SQL执行错误是最容易修改的错误
如果你使用纯Mybatis相比MP会更容易爆出SQL执行错误。其实大可不必太在乎这个问题,如果是SQL执行逻辑有问题,那不管MP还是Mybatis都会报错。如果是SQL语法错误,由于SQL语法错误在Java开发中错误日志非常显眼,所以你可以通过复制日志中报错的SQL然后代码全局搜索快速定位出错位置,而且SQL语法错误基本都是字段名写错或者执行条件顺序错误,这都是非常容易修改的BUG。

纯Mybatis具有更好的代码复用性
比如,我要查询班级id为7,的所有班干部同学。你在纯Mybatis中会一次性将SQL写进XML文件中,如果在项目中这条SQL需要调用N次,你只需要在这N个地方都传参调用即可。但如果用了MP,你需要将相同的代码复制N次。

Mybatis-Plus入门案例、以及为什么不建议使用MP?相关推荐

  1. MyBatis-学习笔记02【02.Mybatis入门案例】

    Java后端 学习路线 笔记汇总表[黑马程序员] MyBatis-学习笔记01[01.Mybatis课程介绍及环境搭建][day01] MyBatis-学习笔记02[02.Mybatis入门案例] M ...

  2. MyBatisPlus(一)MyBatisPlus介绍和入门案例

    文章目录 MyBatis-Plus 简介 特性 框架结构 入门案例 MyBatis-Plus 简介 MyBatis-Plus(简称MP)是一个MyBatis增强工具,在MyBatis的基础上只做增强不 ...

  3. mybatis的入门

    mybatis的环境搭建 第一步:创建maven工程并导入坐标         第二步:创建实体类和dao的接口         第三步:创建Mybatis的主配置文件                 ...

  4. mybatis基于注解的入门案例

    mybatis基于注解的入门案例:             把IUserDao.xml移除,在dao接口的方法上使用@Select注解,并且指定SQL语句             同时需要在SqlMa ...

  5. Mybatis学习IDEA(1)-环境搭建以及入门案例

    Mybatis的环境搭建: 第一步:创建Maven项目 new Project->Maven->next->GroupId(反写域名如:com.itheima)ArtifactID( ...

  6. MyBatis由浅入深学习总结之一:MyBatis入门案例

    一.MyBatis简介 MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名 ...

  7. MyBatis Plus简介和入门案例

    简介 MyBatis-Plus(以下简称MP)是一个 MyBatis 的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发.提高效率而生. 润物无声 只做增强不做改变,引入它不会对现有 ...

  8. (spingboot入门案例)SpingBoot整合mybatis(mySql)

    仅供参考 目录结构: 环境: idea,mysql(8.0.29) 1.新建项目 1. 2.Project SDK选择自己对应的java版本 url选第二个,使用阿里的镜像:http://start. ...

  9. idea springmvc_IDEA搭建SSM(spring+springmvc+mybatis)Maven项目的入门案例

    上一篇文章已经搭建好了SSM的框架,并且启动成功,今天来编写一下入门案例. 文章的主要内容: 1.hello world的编写 2.引入log4j,在控制台打印sql 3.增删改查的编写 一.在mys ...

  10. Mybatis(1)---入门篇单表查询

    1.Mybatis介绍 MyBatis 是一款优秀的持久层框架,它支持定制化 SQL.存储过程以及高级映射.MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集.MyBatis ...

最新文章

  1. bzoj3786星系探索 splay
  2. SVM中的Karush-Kuhn-Tucker条件和对偶问题
  3. 中国汽车脚垫市场消费趋势与营销渠道分析报告2022版
  4. JavaScript内核系列 第8章 面向对象的JavaScript(下)
  5. linux ftp 实例
  6. jenkins 基础配置安装(Ⅰ)
  7. 小米手机的专用计算机连接软件,详细教您小米手机怎么连接电脑
  8. 7620a无线中继模块(wisp)
  9. 关于软件测试的英语面试题,软件测试工程师英语面试题
  10. 后台得到ajax传来的参数,几种ajax传参数到后台获取的方法
  11. dalao的背包九讲
  12. 判断对象内的 属性是否为空
  13. Vue 使用特殊字体
  14. CommonUtils 工具类
  15. 爬杜蕾斯官方微博,内容太刺激了吧
  16. 【pandas问题】UnicodeDecodeError: ‘utf-8‘ codec can‘t decode byte 0xca in position 0: invalid continuati
  17. python 不能被2,3整除的数字
  18. 高德地图添加安全密钥
  19. win10重装系统后连不上公司服务器,Win10电脑重装系统后不能上网怎么办?
  20. python三级_Python三级目录展示方法

热门文章

  1. 高校如何优雅的使用Ipv6--抱着道长的大腿
  2. 该知道的都知道 不知道的慢慢了解 MySQL数据库操作
  3. css实现循环扩散光圈的效果
  4. ICLR 22 GIANT ,UIUC UCLA OGB榜单
  5. linux双系统无u盘安装教程视频教程,U盘安装Windows和Ubuntu 15.04双系统图解教程
  6. JavaScript 数组(二)数组练习
  7. ARM(ARM处理器) x64和x86
  8. 集成混合运动与大功率柔性操作的半人马救灾机器人(4)——项目成果展示
  9. 各有利弊,开源和商业软件应该怎么选?
  10. Bandizip下载安装教程