springboot2.4.4整合mybatis
- 一、搭建工程
- 二、使用mybatis进行数据库操作
- 三、测试运行
- 四、总结
springboot目前已成为javaweb的主流开发框架,它就像一个万能胶,只要拉取相关依赖的starter,我们只需要做少量配置就能做到开箱即用。
mybatis是国内比较流行的持久层框架,即支持注解类型开发也支持xml类型开发,同时支持动态sql,非常灵活好用,spring也对该框架进行了适配,今天这篇博客的内容就是介绍如何使用springboot集成mybatis。
好啦,不罗嗦了正文开始!!!
一、搭建工程
- maven工程大家就自己建,我这里就不罗嗦了,下面为工程的pom文件,大家将该文件复制到自己的pom中,拉取相关依赖(电脑必须有网络)
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>quartz-job</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.4</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-batch</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.16</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.10</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-quartz</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.4</version>
</dependency>
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>4.1.0</version>
</dependency>
<!-- <dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
</dependency>
-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</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.batch</groupId>
<artifactId>spring-batch-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
<groupId>org.xerial</groupId>
<artifactId>sqlite-jdbc</artifactId>
<version>3.32.3.2</version>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.7.13</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
- 在resource文件夹下创建application.yml及application-dev.yml配置文件
application.yml
server:
port: 8080
spring:
profiles:
active: dev
#数据库配置splite数据库
#syx:
# database:
# url: jdbc:sqlite:D:/env/sqlite/sqlite-tools-win32-x86-3350500/sqlite-tools/mydb.db
# driver: org.sqlite.JDBC
# userName:
# passwd:
# validationQuery:
# initSize: 3
# minIdle: 3
# maxActive: 10
# checkTable: false
# maxWaitTime: 60000
# evictionRunTime: 60000
# minEvictionIdleTime: 300000
# keepAlive: true
# testWhileIdle: true
# testOnBorrow: true
# testOnReturn: false
# poolPreparedStatement: true
# maxPoolPreparedStatementSizePerConnection: 20
# validateQueryTimeOut: 3
#数据库配置mysql数据库
syx:
database:
url: jdbc:mysql://localhost:3306/mydb?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true
driver: com.mysql.cj.jdbc.Driver
userName: xxxx
passwd: xxx
validationQuery: select 1 from dual
initSize: 3
minIdle: 3
maxActive: 10
checkTable: false
maxWaitTime: 60000
evictionRunTime: 60000
minEvictionIdleTime: 300000
keepAlive: true
testWhileIdle: true
testOnBorrow: true
testOnReturn: false
poolPreparedStatement: true
maxPoolPreparedStatementSizePerConnection: 20
validateQueryTimeOut: 3
这里我把数据库的配置单独抽取为一个配置类,其中的一些参数在配置类中有注释。
application-dev.yml
mybatis:
mapper-locations: classpath:mapper/*Mapper.xml #mapper文件的路径
#showSql
logging:
level:
com:
syx:
dao: debug
dev的配置文件比较简单,主要是指定mybatis的mapper.xml文件的位置。
- 数据库配置类,主要是为了绑定application.yml中的数据库配置。
package com.syx.microapplication.base;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
/**
* @date: 2022-03-10 23:04
* <p>数据源配置参数</p>
*/
@Component
@ConfigurationProperties(prefix = "syx.database")
public class DataSourceConfigProperty {
private String url;
private String driver;
private String userName;
private String passwd;
private String validationQuery = "select 1 from dual";
//连接池初始大小
private String initSize = "3";
//最小连接数
private String minIdle = "3";
//最大连接数
private String maxActive ="10";
//是否开启表的初始化检查
private boolean checkTable = false;
//获取连接的最大等待时间单位为毫秒
private long maxWaitTime;
//空闲检测时间单位为毫秒
private long evictionRunTime;
//连接在池中最小生存时间单位毫秒
private long minEvictionIdleTime;
//
private boolean keepAlive;
private boolean testWhileIdle;
//获取连接时是否检测连接有效
private boolean testOnBorrow;
//连接归还时是否检测连接有效
private boolean testOnReturn;
//是否缓存PrepareStatement
private boolean poolPreparedStatement;
//每个连接的 PrepareStatement缓存大小
private int maxPoolPreparedStatementSizePerConnection;
//连接检测超时设置
private int validateQueryTimeOut;
public String getUrl() {
validate(url);
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getDriver() {
validate(driver);
return driver;
}
public void setDriver(String driver) {
this.driver = driver;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPasswd() {
return passwd;
}
public void setPasswd(String passwd) {
this.passwd = passwd;
}
public String getValidationQuery() {
return validationQuery;
}
public void setValidationQuery(String validationQuery) {
this.validationQuery = validationQuery;
}
public String getInitSize() {
return initSize;
}
public void setInitSize(String initSize) {
this.initSize = initSize;
}
public String getMinIdle() {
return minIdle;
}
public void setMinIdle(String minIdle) {
this.minIdle = minIdle;
}
public String getMaxActive() {
return maxActive;
}
public void setMaxActive(String maxActive) {
this.maxActive = maxActive;
}
public boolean isCheckTable() {
return checkTable;
}
public void setCheckTable(boolean checkTable) {
this.checkTable = checkTable;
}
public long getMaxWaitTime() {
return maxWaitTime;
}
public void setMaxWaitTime(long maxWaitTime) {
this.maxWaitTime = maxWaitTime;
}
public long getEvictionRunTime() {
return evictionRunTime;
}
public void setEvictionRunTime(long evictionRunTime) {
this.evictionRunTime = evictionRunTime;
}
public long getMinEvictionIdleTime() {
return minEvictionIdleTime;
}
public void setMinEvictionIdleTime(long minEvictionIdleTime) {
this.minEvictionIdleTime = minEvictionIdleTime;
}
public boolean isKeepAlive() {
return keepAlive;
}
public void setKeepAlive(boolean keepAlive) {
this.keepAlive = keepAlive;
}
public boolean isTestWhileIdle() {
return testWhileIdle;
}
public void setTestWhileIdle(boolean testWhileIdle) {
this.testWhileIdle = testWhileIdle;
}
public boolean isTestOnBorrow() {
return testOnBorrow;
}
public void setTestOnBorrow(boolean testOnBorrow) {
this.testOnBorrow = testOnBorrow;
}
public boolean isTestOnReturn() {
return testOnReturn;
}
public void setTestOnReturn(boolean testOnReturn) {
this.testOnReturn = testOnReturn;
}
public boolean isPoolPreparedStatement() {
return poolPreparedStatement;
}
public void setPoolPreparedStatement(boolean poolPreparedStatement) {
this.poolPreparedStatement = poolPreparedStatement;
}
public int getMaxPoolPreparedStatementSizePerConnection() {
return maxPoolPreparedStatementSizePerConnection;
}
public void setMaxPoolPreparedStatementSizePerConnection(int maxPoolPreparedStatementSizePerConnection) {
this.maxPoolPreparedStatementSizePerConnection = maxPoolPreparedStatementSizePerConnection;
}
public int getValidateQueryTimeOut() {
return validateQueryTimeOut;
}
public void setValidateQueryTimeOut(int validateQueryTimeOut) {
this.validateQueryTimeOut = validateQueryTimeOut;
}
private void validate(String val){
if(val == null || "".equals(val)){
throw new IllegalArgumentException("数据库参数配置异常...");
}
}
@Override
public String toString() {
return "DataSourceConfigProperty{" +
"url='" + url + '\'' +
", driver='" + driver + '\'' +
", userName='" + userName + '\'' +
", passwd='" + passwd + '\'' +
", validationQuery='" + validationQuery + '\'' +
", initSize='" + initSize + '\'' +
", minIdle='" + minIdle + '\'' +
", maxActive='" + maxActive + '\'' +
", checkTable=" + checkTable +
", maxWaitTime=" + maxWaitTime +
", evictionRunTime=" + evictionRunTime +
", minEvictionIdleTime=" + minEvictionIdleTime +
", keepAlive=" + keepAlive +
", testWhileIdle=" + testWhileIdle +
", testOnBorrow=" + testOnBorrow +
", testOnReturn=" + testOnReturn +
", poolPreparedStatement=" + poolPreparedStatement +
", maxPoolPreparedStatementSizePerConnection=" + maxPoolPreparedStatementSizePerConnection +
", validateQueryTimeOut=" + validateQueryTimeOut +
'}';
}
}
- 应用配置,该配置主要指定了组件扫描范围及mybayis的dao路径
package com.syx.microapplication.base;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
/**
* @date: 2022-03-11 00:15
* <p></p>
*/
@Configuration
@EnableAspectJAutoProxy
@ComponentScan(AppConfig.COMPONENT_SCAN)
@MapperScan(AppConfig.MAPPER_SCAN)
public class AppConfig {
//包扫描路径
protected static final String COMPONENT_SCAN = "com.syx";
//mybatis的dao路径
protected static final String MAPPER_SCAN = "com.syx.**.dao";
}
- 数据源配置,本应用使用的是druid数据源
package com.syx.microapplication.base;
import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.support.http.StatViewServlet;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import javax.sql.DataSource;
import java.util.ArrayList;
import java.util.List;
/**
* @date: 2022-03-10 23:01
* <p>数据源配置</p>
*/
@Configuration
@EnableTransactionManagement
@ConditionalOnClass(DataSource.class)
public class DataSourceConfig {
@Autowired
private DataSourceConfigProperty dataSourceConfigProperty;
@Bean
@Primary
public DruidDataSource dataSource(){
DruidDataSource druidDataSource = new DruidDataSource();
druidDataSource.setUrl(dataSourceConfigProperty.getUrl());
druidDataSource.setDriverClassName(dataSourceConfigProperty.getDriver());
druidDataSource.setUsername(dataSourceConfigProperty.getUserName());
druidDataSource.setPassword(dataSourceConfigProperty.getPasswd());
druidDataSource.setInitialSize(Integer.parseInt(dataSourceConfigProperty.getInitSize()));
druidDataSource.setMinIdle(Integer.parseInt(dataSourceConfigProperty.getMinIdle()));
druidDataSource.setMaxActive(Integer.parseInt(dataSourceConfigProperty.getMaxActive()));
druidDataSource.setMaxWait(dataSourceConfigProperty.getMaxWaitTime());
druidDataSource.setTimeBetweenEvictionRunsMillis(dataSourceConfigProperty.getEvictionRunTime());
druidDataSource.setMinEvictableIdleTimeMillis(dataSourceConfigProperty.getMinEvictionIdleTime());
druidDataSource.setTestWhileIdle(dataSourceConfigProperty.isTestWhileIdle());
druidDataSource.setTestOnBorrow(dataSourceConfigProperty.isTestOnBorrow());
druidDataSource.setTestOnReturn(dataSourceConfigProperty.isTestOnReturn());
druidDataSource.setValidationQuery(dataSourceConfigProperty.getValidationQuery());
return druidDataSource;
}
/**
* druid监控平台
* @return
*/
@Bean
public ServletRegistrationBean<StatViewServlet> servletRegistrationBean(){
ServletRegistrationBean<StatViewServlet> registrationBean = new ServletRegistrationBean<>();
StatViewServlet servlet = new StatViewServlet();
registrationBean.setServlet(servlet);
registrationBean.setName("druidView");
registrationBean.setLoadOnStartup(2);
List<String> urlMapping = new ArrayList<>();
urlMapping.add("/druid/*");
registrationBean.setUrlMappings(urlMapping);
return registrationBean;
}
}
- 启动类
package com.syx.microapplication;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.quartz.QuartzAutoConfiguration;
/**
* @date: 2022-03-10 23:49
* <p></p>
*/
@SpringBootApplication
public class MainApp {
public static void main(String[] args) {
SpringApplication.run(MainApp.class,args);
}
}
二、使用mybatis进行数据库操作
到目前为止,咱们的工程就搭建完毕了,接下来咱们就创建实体类、mybatis的dao以及mapper.xml文件。
- 创建实体类
package com.syx.web.entity;
import lombok.Data;
@Data
public class Company {
private int id;
private String name;
private int age;
private String address;
private float salary;
}
- 实体类对应的数据表
CREATE TABLE `company` (
`ID` int(11) NOT NULL,
`NAME` varchar(40) DEFAULT NULL,
`AGE` int(11) DEFAULT NULL,
`ADDRESS` char(40) DEFAULT NULL,
`SALARY` double DEFAULT NULL,
PRIMARY KEY (`ID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
--插入一条模拟数据
INSERT INTO `mydb`.`company` (`ID`, `NAME`, `AGE`, `ADDRESS`, `SALARY`) VALUES ('1', 'zs', '11', 'china', '200110');
- 创建mybatis的dao接口(一定要在@MapperScan注解指定的目录下创建)
package com.syx.web.dao;
import com.syx.web.entity.Company;
import org.apache.ibatis.annotations.Param;
import java.util.List;
public interface CompanyDao {
List<Company> findAll();
Company findById(@Param("id") int id);
}
- 创建dao对应的mapper.xml文件**(需要在 mapper-locations指定的目录下创建)**
<?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.syx.web.dao.CompanyDao">
<resultMap id="CompanyResultMap" type="com.syx.web.entity.Company">
<result column="ID" property="id" />
<result column="NAME" property="name" />
<result column="AGE" property="age" />
<result column="ADDRESS" property="address" />
<result column="SALARY" property="salary" />
</resultMap>
<select id="findAll" resultMap="CompanyResultMap">
select * from company
</select>
<select id="findById" resultMap="CompanyResultMap">
SELECT * FROM COMPANY
<where>
id=#{id}
</where>
</select>
</mapper>
mapper中标签的id要与dao中的方法名对应。
三、测试运行
package com.syx;
import com.syx.microapplication.MainApp;
import com.syx.web.dao.CompanyDao;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
/**
* @date: 2022-03-12 19:06
* <p></p>
*/
@SpringBootTest(classes = MainApp.class)
public class TestDao {
@Autowired
CompanyDao companyDao;
@Test
public void func3() {
System.out.println(companyDao.findAll());
}
}
四、总结
springboot集成mybatis中我们做的配置有三处:
1、配置druid数据源(持久层框架依赖数据源)
2、指定@MapperScan注解扫描的包路径
3、指定mapper-locations的路径
大家看完整个过程是不是发现很简单,这就是springboot的自动装配的优势,其中最主要的一个类就是MybatisAutoConfiguration ,这个类帮我们完成了很多配置工作,包括注入数据源,初始化sqlSessionFactory等。。。
@org.springframework.context.annotation.Configuration
@ConditionalOnClass({ SqlSessionFactory.class, SqlSessionFactoryBean.class })
@ConditionalOnSingleCandidate(DataSource.class)
@EnableConfigurationProperties(MybatisProperties.class)
@AutoConfigureAfter({ DataSourceAutoConfiguration.class, MybatisLanguageDriverAutoConfiguration.class })
public class MybatisAutoConfiguration implements InitializingBean {}
大家有兴趣的可以自行学习该类的源码,从中可以了解springboot的自动装配原理。