Mybatis-plus入门
简介
这个官网的简介有点意思
为什么要学习mybatis-plus?(个人理解)
mybatis-plus的优点(和mybatis相比)
- mp不需要去写dao层mapper接口的映射.xml文件只需要继承一个BaseMapper
- 不需要书写mybatis-config主配置文件只需要在application.yaml中书写连接数据库的内容
- .yaml这种配置文件的书写格式精简了书写的内容
- 不需要去获取Sqlsession直接从spring容器中去获取XxxMapper对象即可完成简单CRUD
项目目录
搭建一个简单mybatis-plus开发环境
创建数据库表
create database mp;
use mp;
#创建用户表
CREATE TABLE user (
id BIGINT(20) PRIMARY KEY NOT NULL COMMENT '主键',
name VARCHAR(30) DEFAULT NULL COMMENT '姓名',
age INT(11) DEFAULT NULL COMMENT '年龄',
email VARCHAR(50) DEFAULT NULL COMMENT '邮箱',
manager_id BIGINT(20) DEFAULT NULL COMMENT '直属上级id',
create_time DATETIME DEFAULT NULL COMMENT '创建时间',
CONSTRAINT manager_fk FOREIGN KEY (manager_id)
REFERENCES user (id)
) ENGINE=INNODB CHARSET=UTF8;
#初始化数据:
INSERT INTO user (id, name, age, email, manager_id
, create_time)
VALUES (1087982257332887553, '大boss', 40, 'boss@baomidou.com', NULL
, '2019-01-11 14:20:20'),
(1088248166370832385, '王天风', 25, 'wtf@baomidou.com', 1087982257332887553
, '2019-02-05 11:12:22'),
(1088250446457389058, '李艺伟', 28, 'lyw@baomidou.com', 1088248166370832385
, '2019-02-14 08:31:16'),
(1094590409767661570, '张雨琪', 31, 'zjq@baomidou.com', 1088248166370832385
, '2019-01-14 09:15:15'),
(1094592041087729666, '刘红雨', 32, 'lhm@baomidou.com', 1088248166370832385
, '2019-01-14 09:48:16');
导入依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.3</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.schong</groupId>
<artifactId>testmp</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>testmp</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.1.2</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>5.1.7</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
创建实体类
package com.schong.domain;
import lombok.Data;
import java.time.LocalDateTime;
@Data
public class User {
private Long id;
private String name;
private Integer age;
private String email;
private Long managerId;
private LocalDateTime createTime;
}
编写实体类对应的dao层mapper
package com.schong.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.schong.domain.User;
public interface UserMapper extends BaseMapper<User> {
}
配置@MapperScan
package com.schong;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
@MapperScan("com.schong.dao")
public class TestmpApplication {
public static void main(String[] args) {
SpringApplication.run(TestmpApplication.class, args);
}
}
配置application.yaml
# 配置数据源
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/test_mybatis?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai
username: root
password: 1234
编写测试类
package com.schong;
import com.schong.dao.UserMapper;
import com.schong.domain.User;
import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.List;
@SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection")
@RunWith(SpringRunner.class)
@SpringBootTest
class TestmpApplicationTests {
@Autowired
UserMapper userMapper;
@Test
public void select(){
List<User> list = userMapper.selectList(null);
list.forEach(System.out::println);
}
}
测试结果
mybaties多数据源配置
为什么要配置多数据源(个人理解)?
-
起到备份作用
当主数据库的数据丢失的时候还有从库进行保障。
-
缓解单个数据库的压力
一般将主数据库用作增删改操作,从数据库用作查询操作。
依赖导入(pom.xml)
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>dynamic-datasource-spring-boot-starter</artifactId>
<version>3.0.0</version>
</dependency>
数据源链接配置(application.properties)
在这里我用的是两个数据库
正常的话应该用的是两个不同的数据库软件,这里就简单建两个数据库用用吧,主要是代码实现。
#多数据源数据库配置
#主数据库
#指定默认的数据源
spring.datasource.dynamic.primary=master
spring.datasource.dynamic.datasource.master.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.dynamic.datasource.master.url=jdbc:mysql://localhost:3306/ssm_schong?characterEncoding=UTF-8
spring.datasource.dynamic.datasource.master.username=root
spring.datasource.dynamic.datasource.master.password=1234
#从数据源
spring.datasource.dynamic.datasource.slave.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.dynamic.datasource.slave.url=jdbc:mysql://localhost:3306/ssm_schong_slave?characterEncoding=UTF-8
spring.datasource.dynamic.datasource.slave.username=root
spring.datasource.dynamic.datasource.slave.password=1234
操作多个数据库的代码写在service层
@Service
@Transactional
@DS("master")
public class StudentServiceImpl implements StudentService {
@Autowired
StudentDao dao;
@Override
@DS("slave")
public List<Student> findAll() {
return dao.selectList(null);
}
@Override
public void inster(Student student) {
dao.insert(student);
}
}
利用@DS注解实现数据源的切换
@DS中的值就是我们在application.properties中配置数据源时指定的数据源的名字
-
@DS注解可以作用在类和方法上
-
@DS注解的作用原则
-
局部大于整体原则
-
如果不设置,默认使用主数据源
-
数据库
主数据库
从库
测试
@SpringBootTest
public class TestMasterSlave {
@Autowired
StudentService service;
@Test
/*
这里测试的是查询,那么查询应该从从属数据库查询数据
*/
public void selectSlave(){
List<Student> students = service.findAll();
for (Student student : students) {
System.out.println(student);
}
}
@Test
public void inster(){
Student student = new Student().setId(11).setName("张三slave").setAge(66);
service.inster(student);
}
}
从库查询结果
主库插入结果
分页查询
数据库信息
#####分页查询代码
@Test
void test2(){
//分页查询,当前第一页,每页显示两条
IPage<Student> page = new Page<>(1,2);
IPage<Student> iPage = dao.selectPage(page, null);
//总记录数
long total = iPage.getTotal();
System.out.println(total);
//循环输出结果集中的数据
List<Student> students = iPage.getRecords();
for (Student student : students) {
System.out.println(student);
}
}
查询结果
根据查询结果发现我们分别输出了数据库的总条数和分页显示两条可是结果却和代码不符。
通过百度得知需要在项目里面写如下代码:包位置和dao层同级
@Configuration
@MapperScan("com.schong.dao")
public class MybatisPlusConfig {
// 最新版
@Bean
public PaginationInterceptor paginationInterceptor() {
PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
// 设置请求的页面大于最大页后操作, true调回到首页,false 继续请求 默认false
// paginationInterceptor.setOverflow(false);
// 设置最大单页限制数量,默认 500 条,-1 不受限制
// paginationInterceptor.setLimit(500);
// 开启 count 的 join 优化,只针对部分 left join
paginationInterceptor.setCountSqlParser(new JsqlParserCountOptimize(true));
return paginationInterceptor;
}
}
再次查询
条件分页查询
@Test
void test3(){
IPage<Student> page = new Page<>(2,2);
//只要是涉及到条件查询的带带就会使用他
QueryWrapper<Student> queryWrapper = new QueryWrapper<>();
queryWrapper.le("age",66);
IPage<Student> iPage = dao.selectPage(page, queryWrapper);
long total = iPage.getTotal();
System.out.println(total);
List<Student> students = iPage.getRecords();
for (Student student : students) {
System.out.println(student);
}
}
查询结果
//只要是涉及到条件查询的带带就会使用他
QueryWrapper<Student> queryWrapper = new QueryWrapper<>();
queryWrapper.le("age",66);
IPage<Student> iPage = dao.selectPage(page, queryWrapper);
long total = iPage.getTotal();
System.out.println(total);
List<Student> students = iPage.getRecords();
for (Student student : students) {
System.out.println(student);
}
}