1、工程创建
1.1初始化工程
注意:写name 和 Group
name:工程名 Group:是项目的包的名字
选择 Lombok依赖
注意: 环境是springboot 2.7.0
2、application.yml文件的配置
spring:
application:
name: Mybatis_Plus-test
datasource:
username: root
password: root
url: jdbc:mysql://localhost:3306/mp?useSSL=false&useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8
driver-class-name: com.mysql.cj.jdbc.Driver
web:
resources:
static-locations: /META-INF/resources/,classpath:/resources/,classpath:/static/,classpath:/public/,classpath:/templates/
mybatis-plus:
global-config:
db-config:
#设置实体类的表的统一前缀
table-prefix: tbl_
#设置统一的主键生成策略
id-type: auto
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
3、导入pom文件的依赖:
建议直接覆盖所有
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<!--导入配置文件处理器,配置文件进行绑定就会有提示-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</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-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.29</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.0</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>3.5.1</version>
</dependency>
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.31</version>
</dependency>
4、创建数据库和表
-- 创建库
CREATE DATABASE 数据库名;
-- 使用库
USE 数据库名;
-- 创建表
CREATE TABLE 数据表名(
id INT(11) PRIMARY KEY AUTO_INCREMENT, 主键设置,自动增长
last_name VARCHAR(50),
email VARCHAR(50),
gender CHAR(1),
age int
); 表名 字段名 值
INSERT INTO tbl_employee(last_name,email,gender,age) VALUES('Tom','tom@atguigu.com',1,22);
INSERT INTO tbl_employee(last_name,email,gender,age) VALUES('Jerry','jerry@atguigu.com',0,25);
INSERT INTO tbl_employee(last_name,email,gender,age) VALUES('Black','black@atguigu.com',1,30);
INSERT INTO tbl_employee(last_name,email,gender,age) VALUES('White','white@atguigu.com',0,35);
5、创建包entity创建实体类,加入注解
注意:加入注解:@Data
@AllArgsConstructor
@NoArgsConstructor
@EqualsAndHashCode
@TableName(“tbl_employee”)
package com.bjpowernode.mybatis_plustest.pojo;
import com.baomidou.mybatisplus.annotation.*;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
@EqualsAndHashCode
@TableName("tbl_employee")
public class Employee {
@TableId(type = IdType.AUTO)
private Integer id ;
@TableField(value = "last_name")
private String lastName1;
private String email ;
private Integer gender ;
private Integer age ;
//逻辑删除的方法 就是数据库中的数据不删除.但是查询出的数据没有了。
//当数据库中的字段的值为1的时候,表示逻辑删除成功。
//逻辑删除后的数据不能被修改。
//逻辑删除必须使用创建集合的办法 List<Long> list = Arrays.asList(220L);
@TableLogic
private Integer is_deleted;
}
6、创建dao层,创建mapper包,创建对应实体类的接口,创建对象
注意:继承BaseMapper接口,并且BaseMapper接口必须指定实体类的类型,mapper文件的名字为s实体类m名+mapper
package com.bjpowernode.mybatis_plustest.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.bjpowernode.mybatis_plustest.pojo.Employee;
import org.apache.ibatis.annotations.Mapper;
@Mapper (指定实体类的类型)
public interface Employeemapper extends BaseMapper<Employee> {
}
6.1在启动类上加入扫描dao层包的注解
注意:copypath选最后一个
package com.bjpowernode.mybatis_plustest;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
@MapperScan("com.bjpowernode.mybatis_plustest.mapper")
public class MybatisPlusTestApplication {
public static void main(String[] args) {
SpringApplication.run(MybatisPlusTestApplication.class, args);
}
}
7、创建测试类
注意:测试类在src/test路径下,创建时加@SpringBootTest依赖就成了测试类
package com.bjpowernode.mybatis_plustest;
import com.bjpowernode.mybatis_plustest.mapper.Employeemapper;
import com.bjpowernode.mybatis_plustest.pojo.Employee;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@SpringBootTest
class MybatisPlusTestApplicationTests {
@Autowired
private Employeemapper employeemapper;
@Test
void contextLoads() {
List<Employee> list = employeemapper.selectList(null);
list.forEach(System.out::println);
}
@Test
public void testInsert(){
Employee user=new Employee();
user.setAge(24);
user.setLastName("最后");
user.setEmail("1271839347@qq.com");
user.setGender(0);
int insert = employeemapper.insert(user);
System.out.println("添加的行数是:"+insert);
System.out.println("id"+user.getId());
}
@Test
public void testDelete(){
//删除的方法
// int i = employeemapper.deleteById(8);
// System.out.println("返回的值是"+i);
//
// //删除,使用Map集合做条件过滤
// Map<String,Object> map=new HashMap<>();
// map.put("last_name","white");
// map.put("age",35);
// int result = employeemapper.deleteByMap(map);
// System.out.println("result:"+result);
(使数据转换为集合的方法)
注意:集合中的数据对应数据库中的id字段,但是要加long
List<Long> list = Arrays.asList(1L, 2L, 3L);
int result2 = employeemapper.deleteBatchIds(list);
System.out.println("result="+result2);
}
}
7、增强功能(自定义功能)
7.1 在resources目录下创建mapper包,创建mybatis-mapper文件,创建后默认是接口名.xml文件
<?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.bjpowernode.mybatis_plustest.mapper.Employeemapper">
select对应查询方法 对应接口中的方法名 接口中方法的返回值
<select id="selectMapByIdPang" resultType="map">
select last_name,email,gender,age from tbl_employee where id =#{id}
</select>
</mapper>
7.1dao层中添加方法
package com.bjpowernode.mybatis_plustest.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.bjpowernode.mybatis_plustest.pojo.Employee;
import jdk.nashorn.internal.ir.CallNode;
import org.apache.ibatis.annotations.Mapper;
import java.util.Map;
@Mapper
public interface Employeemapper extends BaseMapper<Employee> {
//接口中写方法
Map<String,Object> selectMapByIdPang(Integer id);
}
8、service层的编写
8.1编写对应的service包,service中的类的名字是实体类的名+service
service层中继承IService方法泛型是对应的实体类
package com.bjpowernode.mybatis_plustest.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.bjpowernode.mybatis_plustest.pojo.Employee;
//继承IService方法
public interface EmployeeService extends IService<Employee> {
}
8.2
创建对应的实现类实现类名是实体类+Service+Impl
8.3
实现自己创建的service,并且继承Mybatis-Plus框架的方法ServiceImpl<mapper文件, 实体类>
package com.bjpowernode.mybatis_plustest.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bjpowernode.mybatis_plustest.mapper.Employeemapper;
import com.bjpowernode.mybatis_plustest.pojo.Employee;
import com.bjpowernode.mybatis_plustest.service.EmployeeService;
//ServiceImplMybatis-Plus中的方法
public class EmployeeServiceImpl extends ServiceImpl<Employeemapper, Employee> implements EmployeeService {
}
9、serveice层方法的测试
9.1、测试查询数据总数和添加方法的测试
在测试中调用service层,加入@SpringBootTest注解
package com.bjpowernode.mybatis_plustest;
import com.bjpowernode.mybatis_plustest.pojo.Employee;
import com.bjpowernode.mybatis_plustest.service.EmployeeService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.ArrayList;
import java.util.List;
@SpringBootTest
public class MyBatisPlusApplicationTests {
@Autowired
private EmployeeService employeeService;
@Test
public void testGetCount(){
//查询数据库中总数据数的方法。
int count = employeeService.count();
System.out.println("总记录数是:"+count);
}
@Test //测试批量添加的方法
public void testInsertMore(){
//创建集合
List<Employee> list=new ArrayList<>();
//利用for循环批量创建对象
for(int i=1;i<=10;i++){
Employee employee=new Employee();
employee.setLastName("盘网上搜"+i);
employee.setAge(20+i);
//employee.setEmail("@121212");
//employee.setGender(0);
//把对象放入集合
list.add(employee);
}
//调用Mybatis_Puls中的方法插入
boolean b = employeeService.saveBatch(list);
System.out.println(b);
}
}
9.2增改删查的测试
package com.bjpowernode.mybatis_plustest;
import com.bjpowernode.mybatis_plustest.mapper.Employeemapper;
import com.bjpowernode.mybatis_plustest.pojo.Employee;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@SpringBootTest
class MybatisPlusTestApplicationTests {
@Autowired
private Employeemapper employeemapper;
@Test
void contextLoads() {
//查询的方法(全部查询)
List<Employee> list = employeemapper.selectList(null);
list.forEach(System.out::println);
}
@Test
public void testInsert(){
Employee user=new Employee();
user.setAge(20);
user.setLastName1("keneng");
user.setEmail("1271839347@qq.com");
user.setGender(0);
int insert = employeemapper.insert(user);
System.out.println("添加的行数是:"+insert);
System.out.println("id"+user.getId());
}
@Test
public void testDelete(){
//删除的方法
// int i = employeemapper.deleteById(8);
// System.out.println("返回的值是"+i);
//
// //删除,使用Map集合做条件过滤
// Map<String,Object> map=new HashMap<>();
// map.put("last_name","white");
// map.put("age",35);
// int result = employeemapper.deleteByMap(map);
// System.out.println("result:"+result);
List<Long> list = Arrays.asList(12L, 13L, 14L);
int result2 = employeemapper.deleteBatchIds(list);
System.out.println("result="+result2);
}
@Test
public void testUpdate(){
Employee user=new Employee();
user.setGender(0);
user.setAge(999);
user.setId(9);
user.setLastName1("可能");
user.setEmail("1271839347@qq.com");
int result = employeemapper.updateById(user);
System.out.println("result的结果是"+result);
}
@Test
public void testSelect(){
// //查询的方法(按照id查询)
// Employee employee = employeemapper.selectById(9);
//
// System.out.println(employee);
//把id放入集合,然后利用Mybatis-Plus方法放入集合,返回一个集合来存储
// List<Integer> integers = Arrays.asList(9, 10, 11);
// List<Employee> employees = employeemapper.selectBatchIds(integers);
//
//
//
//
// //集合中有.forEach方法方法中的(System.out::println)可以输出数据库中的表
// employees.forEach(System.out::println);
//String为key ,Object为值
// HashMap<String, Object> map = new HashMap<>();
// //可以为筛选条件,"Jack"为筛选的值
// map.put("last_name","最后");
// map.put("age",20);
//传入一个map集合的方法
// List<Employee> user = employeemapper.selectByMap(map);
// user.forEach(System.out::println);
Map<String, Object> map = employeemapper.selectMapByIdPang(9);
}
}
测试条件增改删查的方法
package com.bjpowernode.mybatis_plustest;
import com.baomidou.mybatisplus.core.conditions.AbstractWrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.bjpowernode.mybatis_plustest.mapper.Employeemapper;
import com.bjpowernode.mybatis_plustest.pojo.Employee;
import org.junit.jupiter.api.Test;
import org.junit.platform.commons.util.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.List;
//组件自动装配的方法
@SpringBootTest
public class MybatisPlusWrapperTest {
@Autowired
private Employeemapper employeemapper;
//测试条件查询
@Test
public void test01(){
//查询用户名包含a,年龄在20到30之间,邮箱信息不为null的用户信息
//MybatisPlus中有QueryWrapper类也叫条件构造器
//实体类名称
QueryWrapper<Employee> queryWrapper =new QueryWrapper<>();
//like用来筛选 //包含的值 //值为20到30之间 //不等于空的值
queryWrapper.like("last_name", "最后").between("age",20,30).isNotNull("email");
List<Employee> employees = employeemapper.selectList(queryWrapper);
employees.forEach(System.out::println);
}
//测试条件排序查询的方法
@Test
public void test02(){
//查询用户信息,按照年龄的降序排序,若年龄相同,则按照id升序排序
//实体类名称
QueryWrapper<Employee> queryWrapper =new QueryWrapper<>();
//Desc是降序 Asc是升序, 先点击的为先筛选,后点击的为后筛选。
queryWrapper.orderByDesc("age").orderByAsc("id");
List<Employee> employees = employeemapper.selectList(queryWrapper);
employees.forEach(System.out::println);
}
//测试条件删除
@Test
public void test03(){
//删除邮箱地址
//实体类名
//queryWrapper为条件构造器
QueryWrapper<Employee> queryWrapper =new QueryWrapper<>();
queryWrapper.isNull("email");
//Mybatis_Plus中的delete方法。
int result = employeemapper.delete(queryWrapper);
System.out.println("受影响的行数"+result);
}
//测试条件修改的方法
@Test
public void test04(){
//实体类名
//queryWrapper为条件构造器
//将(年龄大于20并且用户名中包含有a)或邮箱为null的用户信息修改
QueryWrapper<Employee> queryWrapper =new QueryWrapper<>();
//gt(大于) //val代表值
queryWrapper.gt("age",20).like("last_name","我能").or().isNull("email");
//设置修改后的字段属性
Employee employee=new Employee();
employee.setLastName("刘亦菲");
employee.setEmail("lyf5201314@qq.com");
//传入要设置好的修改的对象,和条件构造器。
int update = employeemapper.update(employee, queryWrapper);
System.out.println("修改的行数为"+update);
}
//测试条件优先级变化
@Test
public void test05(){
//将用户名中包含有a并且(年龄大于20或邮箱为null)的用户信息修改
//lambda中的条件优先执行
QueryWrapper<Employee> queryWrapper=new QueryWrapper<>();
//(这里面优先执行)
queryWrapper.like("last_name","刘亦菲").and(i->i.gt("age",20).or().isNull("email"));
Employee employee=new Employee();
employee.setLastName("可以");
employee.setEmail("lyf5201314@qq.com");
int update = employeemapper.update(employee, queryWrapper);
System.out.println("修改的行数为"+update);
}
//查询表中的某些字段
@Test
public void test06(){
//查询用户的用户名,年龄,邮箱
QueryWrapper queryWrapper=new QueryWrapper();
queryWrapper.select("id","last_name","age","email");
List list = employeemapper.selectMaps(queryWrapper);
list.forEach(System.out::println);
}
//测试子查询
//id小于等于100的功能
@Test
public void test07(){
QueryWrapper queryWrapper=new QueryWrapper();
queryWrapper.inSql("id","select id from tbl_employee where id <=100");
List list = employeemapper.selectList(queryWrapper);
list.forEach(System.out::println);
}
//使用UpdateWrapper修改数据
@Test
public void test08(){
UpdateWrapper<Employee> updateWrapper=new UpdateWrapper<>();
updateWrapper.like("last_name","我能1").and(i->i.gt("age",20).or().isNull("email"));
updateWrapper.set("last_name","我能").set("email","我可以的@万千瓦");
int update = employeemapper.update(null, updateWrapper);
System.out.println("修改了"+update);
}
//模拟开发中组装条件的情况
@Test
public void test09(){
QueryWrapper queryWrapper=new QueryWrapper();
String lastname="";
Integer ageBegin=20;
Integer ageEnd=30;
if(StringUtils.isNotBlank(lastname)){
//isNotBLank判断某个字符是否不为空字符串,不为null,不为空白符
queryWrapper.like("last_name",lastname);
}
if(ageBegin!=null){
//ge大于等于最小值
queryWrapper.ge("age",ageBegin);
}
if(ageEnd!=null){
//le小于最小值
queryWrapper.le("age",ageEnd);
}
List list = employeemapper.selectList(queryWrapper);
list.forEach(System.out::println);
}
//模拟开发中组装条件的情况
@Test
public void test10(){
QueryWrapper queryWrapper=new QueryWrapper();
String lastname="";
Integer ageBegin=20;
Integer ageEnd=30;
//String用StringUtil.isNotBlank判断
if(StringUtils.isNotBlank(lastname)){
//isNotBLank判断某个字符是否不为空字符串,不为null,不为空白符
queryWrapper.like("last_name",lastname);
}
if(ageBegin!=null){
//ge大于等于最小值
queryWrapper.ge("age",ageBegin);
}
if(ageEnd!=null){
//le小于等于最小值
queryWrapper.le("age",ageEnd);
}
List list = employeemapper.selectList(queryWrapper);
list.forEach(System.out::println);
}
//模拟开发中组装条件的情况
//只是test10简化写法
@Test
public void test11(){
QueryWrapper queryWrapper=new QueryWrapper();
String lastname="最后";
Integer ageBegin=20;
Integer ageEnd=30;
queryWrapper.like(StringUtils.isNotBlank(lastname), "last_name", lastname).ge(ageBegin != null, "age", ageBegin).le(ageEnd != null, "age", ageEnd);
List list = employeemapper.selectList(queryWrapper);
list.forEach(System.out::println);
}
//和test10一个性质,获取属性的方法不同
@Test
public void test12(){
LambdaQueryWrapper<Employee> queryWrapper=new LambdaQueryWrapper<>();
String lastname="最后";
Integer ageBegin=20;
Integer ageEnd=30;
//等于空 获取实体类属性 赋值
queryWrapper.like(StringUtils.isNotBlank(lastname), Employee::getLastName, lastname).ge(ageBegin != null, Employee::getAge, ageBegin).le(ageEnd != null, Employee::getAge, ageEnd);
List list = employeemapper.selectList(queryWrapper);
list.forEach(System.out::println);
}
//使用UpdateWrapper修改数据
@Test
public void test13(){
LambdaUpdateWrapper<Employee> updateWrapper=new LambdaUpdateWrapper<>();
updateWrapper.like(Employee::getLastName,"最后").and(i- >i.gt(Employee::getAge,20).or().isNull(Employee::getEmail));
updateWrapper.set(Employee::getLastName,"我能").set(Employee::getEmail,"我可以的@万千瓦");
int update = employeemapper.update(null, updateWrapper);
System.out.println("修改了"+update);
}
}
10、添加Mybatis_Plus中的分页插件的方法
创建cofig表示配置包,创建MybatisPlusConfig配置类,配置类上添加@Configuration表示是一个配置类,有配置类后将扫描Dao层的注解转移到配置类
package com.bjpowernode.mybatis_plustest.cofig;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
@MapperScan("com.bjpowernode.mybatis_plustest.mapper")
public class MybatisPlusConfig {
@Bean //MybatisPlusInterceptor是MybatisPlusInterceptor中的拦截器
public MybatisPlusInterceptor mybatisPlusInterceptor(){
MybatisPlusInterceptor interceptor=new MybatisPlusInterceptor();
//拦截器自带的方法 //设置数据库类型
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
return interceptor;
}
}
创建测试类测试分页方法
package com.bjpowernode.mybatis_plustest;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.bjpowernode.mybatis_plustest.mapper.Employeemapper;
import com.bjpowernode.mybatis_plustest.pojo.Employee;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import javax.annotation.Resource;
@SpringBootTest
public class MybatisPlusPlugins {
@Resource
private Employeemapper employeemapper;
@Test
public void testPage(){
//创建分页对象 //c
//对应的实体类 //当前向第几页 //显示是条数
Page<Employee> page=new Page<>(1,3);
employeemapper.selectPage(page, null);
//获取当前页数据
System.out.println(page.getRecords());
//获取总页数
System.out.println(page.getPages());
//获取总记录数
System.out.println(page.getTotal());
//判断是否有下一页
System.out.println(page.hasNext());
//判断是否有上一页
System.out.println(page.hasPrevious());
}
}
10、如果要再自定义的sql语句中使用分页插件的方法
如果要使用自定义的配置信息,必须要再Dao层中创建方法
package com.bjpowernode.mybatis_plustest.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.bjpowernode.mybatis_plustest.pojo.Employee;
import jdk.nashorn.internal.ir.CallNode;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.Map;
@Mapper
public interface Employeemapper extends BaseMapper<Employee> {
//接口中写方法
Map<String,Object> selectMapByIdPang(Integer id);
/*
通过年龄查询用户信息并分页
*/
//创建的对象必须是Page对象(如果使用自己的sql语句) //第一返回值必须是page对象 //根据年龄查询用户信息
Page<Employee> selectPangVo(@Param("page") Page<Employee> page,@Param("age") Integer age);
}
10.2 定义select语句
<?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.bjpowernode.mybatis_plustest.mapper.Employeemapper">
<select id="selectMapByIdPang" resultType="map">
select last_name,email,gender,age from tbl_employee where id =#{id}
</select>
<select id="selectPangVo" resultType="Employee">
select id,lastName,age,email from tbl_employee where age >#{age}
</select>
</mapper>
11、Mybatis-Plus的乐观锁插件
数据库中增加商品表
CREATE TABLE t_product (
id BIGINT(20) NOT NULL COMMENT '主键ID',
NAME VARCHAR(30) NULL DEFAULT NULL COMMENT '商品名称',
price INT(11) DEFAULT 0 COMMENT '价格',
VERSION INT(11) DEFAULT 0 COMMENT '乐观锁版本号',
PRIMARY KEY (id)
);
添加一条数据
INSERT INTO t_product (id, NAME, price) VALUES (1, '外星人笔记本', 100);
添加一个实体类Product
package com.bjpowernode.mybatis_plustest.pojo;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
@EqualsAndHashCode
@TableName("t_product")
public class Product {
private Long id;
private String name;
private Integer price;
private Integer version;
}
添加一个Mapper接口ProductMapper
x 1public interface ProductMapper extends BaseMapper<Product> {}
测试方法
package com.bjpowernode.mybatis_plustest;
import com.bjpowernode.mybatis_plustest.mapper.ProductMapper;
import com.bjpowernode.mybatis_plustest.pojo.Product;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import javax.annotation.Resource;
@SpringBootTest
public class Mybatis_pulsProduct {
@Resource
private ProductMapper productMapper;
//1.小李获取商品价格
@Test
public void testProduct01(){
//1.小李获取商品价格
Product productLi = productMapper.selectById(1);
System.out.println("小李获取的商品价格为:" + productLi.getPrice());
//2.小王获取商品价格
Product productWang = productMapper.selectById(1);
System.out.println("小李获取的商品价格为:" + productWang.getPrice());
//3.小李修改商品价格+50
productLi.setPrice(productLi.getPrice()+50);
productMapper.updateById(productLi);
//4.小王修改商品价格-30
productWang.setPrice(productWang.getPrice()-30);
productMapper.updateById(productWang);
//5.老板查询商品价格
Product productBoss = productMapper.selectById(1);
System.out.println("老板获取的商品价格为:" + productBoss.getPrice());
}
}
//发现有问题
11.2解决乐观锁问题
package com.bjpowernode.mybatis_plustest.pojo;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
@EqualsAndHashCode
@TableName("t_product")
public class Product {
private Long id;
private String name;
private Integer price;
private Integer version;
@Version
private Integer version;
}
添加乐观锁插件配置
package com.bjpowernode.mybatis_plustest.cofig;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
@MapperScan("com.bjpowernode.mybatis_plustest.mapper")
public class MybatisPlusConfig {
@Bean //MybatisPlusInterceptor是MybatisPlusInterceptor中的拦截器
public MybatisPlusInterceptor mybatisPlusInterceptor(){
MybatisPlusInterceptor interceptor=new MybatisPlusInterceptor();
//添加分页插件 //设置数据库类型
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
//添加乐观锁插件
interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
return interceptor;
}
}
重新优化方法
package com.bjpowernode.mybatis_plustest;
import com.bjpowernode.mybatis_plustest.mapper.ProductMapper;
import com.bjpowernode.mybatis_plustest.pojo.Product;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import javax.annotation.Resource;
@SpringBootTest
public class Mybatis_pulsProduct {
@Resource
private ProductMapper productMapper;
//1.小李获取商品价格
@Test
public void testProduct01(){
//1.小李获取商品价格
Product productLi = productMapper.selectById(1);
System.out.println("小李获取的商品价格为:" + productLi.getPrice());
//2.小王获取商品价格
Product productWang = productMapper.selectById(1);
System.out.println("小李获取的商品价格为:" + productWang.getPrice());
//3.小李修改商品价格+50
productLi.setPrice(productLi.getPrice()+50);
productMapper.updateById(productLi);
//4.小王修改商品价格-30
productWang.setPrice(productWang.getPrice()-30);
int result = productMapper.updateById(productWang);
if(result == 0){
//操作失败,重试 //重新查询出来的对象,等于重新获取版本号
Product productNew = productMapper.selectById(1);
productNew.setPrice(productNew.getPrice()-30);
productMapper.updateById(productNew);
}
//5.老板查询商品价格
Product productBoss = productMapper.selectById(1);
System.out.println("老板获取的商品价格为:" + productBoss.getPrice());
}
}
12、通用枚举
表中的有些字段值是固定的,例如性别(男或女),此时我们可以使用MyBatis-Plus的通用枚举来实现
-
数据库表添加字段
sex
-
创建通用枚举类型
package com.bjpowernode.mybatis_plustest.enums;
import com.baomidou.mybatisplus.annotation.EnumValue;
public enum SexEnum {
//表示男
//表示MALE的默认值为1
MALE(1, "男"),
//表示女
FEMALE(2, "女");
@EnumValue //将注解所标识的属性的值存储到数据库中 //和数据库的字段对应
private int sex;
private String sexName;
//构造方法
SexEnum(Integer sex, String sexName) {
this.sex = sex;
this.sexName = sexName;
}
}
实体类中添加字段
package com.bjpowernode.mybatis_plustest.pojo;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.baomidou.mybatisplus.annotation.TableName;
import com.bjpowernode.mybatis_plustest.enums.SexEnum;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
@EqualsAndHashCode
@TableName("tbl_employee")
public class Employee {
@TableId(type = IdType.AUTO)
private Integer id ;
private String lastName;
private String email ;
private Integer gender ;
private Integer age ;
//添加枚举字段
private SexEnum sex;
@TableLogic
private Integer is_deleted;
}
测试枚举
package com.bjpowernode.mybatis_plustest;
import com.bjpowernode.mybatis_plustest.enums.SexEnum;
import com.bjpowernode.mybatis_plustest.mapper.Employeemapper;
import com.bjpowernode.mybatis_plustest.pojo.Employee;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import javax.annotation.Resource;
@SpringBootTest
public class Mybatis_pulsEnumTest {
@Resource
private Employeemapper employeemapper;
@Test
public void test(){
Employee employee=new Employee();
employee.setLastName("admin");
employee.setAge(33);
employee.setSex(SexEnum.MALE);
int result = employeemapper.insert(employee);
System.out.println("result:"+result);
}
}
配置扫描通用枚举
spring:
application:
name: Mybatis_Plus-test
datasource:
username: root
password: root
url: jdbc:mysql://localhost:3306/mp?useSSL=false&useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8
driver-class-name: com.mysql.cj.jdbc.Driver
web:
resources:
static-locations: /META-INF/resources/,classpath:/resources/,classpath:/static/,classpath:/public/,classpath:/templates/
mybatis-plus:
global-config:
db-config:
#设置实体类的表的统一前缀
table-prefix: tbl_
#设置统一的主键生成策略
id-type: auto
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
#配置类型别名对应的包
type-aliases-package: com.bjpowernode.mybatis_plustest.pojo
#扫描通用枚举的包
type-enums-package: com.bjpowernode.mybatis_plustest.enums
13、代码生成器
pom文件中添加依赖
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>3.5.1</version>
</dependency>
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.31</version>
</dependency>
测试类测试
package com.bjpowernode.mybatis_plustest;
import com.baomidou.mybatisplus.generator.FastAutoGenerator;
import com.baomidou.mybatisplus.generator.config.OutputFile;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
import java.util.Collections;
public class FastAutoGeneratorTest {
public static void main(String[] args) {
System.out.println(System.getProperty("user.dir"));
FastAutoGenerator.create("jdbc:mysql://localhost:3306/mp?useSSL=false&useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8",
"root", "root")
.globalConfig(builder -> {
builder.author("pangwanshan") // 设置作者
// .enableSwagger() // 开启 swagger 模式 需要导入swagger的包
// .fileOverride() // 覆盖已生成文件
.outputDir("D://test"); // 指定输出目录
})
.packageConfig(builder -> {
builder.parent("com.bjpowernode") // 设置父包名
.moduleName("mybatis_plustest") // 设置父包模块名
.pathInfo(Collections.singletonMap(OutputFile.mapperXml, "D://test")); // 设置mapperXml生成路径
})
.strategyConfig(builder -> {
builder.addInclude("tbl_employee") // 设置需要生成的表名
.addTablePrefix("t_", "c_"); // 设置过滤表前缀
})
.templateEngine(new FreemarkerTemplateEngine()) // 使用Freemarker引擎模板,默认的是Velocity引擎模板
.execute();
}
}
14、多数据源
适用于多种场景:纯粹多库、 读写分离、 一主多从、 混合模式等
场景说明:
我们创建两个库,分别为:mp
(以前的库不动)与mybatis_plus_1
(新建),将mp库的product
表移动到mybatis_plus_1库,这样每个库一张表,通过一个测试用例分别获取用户数据与商品数据,如果获取到说明多库模拟成功
CREATE DATABASE `mybatis_plus_1` /*!40100 DEFAULT CHARACTER SET utf8mb4 */;
use `mybatis_plus_1`;
CREATE TABLE product (
id BIGINT(20) NOT NULL COMMENT '主键ID',
name VARCHAR(30) NULL DEFAULT NULL COMMENT '商品名称',
price INT(11) DEFAULT 0 COMMENT '价格',
version INT(11) DEFAULT 0 COMMENT '乐观锁版本号',
PRIMARY KEY (id)
);
添加测试数据
INSERT INTO product (id, NAME, price) VALUES (1, '外星人笔记本', 100);
删除mp
库中的product
表
14.2新建工程引入依赖
自行新建一个Spring Boot工程并选择MySQL驱动及Lombok依赖
引入MyBaits-Plus的依赖及多数据源的依赖
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.0</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.29</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
引入多数据源依赖
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>dynamic-datasource-spring-boot-starter</artifactId>
<version>3.5.0</version>
</dependency>
14.3创建Mapper及Service
新建接口 EmployeeMapper
@Mapper
public interface EmployeeMapper extends BaseMapper<Employee> {
}
新建接口ProductMapper
@Mapper
public interface ProductMapper extends BaseMapper<Product> {
}
新建接口 EmployeeService
指定操作的数据源
public interface EmployeeService extends IService<Employee>{
}
新建Service接口ProductService
指定操作的数据源
public interface EmployeeService extends IService<Employee>{
}
创建实现类
@Service
public class EmployeeServiceImpl extends ServiceImpl<EmployeeMapper, Employee> implements EmployeeService {
}
@DS("master") //实现类上设置数据源
@Service
public class ProductServiceImpl extends ServiceImpl<ProductMapper, Product> implements ProductService {
}
添加appliction.yml配置文件
spring:
# 配置数据源信息
datasource:
dynamic:
# 设置默认的数据源或者数据源组,默认值即为master
primary: master
# 严格匹配数据源,默认false.true未匹配到指定数据源时抛异常,false使用默认数据源
strict: false
datasource:
master:
url: jdbc:mysql://localhost:3306/mp?characterEncoding=utf-8&useSSL=false
driver-class-name: com.mysql.cj.jdbc.Driver
username: root
password: root
slave_1:
url: jdbc:mysql://localhost:3306/mybatis_plus_1?characterEncoding=utf-8&useSSL=false
driver-class-name: com.mysql.cj.jdbc.Driver
username: root
password: root
编写测试方法
package com.atguigu.mybatis_pulsdata;
import com.atguigu.mybatis_pulsdata.Service.EmployeeService;
import com.atguigu.mybatis_pulsdata.Service.ProductService;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import javax.annotation.Resource;
//测试类不要忘了加注解!!
@SpringBootTest
public class TestDatasourceApplicationTests {
@Resource
EmployeeService employeeService;
@Resource
ProductService productService;
@Test
void contextLoads() {
//注意:数据库中无数据不会包空指针。
System.out.println(employeeService.getById(1));
System.out.println(productService.getById(1));
}
}
MyBatisX插件
MyBatis-Plus为我们提供了强大的mapper和service模板,能够大大的提高开发效率。
但是在真正开发过程中,MyBatis-Plus并不能为我们解决所有问题,例如一些复杂的SQL,多表联查,我们就需要自己去编写代码和SQL语句,我们该如何快速的解决这个问题呢,这个时候可以使用MyBatisX插件。
MyBatisX一款基于 IDEA 的快速开发插件,为效率而生。
安装MyBatisX插件
打开IDEA,File-> Setteings->Plugins->MyBatisX,搜索栏搜索MyBatisX然后安装。
快速生成代码
新建一个Spring Boot项目引入依赖(创建工程时记得勾选lombok及mysql驱动)
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.1</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>dynamic-datasource-spring-boot-starter</artifactId>
<version>3.5.0</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
配置数据源信息
spring:
datasource:
type: com.zaxxer.hikari.HikariDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/mybatis_plus?characterEncoding=utf-8&useSSL=false
username: root
password: root
填写数据库信息并保存
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OoTIJSUf-1654584808916)(庞万山Mybatis-Plus的框架使用.assets/屏幕截图 2022-06-07 134850.jpg)]
找到我们需要生成的表点击右键
继续填写信息
大功告成(真特么好用yyds)
快速生成CRUD
MyBaitsX可以根据我们在Mapper接口中输入的方法名快速帮我们生成对应的sql语句
CRUD的规则
BY后跟条件and加条件
Between 区间
OrderByAgeDesc 写法排序