赞
踩
目录
目录
- Spring容器为接口创建代理对象. Spring容器启动对象立即创建
- 根据 @Autowired 注解动态注入Mapper接口的代理对象
- 用户通过Mapper接口调用方法.(执行业务操作)
- Mybatis根据接口方法动态匹配xml的映射文件
(1.根据Mapper的接口路径匹配xml映射文件中的 com.jt.mapper.UserMapper
(2.根据接口的方法匹配xml映射文件中的sql id 之后执行Sql语句
(3.Mybatis将结果集封装为对象之后返回.
Mybatis是一种操作数据库的框架,提供一种Mapper类,支持让你用java代码进行增删改查的数据库操作,前提是你得先在xml中写好sql语句,但是每当要写一个业务逻辑的时候都要在DAO层写一个方法,再对应一个SQL,即使是简单的条件查询、或者是仅仅改变了一个条件都要在DAO层新增一个方法,还是有点麻烦。而MybatisPlus自动为Mybatis生成简单的增删改查SQL语句的工具,可以省去手写简单SQL语句的时间,只在XML中编写其它需要的SQL语句,所以MP与mybatis配合使用的话可以很好的提高开发效率。
Mybatis-Plus是一个Mybatis的增强工具,它在Mybatis的基础上做了增强,却不做改变。我们在使用Mybatis-Plus之后既可以使用Mybatis-Plus的特有功能,又能够正常使用Mybatis的原生功能。Mybatis-Plus是为简化开发、提高开发效率而生,但它也提供了一些很有意思的插件,比如SQL性能监控、乐观锁、执行分析等。
向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>

注意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;
- }

创建UserMapper.xml文件,里面包含大量的SQL语句
- <?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.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 > #{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 > #{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: 8090
-
- spring:
- datasource:
- driver-class-name: com.mysql.cj.jdbc.Driver
- url: jdbc:mysql://127.0.0.1:3306/jt?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf8&autoReconnect=true&allowMultiQueries=true
- username: root
- password: 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

包路径要与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);
- }

注释里的(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 {
- @Autowired
- private 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("成功");
- }
- }

代码整洁本身是为了降低修改成本的,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次。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。