一MybatisPlus(MP)介绍
MyBatis-Plus(简称 MP)是一个 MyBatis 的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。
二MybatisPlus(MP)特性
1无侵入:只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑
2损耗小:启动即会自动注入基本 CURD,性能基本无损耗,直接面向对象操作
3强大的 CRUD 操作:内置通用 Mapper、通用 Service,仅仅通过少量配置即可实现单表大部分 CRUD 操作,更有强大的条件构造器,满足各类使用需求
4支持 Lambda 形式调用:通过 Lambda 表达式,方便的编写各类查询条件,无需再担心字段写错
5支持主键自动生成:支持多达 4 种主键策略(内含分布式唯一 ID 生成器 - Sequence),可自由配5置,完美解决主键问题
6支持 ActiveRecord 模式:支持 ActiveRecord 形式调用,实体类只需继承 Model 类即可进行强大的 CRUD 操作
7支持自定义全局通用操作:支持全局通用方法注入( Write once, use anywhere )
9内置代码生成器:采用代码或者 Maven 插件可快速生成 Mapper 、 Model 、 Service 、 Controller 层代码,支持模板引擎,更有超多自定义配置等您来使用
9内置分页插件:基于 MyBatis 物理分页,开发者无需关心具体操作,配置好插件之后,写分页等同于普通 List 查询
10分页插件支持多种数据库:支持 MySQL、MariaDB、Oracle、DB2、H2、HSQL、SQLite、Postgre、SQLServer 等多种数据库
11内置性能分析插件:可输出 Sql 语句以及其执行时间,建议开发测试时启用该功能,能快速揪出慢查询
12内置全局拦截插件:提供全表 delete 、 update 操作智能分析阻断,也可自定义拦截规则,预防误操作
三JPA思想
JPA是Java Persistence API的简称,中文名Java持久层API,是JDK 5.0注解或XML描述对象-关系表的映射关系,并将运行期的实体对象持久化到数据库中。
Sun引入新的JPA ORM规范出于两个原因:其一,简化现有Java EE和Java SE应用开发工作;其二,Sun希望整合ORM技术,实现天下归一。
优化方法:
sql语句入库: insert into user (xxx,xxx,xxx) values("xxxx","xxx",xxxxx"); 手写
jpa方式: userMapper.insert(user); 用户操作的是对象,至于sql则由程序自动完成!!!
四ORM介绍
对象关系映射(Object Relational Mapping,简称ORM)是通过使用描述对象和数据库之间映射的元数据,将面向对象语言程序中的对象自动持久化到关系数据库中。本质上就是将数据从一种形式转换到另外一种形式。 这也同时暗示着额外的执行开销;然而,如果ORM作为一种中间件实现,则会有很多机会做优化,而这些在手写的持久层并不存在。 更重要的是用于控制转换的元数据需要提供和管理;但是同样,这些花费要比维护手写的方案要少;而且就算是遵守ODMG规范的对象数据库依然需要类级别的元数据。
总结: ORM表示对象关系映射.
1.对象与数据表映射关系
2.对象的属性与表的字段映射
五MP原理说明
想法: userMapper.insert(user对象),要求实现数据库的入库操作.
核心:以面向对象的方式操作数据库.
实现原理:
1.标识对象与表的映射关系.
-通过自定义的注解标识当前对象与表的映射关系
2.标识对象的属性与表中字段的映射关系.
-通过自定义的注解标识属性与字段的映射.
3.定义共同的API接口,在其中编辑单表的所有CURD操作.
4.将公共的方法,动态的转化为sql语句.之后交给Mybatis去执行. (框架自动实现)
例子:
1.入库user表
userMapper.insert(user);
sql: insert into user(id,name.age,sex) values (“1”,“tom”,18,“男”); 动态拼接而成的
2.入库dept表
deptMapper.insert(dept);
sql: insert into dept(xxx,xxx) values(“yyyy”,“yyyy”);
六SpringBoot整合MybatisPlus
1引入jar包
<!--spring整合mybatis-plus -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.2.0</version>
</dependency>
2对象与表关联配置
@Data
//@TableName("user") //1.定义对象与表的映射关系
//优化策略:如果表名及属性名称与表的名称一致,则可以省略 属性可以省略注解
@TableName
public class User {
@TableId(type=IdType.AUTO) //2.标识主键,主键自增
private Integer id;
//@TableField("name") //属性与字段的映射
private String name;
private Integer age;
private String sex;
}
3继承公共Mapper接口
//继承baseMapper并且指定泛型对象
//@Mapper
public interface UserMapper extends BaseMapper<User>{
//添加接口方法
List<User> findAll();
}
4编辑YML配置文件
说明:将mybatis修改为MybatisPlus的操作
#MybatisPlus配置信息
mybatis-plus: #润物细无声
#定义别名包 映射时自动的拼接包路径
type-aliases-package: com.jt.pojo
#扫描mapper的映射文件 必须有
mapper-locations: classpath:/mybatis/mappers/*.xml
#开启驼峰映射
configuration:
map-underscore-to-camel-case: true
5MP案例测试
/**
*面向对象的方式操作数据库
* 实现入库操作
*/
@Test
public void testInsert() {
User user = new User();
user.setName("MybatisPlus测试")
.setAge(18)
.setSex("男");
int rows = userMapper.insert(user);
System.out.println("入库成功!影响:"+rows+"行");
}
6添加sql日志
server:
port: 8090
servlet:
context-path: /
#由于pom.xml文件中添加jdbc的依赖包,所以该行必须配置
spring:
datasource:
#该驱动一般适用低版本的驱动链接. driver-class-name: com.mysql.jdbc.Driver
#如果使用最新版本的驱动则配置如下
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/jtdb?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf8&autoReconnect=true&allowMultiQueries=true
username: root
password: root
#MybatisPlus配置信息
mybatis-plus: #润物细无声
#定义别名包 映射时自动的拼接包路径
type-aliases-package: com.jt.pojo
#扫描mapper的映射文件 必须有
mapper-locations: classpath:/mybatis/mappers/*.xml
#开启驼峰映射
configuration:
map-underscore-to-camel-case: true
logging:
level: #日志配置
#哪个包路径的日志 日志级别
com.jt.mapper: debug
7日志展现
七MPAPI学习
1selectBatchIds
/*MybatisPlus API说明*/
/*案例1: 查询id号为 1,2,5,6,7数据
*sql: select * from user where id=1 and id=2 and......
* select * from user where id in (1,2,5,6,7)
*齐总说:(多表操作时)不要使用in 因为性能低.
*
* */
@Test
public void test01() {
Integer[] intArray = {1,2,5,6,7};
//controller中接收用户的参数一般都是数组
/*
* List<Integer> idList = new ArrayList<>(); idList.add(1); idList.add(2);
* idList.add(5); idList.add(6); idList.add(7);
*/
//代码优化 数组转化为集合
List<Integer> idList = Arrays.asList(intArray);
List<User> userList = userMapper.selectBatchIds(idList);
System.out.println(userList);
}
2selectById
/** 根据主键查询
* byId不代表具体的ID字段,代码主键信息
* selectById:根据主键查询
*/
@Test
public void test02() {
User user = userMapper.selectById(21);
System.out.println(user);
}
3selectByMap
/** 查询name="白骨精"sex="女"的数据
* 多条件查询:byMap
* 案例:
* name="白骨精"
* sex="女"
*/
@Test
public void test03() {
Map<String,Object> columnMap = new HashMap<>();
columnMap.put("name", "白骨精");
columnMap.put("sex", "女");
List<User> userList = userMapper.selectByMap(columnMap);
System.out.println(userList);
}
4selectList
/**查询ge大于18岁的 女性用户
* 条件构造器:动态的拼接sql语句中的where条件
* 需求: 查询age大于18岁的 女性用户.
* sql: select * from user where age >18 and sex='女'
* 语法: > gt, < lt, = eq, >=ge, <= le
* 一般左侧写字段,右侧写值. 不能互换
* 如果没有特殊的要求,则默认采用and符号进行连接
*/
@Test
public void test04() {
//定义条件构造器
QueryWrapper<User> queryWrapper = new QueryWrapper<User>();
queryWrapper.gt("age", 18)
.eq("sex", "女");
List<User> userList = userMapper.selectList(queryWrapper);
System.out.println(userList);
}
5Like
//案例
//1.name属性中包含"精"的数据,并且为女性
//2.name属性中以"孙"开头的数据,并且为女性
@Test
public void test05() {
//定义条件构造器
QueryWrapper<User> queryWrapper = new QueryWrapper<User>();
queryWrapper.like("name", "精")
.eq("sex", "女");
List<User> userList = userMapper.selectList(queryWrapper);
System.out.println(userList);
QueryWrapper<User> queryWrapper2 = new QueryWrapper<User>();
queryWrapper2.likeRight("name", "孙");
List<User> userList2 = userMapper.selectList(queryWrapper2);
System.out.println(userList2);
}
6between
//查询年龄在18-35之间 and name以"王"开头
@Test
public void test06() {
//定义条件构造器//1.name属性中包含"精"的数据,并且为女性
QueryWrapper<User> queryWrapper = new QueryWrapper<User>();
queryWrapper.between("age", 18, 35)
.likeRight("name", "王");
List<User> userList = userMapper.selectList(queryWrapper);
System.out.println(userList);
}
7orderBy
//查询年龄大于100岁的,并且按照年龄降序排列,如果年龄相同按照Id降序排列.
//SELECT id,sex,name,age FROM user WHERE (age > ?) ORDER BY age DESC , id DESC
@Test
public void test07() {
QueryWrapper<User> queryWrapper = new QueryWrapper<User>();
queryWrapper.gt("age",100)
.orderByDesc("age","id");
List<User> userList = userMapper.selectList(queryWrapper);
System.out.println(userList);
}
8inSql
/**
* 查询age < 100岁的用户,并且性别与name="孙尚香"的性别相同的的用户数据.
* insql: 查询的条件A必须通过查询的条件B获取
*/
@Test
public void test08() {
String name = "'孙尚香'"; //动态传参获取
QueryWrapper<User> queryWrapper = new QueryWrapper<User>();
queryWrapper.lt("age", 100)
.inSql("sex", "SELECT sex FROM USER WHERE NAME="+name);
List<User> userList = userMapper.selectList(queryWrapper);
System.out.println(userList);
}
9select
/**
* 需求说明:有时查询可能不需要查询全部字段,会挑选其中几个进行查询.
条件:查询age为18岁的用户的name和id.
案例1:SELECT id,sex,name,age FROM user WHERE (age = ?) 不满足要求
User(id=12, name=貂蝉, age=18, sex=女)
案例2:SELECT id,name FROM user WHERE (age = ?) 感觉完成要求
User(id=12, name=貂蝉, age=null, sex=null)
案例3:SELECT id,name FROM user WHERE (age = ?)
{name=貂蝉, id=12}
*/
@Test
public void test09() {
QueryWrapper<User> queryWrapper = new QueryWrapper<User>();
queryWrapper.select("id","name").eq("age", 18);
List<User> userList = userMapper.selectList(queryWrapper);
System.out.println(userList);
QueryWrapper<User> queryWrapper2 = new QueryWrapper<User>();
queryWrapper2.select("id","name").eq("age", 18);
List<Map<String,Object>> listMap =
userMapper.selectMaps(queryWrapper2);
System.out.println(listMap);
}
10Condition
/**
* Condition: true时,则添加where条件
* false时,跳过
* 条件:以name和sex不为null的数据当做where条件.
* 非空条件查询
*
* 模拟mybatis中的动态sql的写法 由Condition进行控制
*/
@Test
public void test10() {
String name = "貂蝉"; //用户传递的参数
Integer age = 18;
QueryWrapper<User> queryWrapper = new QueryWrapper<User>();
queryWrapper.eq(!StringUtils.isEmpty(name), "name",name);
queryWrapper.eq( age!=null, "age",age);
List<User> userList = userMapper.selectList(queryWrapper);
System.out.println(userList);
}
11根据对象查询
/**
* 根据对象查询数据
*/
@Test
public void test11() {
User user = new User(); //用户数据的传递,采用user对象的方式接收
user.setName("王昭君");
user.setSex("女");
//用户要求根据传递的对象进行查询,
//根据对象中不为null的属性之后拼接where条件
QueryWrapper<User> queryWrapper = new QueryWrapper<User>(user);
List<User> userList = userMapper.selectList(queryWrapper);
System.out.println(userList);
//查询全部数据
List<User> userList2 = userMapper.selectList(null);
//userMapper.selectObjs(queryWrapper) 只查询第一列(主键)
System.out.println(userList2);
}
12删除操作
/**
* 用户删除操作
* 说明:将name属性中为null的数据删除.
*/
@Test
public void test13() {
//userMapper.deleteById(id); //传递主键,之后删除
//userMapper.deleteBatchIds(idList); //根据id批量删除数据.
//userMapper.deleteByMap(columnMap) //根据指定的字段删除数据.
QueryWrapper<User> queryWrapper = new QueryWrapper<User>();
queryWrapper.isNull("name");
int rows = userMapper.delete(queryWrapper);
System.out.println("影响行数:"+rows);
}
13更新操作
/**
* 1.根据主键进行修改.
* 要求: id=50号的信息,修改为name="张娜拉" age= 19 sex=女
* 遭到封杀
*/
@Test
public void test14() {
User user = new User();
user.setId(50).setName("张娜拉").setAge(19).setSex("女");
//如何解析sql byId说明 只有id属性充当where条件 其余属性充当set条件.
//如果获取主键信息时使用
int rows = userMapper.updateById(user);
System.out.println("影响的行数:"+rows);
//2. entity:需要修改的数据
// updateWrapper: 修改的条件
User user2 = new User();
user2.setAge(25).setSex("男");
UpdateWrapper<User> updateWrapper= new UpdateWrapper<User>();
updateWrapper.eq("id", 50);
//具有通用性.任何条件都可以使用update(xx,xxx)
userMapper.update(user2, updateWrapper);
}