1、创建项目时勾选SQL -> MyBatis Framework、数据库驱动,也可以手动添加依赖
<dependency>
<groupId>org.mybatis.spring.bootgroupId>
<artifactId>mybatis-spring-boot-starterartifactId>
<version>2.1.4version>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<scope>runtimescope>
dependency>
2、entity
@Data
public class User {
private int id;
private String name;
//......
}
实体类不需要放到spring容器中
3、dao|mapper
public interface UserMapper{
User findUserById(Integer id);
}
mapper接口上不需要加注解
4、mapper
DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.chy.mall.dao.UserMapper">
<select id="findUserById" parameterType="integer" resultType="user">
select * from tb_user where id=#{id}
select>
mapper>
不同公司的命名习惯可能不同,如果接口取名XxxMapper,namespace使用XxxMapper;如果接口取名XxxDao,namespace使用XxxDao,与接口名保持一致。
5、引导类上加@MapperScan
@MapperScan(basePackages = { "com.chy.mall.dao1" , "com.chy.mall.dao2" })
value是basePackages的别名,也可以使用value属性来配置。
6、yml
mybatis:
#指定xml映射文件位置,多个时逗号分隔
mapper-locations: classpath:mapper/**.xml
#实体类别名,有多个包时以英文逗号或分号隔开
type-aliases-package: com.chy.mall.userserver.entity
configuration:
#下划线自动转驼峰
map-underscore-to-camel-case: true
#打印sql语句,有多种日志实现方式,常用StdOutImpl、Slf4jImpl
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
# log-impl: org.apache.ibatis.logging.slf4j.Slf4jImpl
不推荐在yml中配日志,建议日志都在logback-spring.xml中统一配置、管理
<logger name="com.chy.mall.dao" level="DEBUG" />
说明
1、classpath、classpath*的区别
2、路径中**、*的区别
3、如果xml映射文件没有放在resources目录下,而是放在了java目录下
mapper-locations=com/chy/mall/dao/mapper/**/*Mapper.xml
#或者
mapper-locations=classpath:com/chy/mall/dao/mapper/**/*Mapper.xml
4、不管是配置实体类别名,还是配置mapper文件位置,值中classpath可以加也可以不加;如果依赖的模块中有mapper映射文件、mybatis要用到的实体类,则一定要加classpath*。
5、如果应用启动时报WARN
Establishing SSL connection without server’s identity verification is not recommende
这是因为mysql server版本、mysql驱动使用的版本不一致,一个使用5.x,一个使用8.x。可以在数据库连接配置的url中加上 &useSSL=false
HiKariCP,CP即Connection Pool,代码经过精简优化,jar包体积很小,稳定可靠、性能极高,号称性能最高的连接池,是springboot 2.x默认的数据库连接池。hikari的高性能得益于最大限度地避免锁竞争。
druid是阿里开源的连接池,性能略低于hikari,但功能全面、扩展性强,对数据库操作有监控、统计功能,便于分析、优化数据库操作。
springboot 2.x默认使用hikari作为数据库连接池,自带了hikari的依赖,不需要添加额外依赖。
yml
spring:
datasource:
#默认就是hikari,可缺省
# type: com.zaxxer.hikari.HikariDataSource
url: jdbc:mysql://localhost:3306/mall?serverTimezone=Asia/Shanghai&allowMultiQueries=true
driver-class-name: com.mysql.cj.jdbc.Driver
username: root
password: abcd
hikari:
#默认30000 ms,即30s
connection-timeout: 30000
#默认600000 ms,即10min
idle-timeout: 600000
#连接池中的最大连接数(active+idle),默认10
maximum-pool-size: 200
#默认10
minimum-idle: 50
驱动、url、用户名、密码不要写在hikari中,容易出错,即不要使用以下属性进行配置
hikari:
driver-class-name: com.mysql.cj.jdbc.Driver
jdbc-url: jdbc:mysql://localhost:3306/mall?serverTimezone=UTC
username: root
password: abcd
pom.xml
<dependency>
<groupId>com.alibabagroupId>
<artifactId>druid-spring-boot-starterartifactId>
<version>1.1.22version>
dependency>
yml
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
#这4个配置可以写在此处,也可以写在druid中
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/mall?serverTimezone=UTC
username: root
password: abcd
druid:
# url: jdbc:mysql://localhost:3306/mall?serverTimezone=UTC
# username: root
# password: abcd
# driver-class-name: com.mysql.cj.jdbc.Driver
initial-size: 50
max-active: 200
min-idle: 30
#获取数据库连接的最大等待时间,ms,默认-1 一直等待
max-wait: 5000
#是否缓存PreparedStatement,默认false。开启后对支持游标的数据库比如oracle速度提升大,mysql对游标的支持一般,建议关闭
#pool-prepared-statements: true
#缓存的PreparedStatement的最大数量,默认-1 不缓存。大于0时可缺省上一句配置、会自动开启PreparedStatement缓存,key也可以写成 max-pool-prepared-statement-per-connection-size
#max-open-prepared-statements: 20
#申请连接时检测连接是否有效,开启会降低性能
test-on-borrow: false
#归还连接时检测连接是否有效,开启会降低性能
test-on-return: false
#空闲时才检测检测连接是否有效
test-while-idle: true
#用于检测连接是否有效的查询语句,mysql使用 SELECT 'x',oracle使用 SELECT 1 FROM DUAL
validation-query: SELECT 'x'
#检查时多少ms认为超时
validation-query-timeout: 20000
#间隔多久检测需要关闭的空闲连接,ms
time-between-eviction-runs-millis: 300000
#一个连接在池中的最小存活时间,ms
min-evictable-idle-time-millis: 600000
filter:
stat:
#执行时间超过3000ms就认为是慢sql
slow-sql-millis: 3000
#将慢sql记录到日志中
log-slow-sql: true
#合并sql的统计信息,eg. select * from user where id = ? 不管id是多少,都会合并为1条sql进行统计
merge-sql: true
#wall用于防御sql注入、配置sql语句执行权限
wall:
config:
#允许一次执行多条sql语句
multi-statement-allow: true
#指定druid要使用的filter插件
filters: stat,wall
#监控所有的druid数据源,合并监控数据
use-global-data-source-stat: true
#web监控界面的静态资源配置
web-stat-filter:
enabled: true
url-pattern: /*
exclusions: .js,*.gif,*.jpg,*.bmp,*.png,*.css,*.ico,/druid/*
#web监控页面的路径、登录配置
stat-view-servlet:
enabled: true
url-pattern: /druid/*
login-username: chy
login-password: abcd
驱动、url、用户名、密码可以写在datasource中,也可以写在druid中。
以druid配置多数据源为例
yml
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
ds1:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/db1?serverTimezone=UTC
username: root
password: abcd
ds2:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/db2?serverTimezone=UTC
username: root
password: abcd
每个数据源的所有属性都单独配置。
在配置类中指定mapper接口所在的包、xml映射文件位置,无需在引导类上用@MapperScan指定包位置,无需在yml中指定xml映射文件位置。
config.DataSource1Config
import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import javax.sql.DataSource;
@Configuration //标识为bean的配置类
@MapperScan(basePackages = "com.chy.mall.dao1", sqlSessionTemplateRef = "test1SqlSessionTemplate") //指定对应的mapper接口所在的包、使用的SqlSessionTemplate
public class DataSource1Config {
@Primary
@Bean(name = "ds1")
@ConfigurationProperties("spring.datasource.ds1") //yml中的配置前缀
public DataSource dataSourceOne() {
return DruidDataSourceBuilder.create().build();
}
@Bean(name = "test1SqlSessionFactory")
@Primary
public SqlSessionFactory testSqlSessionFactory(@Qualifier("ds1") DataSource dataSource) throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(dataSource);
//指定xml映射文件位置
bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper/ds1/**/*Mapper.xml"));
return bean.getObject();
}
@Bean(name = "test1TransactionManager")
@Primary
public DataSourceTransactionManager testTransactionManager(@Qualifier("ds1") DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
@Bean(name = "test1SqlSessionTemplate")
@Primary
public SqlSessionTemplate testSqlSessionTemplate(@Qualifier("test1SqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
return new SqlSessionTemplate(sqlSessionFactory);
}
}
config.DataSource2Config
import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import javax.sql.DataSource;
@Configuration //指定mapper接口所在的包、使用的SqlSessionTemplate
@MapperScan(basePackages = "com.chy.mall.dao2",sqlSessionTemplateRef = "test2SqlSessionTemplate")
public class DataSource2Config {
@Bean(name = "ds2")
@ConfigurationProperties("spring.datasource.ds2")
public DataSource dataSourceTwo(){
return DruidDataSourceBuilder.create().build();
}
@Bean(name = "test2SqlSessionFactory")
@Primary
public SqlSessionFactory testSqlSessionFactory(@Qualifier("ds2") DataSource dataSource) throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(dataSource);
//指定xml映射文件位置
bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper/ds2/**/*Mapper.xml"));
return bean.getObject();
}
@Bean(name = "test2TransactionManager")
@Primary
public DataSourceTransactionManager testTransactionManager(@Qualifier("ds2") DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
@Bean(name = "test2SqlSessionTemplate")
@Primary
public SqlSessionTemplate testSqlSessionTemplate(@Qualifier("test2SqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
return new SqlSessionTemplate(sqlSessionFactory);
}
}