现在我已经把我的项目整改到了数据库访问的阶段,这里我来介绍下如何进行整合的,首先我的项目也是使用的mybatis框架,以及druid数据源,这里我首先使用jdbc直接连接数据库引入,顺便剖析下连接数据库自动配置的原理
jdbc直接访问数据库
引入相关依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
application.yml文件中配置
server:
port: 80
spring:
datasource:
username: 数据库账户
password: 数据库密码
url: jdbc:mysql://ip:3306/hrp_ecs?useUnicode=true&characterEncoding=utf8&useSSL=false&autoReconnect=true&failOverReadOnly=false&allowMultiQueries=true&useAffectedRows=true
driver-class-name: com.mysql.cj.jdbc.Driver
测试连接是否成功以及数据源
@Test
void contextLoads() {
System.out.println("=============");
System.out.println(dataSource.getClass());
try {
System.out.println("=============");
System.out.println(dataSource.getConnection());
System.out.println("=============");
} catch (SQLException e) {
e.printStackTrace();
}
}
到目前为止没有任何问题
看完效果总得分析下原理
自动配置原理
org.springframework.boot.autoconfigure.jdbc.DataSourceProperties
数据源的相关配置都在这个类中
最为熟悉的属性
根据原来以往的经验我们知道自动配置原理相关类是:
org.springframework.boot.autoconfigure.jdbc.DataSourceConfiguration
默认支持的数据源:
- org.apache.tomcat.jdbc.pool.DataSource
- com.zaxxer.hikari.HikariDataSource
- org.apache.commons.dbcp2.BasicDataSource
@Configuration(
proxyBeanMethods = false
)
@ConditionalOnClass({BasicDataSource.class})
@ConditionalOnMissingBean({DataSource.class})
@ConditionalOnProperty(
name = {"spring.datasource.type"},
havingValue = "org.apache.commons.dbcp2.BasicDataSource",
matchIfMissing = true
)
static class Dbcp2 {
Dbcp2() {
}
@Bean
@ConfigurationProperties(
prefix = "spring.datasource.dbcp2"
)
BasicDataSource dataSource(DataSourceProperties properties) {
return (BasicDataSource)DataSourceConfiguration.createDataSource(properties, BasicDataSource.class);
}
}
@Configuration(
proxyBeanMethods = false
)
@ConditionalOnClass({HikariDataSource.class})
@ConditionalOnMissingBean({DataSource.class})
@ConditionalOnProperty(
name = {"spring.datasource.type"},
havingValue = "com.zaxxer.hikari.HikariDataSource",
matchIfMissing = true
)
static class Hikari {
Hikari() {
}
@Bean
@ConfigurationProperties(
prefix = "spring.datasource.hikari"
)
HikariDataSource dataSource(DataSourceProperties properties) {
HikariDataSource dataSource = (HikariDataSource)DataSourceConfiguration.createDataSource(properties, HikariDataSource.class);
if (StringUtils.hasText(properties.getName())) {
dataSource.setPoolName(properties.getName());
}
return dataSource;
}
}
@Configuration(
proxyBeanMethods = false
)
@ConditionalOnClass({org.apache.tomcat.jdbc.pool.DataSource.class})
@ConditionalOnMissingBean({DataSource.class})
@ConditionalOnProperty(
name = {"spring.datasource.type"},
havingValue = "org.apache.tomcat.jdbc.pool.DataSource",
matchIfMissing = true
)
static class Tomcat {
Tomcat() {
}
@Bean
@ConfigurationProperties(
prefix = "spring.datasource.tomcat"
)
org.apache.tomcat.jdbc.pool.DataSource dataSource(DataSourceProperties properties) {
org.apache.tomcat.jdbc.pool.DataSource dataSource = (org.apache.tomcat.jdbc.pool.DataSource)DataSourceConfiguration.createDataSource(properties, org.apache.tomcat.jdbc.pool.DataSource.class);
DatabaseDriver databaseDriver = DatabaseDriver.fromJdbcUrl(properties.determineUrl());
String validationQuery = databaseDriver.getValidationQuery();
if (validationQuery != null) {
dataSource.setTestOnBorrow(true);
dataSource.setValidationQuery(validationQuery);
}
return dataSource;
}
}
自定义数据源
我们往往有自己喜欢的数据源配置直接需要用的数据源
参考DataSourceConfiguration,根据配置创建数据源,默认使用Tomcat连接池;可以使用
spring.datasource.type指定自定义的数据源类型
@Configuration(
proxyBeanMethods = false
)
@ConditionalOnMissingBean({DataSource.class})
@ConditionalOnProperty(
name = {"spring.datasource.type"}
)
static class Generic {
Generic() {
}
@Bean
DataSource dataSource(DataSourceProperties properties) {
//使用DataSourceBuilder创建数据源,利用反射创建响应type的数据源,并且绑定相关属性
return properties.initializeDataSourceBuilder().build();
}
}
DataSourceInitializer:ApplicationListener;
作用:
1)、runSchemaScripts();运行建表语句;
2)、runDataScripts();运行插入数据的sql语句;
默认只需要将文件命名为:
schema‐.sql、data‐.sql
默认规则:schema.sql,schema‐all.sql;
可以使用
schema:
‐ classpath:department.sql
指定位置
整合druid
导入依赖
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.8</version>
</dependency>
server:
port: 80
spring:
datasource:
username: 数据库账户
password: 数据库密码
url: jdbc:mysql://ip:3306/hrp_ecs?useUnicode=true&characterEncoding=utf8&useSSL=false&autoReconnect=true&failOverReadOnly=false&allowMultiQueries=true&useAffectedRows=true
driver-class-name: com.mysql.cj.jdbc.Driver
type: com.alibaba.druid.pool.DruidDataSource
#数据源其他配置
initialSize: 5
minIdle: 5
maxActive: 20
maxWait: 60000
timeBetweenEvictionRunsMillis: 60000
minEvictableIdleTimeMillis: 300000
validationQuery: SELECT 1 FROM DUAL
testWhileIdle: true
testOnBorrow: false
testOnReturn: false
poolPreparedStatements: true
增加type属性
进行测试数据源已经修改成Druid但是
从断点中我们看到数据源配置属性并没有生效
此时我们需要配置一个配置类
@Configuration
public class DruidConfig {
@ConfigurationProperties(prefix = "spring.datasource")
@Bean
public DataSource druid(){
return new DruidDataSource();
}
}
我们知道drui有监控功能如何实现:
原来传统的我们是在web.xml里面配置一个servlet和一个filter
因此我们也在DruidConfig 增加一个servlet和一个filter
@Configuration
public class DruidConfig {
@ConfigurationProperties(prefix = "spring.datasource")
@Bean
public DataSource druid(){
return new DruidDataSource();
}
//配置Druid的监控
//1、配置一个管理后台的Servlet
//ssm架构下在web.xml里面配置的
@Bean
public ServletRegistrationBean statViewServlet(){
ServletRegistrationBean bean = new ServletRegistrationBean(new StatViewServlet(), "/druid/*");
Map<String,String> initParameters = new HashMap<String,String>();
initParameters.put(StatViewServlet.PARAM_NAME_USERNAME,"chd");
initParameters.put(StatViewServlet.PARAM_NAME_PASSWORD,"chd");
initParameters.put(StatViewServlet.PARAM_NAME_RESET_ENABLE,"true");
bean.setInitParameters(initParameters);
return bean;
}
@Bean
public FilterRegistrationBean webStatFilter(){
FilterRegistrationBean bean = new FilterRegistrationBean();
bean.setFilter(new WebStatFilter());
Map<String,String> initParameters = new HashMap<String,String>();
initParameters.put("exclusions","*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*");
initParameters.put("sessionStatMaxCount","1000");
initParameters.put("principalSessionName","user_name");
initParameters.put("profileEnable","true");
bean.setInitParameters(initParameters);
return bean;
}
}
可以成功登录
传统项目配置:
<servlet>
<servlet-name>DruidStatView</servlet-name>
<servlet-class>com.alibaba.druid.support.http.StatViewServlet</servlet-class>
<init-param>
<!-- 允许清空统计数据 -->
<param-name>resetEnable</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<!-- 用户名 -->
<param-name>loginUsername</param-name>
<param-value>chd</param-value>
</init-param>
<init-param>
<!-- 密码 -->
<param-name>loginPassword</param-name>
<param-value>chd</param-value>
</init-param>
<load-on-startup>3</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>DruidStatView</servlet-name>
<url-pattern>/druid/*</url-pattern>
</servlet-mapping>
<filter>
<filter-name>DruidWebStatFilter</filter-name>
<filter-class>com.alibaba.druid.support.http.WebStatFilter</filter-class>
<init-param>
<param-name>exclusions</param-name>
<param-value>*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*</param-value>
</init-param>
<init-param>
<param-name>sessionStatMaxCount</param-name>
<param-value>1000</param-value>
</init-param>
<init-param>
<param-name>principalSessionName</param-name>
<param-value>user_name</param-value>
</init-param>
<init-param>
<param-name>profileEnable</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>DruidWebStatFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
整合mybatis
增加依赖
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.3</version>
</dependency>
这个是mybatis官方提供的
这里关于mybatis相关的知识不太多的介绍,如果对mybatis不熟悉的 可以参考我写的mybatis相关文章
我们从注解版和xml2种方式分别进行介绍
注解版:
编写dao
@Mapper
public interface DemoDao {
@Select("select count(*) from sup_order_main")
public Integer test();
}
但是在我们开发中我们很少每个接口上面都写一个@Mapper文件,一般我们处理的方式是把所有的dao放到一个特定的文件夹下
在程序启动入口使用@MapperScan(“com.hrp.dao”)
xml方式:
接口
public interface DemoXmlDao {
public Integer test();
}
mapper配置文件
<?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.hrp.dao.DemoXmlDao">
<!-- 登录 -->
<select id="test" resultType="integer">
select count(*) from sup_order_main
</select>
</mapper>
mybatis主配置文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<settings>
<setting name="lazyLoadingEnabled" value="true"/><!-- 使用延迟加载 -->
<setting name="aggressiveLazyLoading" value="false"/><!-- 按需加载对象属性(即访问对象中一个懒对象属性,不会加载对象中其他的懒对象属性) -->
<setting name="cacheEnabled" value="true"/><!-- 开启二级缓存,默认是false -->
<setting name="callSettersOnNulls" value="true"/><!--解决,查询返回结果含null没有对应字段值问题-->
<setting name="logImpl" value="STDOUT_LOGGING" />
</settings>
</configuration>
这个不是必须有的 一般在生产环境为了提高数据的性能,或者其他实际需要进行的一些配置
application.yml文件中添加
mybatis:
config-location: classpath:sqlMapConfig.xml
mapper-locations: classpath:mapper/com/hrp/**/*.xml