目录
一、SpringBoot整合Mybatis说明
1、Mybatis介绍
2、ORM思想
3、SpringBoot整合Mybatis流程
4、 @SpringBootTest
5、 Mybatis调用流程
二、MyBatisPlus
1、MP介绍
1.1 概念
1.2 MP的特点
2、MP单表操作入门案例
2.1 导入jar包
2.2 在pojo类中配置对象关系映射(ORM)
2.3 继承公共API接口
2.4 编辑YML配置文件
2.5 工具API测试
2.6 配置文件application.yml中打印日志设置
3、MP实现原理
4、MP用法练习
4.1 根据ID查询
4.2 指定属性值查询--对象封装,条件构造器
4.3 特殊字符查询
4.4 like关键字模糊查询
4.5 order by排序查询
4.6 in关键字两种查询方式
4.7 字符串判断的API:StringUtils--org.springframework.util
4.8 MP的更新操作
MyBatis 是一款优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射。MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。
概括: MyBatis 是一款优秀的持久层框架,并且在内部整合的了JDBC,简化了用户操作数据库的过程.
Mybatis是一个半自动化的ORM映射框架,是因为mybatis只完成了要求查询的结果集可以自动的封装为对象 (读)这一步。
对象关系映射(英语:Object Relational Mapping,简称ORM,或O/RM,或O/R mapping),是一种程序设计技术,用于实现面向对象编程语言里不同类型系统的数据之间的转换。从效果上说,它其实是创建了一个可在编程语言里使用的“虚拟对象数据库”。如今已有很多免费和付费的ORM产品,而有些程序员更倾向于创建自己的ORM工具。
核心知识:
宗旨: 以对象的方式操作数据库
1. 要求查询的结果集可以自动的封装为对象 (读)
2. 利用对象封装数据,之后(自动)动态的生成Sql语句执行相关操作. (更新)
导入依赖jar包 数据库驱动/JDBC包/Spring整合Mybatis包
编辑application.yml文件 配置数据源/配置Spring整合Mybatis
编辑Mybatis 接口文件/编辑xxx.xml映射文件
通过@MapperScan为接口创建代理对象.
说明: 该注解是SpringBoot程序 为了简化后端代码测试 提供了专门的测试API.
关键点: 测试时需要Spring容器管理对象,同时将测试的对象获取 之后进行测试.
注意事项: 测试注解只能在测试包中运行.
1、Spring容器为接口创建代理对象. Spring容器启动对象立即创建
2、根据 @Autowired 注解动态注入Mapper接口的代理对象
3、用户通过Mapper接口调用方法.(执行业务操作)
4、Mybatis根据接口方法动态匹配xml的映射文件
5、Mybatis将结果集封装为对象 之后返回.
核心思想: 利用对象操作数据库 单表查询几乎不写Sql
基于springboot整合mybatis案例进行Mp增强测试
说明:MybatisPlus对mybatis的增强(包含),所有jar包只需要导入MP的即可.原有的Mybatis需要删除.
org.springframework.boot
spring-boot-starter-parent
2.5.2
1.8
true
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-test
test
org.springframework.boot
spring-boot-devtools
org.projectlombok
lombok
mysql
mysql-connector-java
5.1.48
runtime
org.springframework.boot
spring-boot-starter-jdbc
com.baomidou
mybatis-plus-boot-starter
3.4.3
org.springframework.boot
spring-boot-maven-plugin
2.5.2
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;
/**对象关系映射配置:
* 1、User对象需要与demo_user表绑定
* 2、User对象中的属性与表中的字段一一绑定,@TableName,@TableId,@TableField*/
@Data
@Accessors(chain = true)
@TableName(value = "demo_user")//相当于key=value,表名以表为准,严格区分大小写
public class User implements Serializable {
/*主键自增*/
@TableId(type = IdType.AUTO)
private Integer id;
//如果属性名与字段同名(包括驼峰规则)可省略@TableField注解,不一样时一定要写
//@TableField("name")
private String name;
//@TableField("age")
private Integer age;
//@TableField("sex")
private String sex;
}
加泛型对象是为了使用泛型对象的类型User
找不到映射文件时进行强制加载全部映射文件:classpath*:/mybatis/*.xml
测试类执行增删改时,不需要在接口中和映射文件中写方法了,直接在测试类创建对象,用对象操作
@SpringBootTest
public class TestSpringBoot {
@Autowired
private UserMapper userMapper; //代理对象
/**
* 新增用户
* Mybatis: 1.mapper接口 2.xml映射 Sql
* MP: 调用接口方法
*/
@Test
public void testInsert(){
User user = new User();
user.setName("吴亦凡").setAge(30).setSex("男");
//单表操作几乎不写Sql
userMapper.insert(user);
//UserMapper.insert(user);报错,类型调用只能调用静态方法
}
}
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
#SpringBoot整合MP
mybatis-plus:
type-aliases-package: com.jt.pojo
mapper-locations: classpath:/mybatis/*.xml
configuration:
map-underscore-to-camel-case: true
# Mapper接口执行 打印Sql日志
logging:
level:
com.jt.mapper: debug
控制台显示日志:
1)用户执行User对象入库操作,userMapper.insert(user)
2)由于接口方法中需要传递泛型对象,则根据用户配置查找对应的泛型对象
3)根据用户的接口获取Mapper接口的父级接口BaseMapper
4)根据User.class动态获取@TableName(“demo_user”)获取对象对应的表名,之后通过@TableField(“name”)绑定与之对应的字段,至此对象与表完成了映射
5)根据上述的映射关系,动态的拼接SQL语句
例子: userMapper.insert(user对象) 如何转化Sql?
**insert into 表名(字段名…) values (属性值…)
insert into demo_user(id,name,age,sex) values (“吴xx”,xx,xx,xx)
**
6)MP将动态生成的Sql交给Mybatis执行最终实现数据入库操作!!!
//1:根据id=1查询数据,id=主键
@Test
public void getUserById(){
User user = userMapper.selectById(1);
System.out.println(user);
}
配置文件中配置日志以便查看控制台sql语句:
//2.name=“王昭君” 和sex=“女” 查询数据.
@Test
public void getUserByAS(){
/*构造条件构造器,动态拼接where条件*/
//1.先封装属性
User user = new User();
user.setName("王昭君").setSex("女");
//2.根据对象中不为null的属性生成where条件,默认都是and 连接
QueryWrapper queryWrapper = new QueryWrapper(user);
List list = userMapper.selectList(queryWrapper);
System.out.println(list);
}
> gt,< lt, = eq
>= ge,<= le
/**3.根据age>18岁 or sex=“女” 查询数据
* SQL语句:select * from demo_user where age>18 or sex="女"
* 特殊字符包括:> gt,< lt, = eq
* >= ge,<= le
**/
@Test
public void getUserAS(){
QueryWrapper queryWrapper = new QueryWrapper();//加泛型可以连续.sql语句
// queryWrapper.gt("age", 18)
// .eq("sex", "女");
//默认是and,如果是age>18 或者 sex="女",使用.or()
queryWrapper.gt("age", 18)
.or()
.eq("sex", "女");
List userList = userMapper.selectList(queryWrapper);
System.out.println(userList);
}
/**4.查询name中包含“君”字的数据
* sql语句:select * from demo_user where name="%君%"*/
@Test
public void testLike(){
QueryWrapper queryWrapper = new QueryWrapper();
//包含“君”,like
queryWrapper.like("name", "君");
//以“君”结尾likeleft,以“君”开头likeright
//queryWrapper.likeLeft("name","君");
//不包含“君”notlike
//queryWrapper.notLike("name", "君");
List userList = userMapper.selectList(queryWrapper);
System.out.println(userList);
}
orderByASc()升序,orderByDesc()降序
/**5.查询age>18 的用户,按照年龄降序排列,如果年龄相同按照sex排列*/
@Test
public void testOrderBy(){
QueryWrapper queryWrapper = new QueryWrapper();
queryWrapper.gt("age",18)
.orderByDesc("age", "sex");
List userList = userMapper.selectList(queryWrapper);
System.out.println(userList);
}
注意:
1)单表查询时,in和or效率相差不大
2)多表查询时,建议使用or,性能更快
3)Object...叫作可变参数类型:
1.可变参数类型的数据结构实质是一个数组
2.定义可变参数类型时,必须位于方法参数的最后
方法1:条件构造器
@Test
public void getIn1(){
QueryWrapper queryWrapper = new QueryWrapper();
queryWrapper.in("id",1,3,5,6,7);
List userList = userMapper.selectList(queryWrapper);
System.out.println(userList);
}
方法2:MP特殊方法调用,尽量使用对象类型,因为对象有方法可以被使用
@Test
public void getIn2(){
Integer[] ids=new Integer[]{1,3,5,6,7};
//将数组转为集合
List idsList = Arrays.asList(ids);
List userList = userMapper.selectBatchIds(idsList);
System.out.println(userList);
}
正常情况下where条件有多个条件时,如果第一条件为空,就不会执行整个where条件,现在加入字符串判断API,目的是where多条件有一个为空时能保证另外一个条件也能执行拼接where条件
1)不加判断时:
@Test
public void testSelectNS(){
String name =null;
String sex = "女";
QueryWrapper queryWrapper = new QueryWrapper();
//判断是否有值
// boolean nameFlag = StringUtils.hasLength(name);
// boolean sexFlag = StringUtils.hasLength(sex);
queryWrapper.eq("name","name")
.eq("sex", sex);
List userList = userMapper.selectList(queryWrapper);
System.out.println(userList);
}
控制台的sql语句:结果是一个空数组
2)当加入字符串判断API时:
/**7.根据name和sex 动态查询数据库
* 动态sql实现:condition 参数
* boolean类型 true:拼接where条件
* false:不拼接整个where条件,但条件之前的sql语句还是执行
*加入字符串判断的API:StringUtils--org.springframework.util
*目的是where多条件有一个为空时能保证另外一个条件也能执行拼接where条件*/
@Test
public void testSelectNS(){
String name =null;
String sex = "女";
QueryWrapper queryWrapper = new QueryWrapper();
//判断是否有值
boolean nameFlag = StringUtils.hasLength(name);
boolean sexFlag = StringUtils.hasLength(sex);
queryWrapper.eq(nameFlag,"name",name)
.eq(sexFlag,"sex", sex);
List userList = userMapper.selectList(queryWrapper);
System.out.println(userList);
}
控制台的sql语句:拼接有值的where条件进行查询
但是,当name和sex值都为空时,控制台的sql语句是:查询整个demo_user表
@Test
public void testUpdate(){
User user = new User();
user.setName("祝君好运").setAge(100);
UpdateWrapper updateWrapper = new UpdateWrapper<>();
updateWrapper.eq("name","吴亦凡");
int row = userMapper.update(user,updateWrapper);
System.out.println(row);
}
// name="云英" sex="男" age="16"
@Test
public void testUpdateById(){
User user = new User();
user.setId(246).setName("云英").setSex("男").setAge(16);
//where id=xxx, 其他不为null的属性当作set条件.
userMapper.updateById(user);
}
//修改Id=x的数据,name=“云缨”,sex=“男”
@Test
public void testUpdateId(){
User user = new User();
user.setName("云缨").setSex("男").setAge(16);
UpdateWrapper updateWrapper = new UpdateWrapper();
updateWrapper.eq("id", 235);
userMapper.update(user, updateWrapper);
}