Spring、Mybatis整合
开始
加入了spring和Mybatis以及其他相关的依赖包,参考的网址:http://search.maven.org/
在pom.xml中添加maven对应jar包的坐标,ctrl+s保存加载
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.3.1</version>
</dependency>
spring的配置文件applicationContext.xml加入SqlSessionFactoryBean的配置
<!-- 创建sqlSessionFactory的bean-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
</bean>
applicationContext.xml中创建数据库连接对象,使用阿里的德鲁伊数据源创建bean,然后注入到上面的sqlSessionFactory
<!-- 配置数据源,使用的是alibaba的Druid(德鲁伊)数据源 -->
<!-- 数据库连接,连接池,监控 -->
<bean name="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
<property name="url" value="${jdbc_url}" />
<property name="username" value="${jdbc_username}" />
<property name="password" value="${jdbc_password}" />
<property name="driverClassName" value="${jdbc_driverClassName}" />
<!-- 初始化连接大小 -->
<property name="initialSize" value="0" />
<!-- 连接池最大使用连接数量 -->
<property name="maxActive" value="20" />
<!-- 连接池最大空闲 -->
<property name="maxIdle" value="20" />
<!-- 连接池最小空闲 -->
<property name="minIdle" value="0" />
<!-- 获取连接最大等待时间 -->
<property name="maxWait" value="60000" />
<!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
<property name="timeBetweenEvictionRunsMillis" value="60000" />
<!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->
<property name="minEvictableIdleTimeMillis" value="25200000" />
<!-- 打开removeAbandoned功能 -->
<property name="removeAbandoned" value="true" />
<!-- 1800秒,也就是30分钟 -->
<property name="removeAbandonedTimeout" value="1800" />
<!-- 关闭abanded连接时输出错误日志 -->
<property name="logAbandoned" value="true" />
<!-- 监控数据库 -->
<!-- <property name="filters" value="stat" /> -->
<property name="filters" value="mergeStat" />
</bean>
注:不使用德鲁伊的话,可以使用普通的连接创建bean
<bean name="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource" >
<property name="url" value="${jdbc_url}" />
<property name="username" value="${jdbc_username}" />
<property name="password" value="${jdbc_password}" />
<property name="driverClassName" value="${jdbc_driverClassName}" />
</bean>
创建db.properties文件
属性前面加jdbc前缀主要是防止出现和系统出现字段重复的错误
jdbc_url=jdbc:mysql://localhost:3308/blogdb?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai
jdbc_username=root
jdbc_password=root
jdbc_driverClassName=com.mysql.cj.jdbc.Driver
在applicationContext.xml中加入加载db.proerties的连接信息
<!-- 读取的是db.properties中的数据库连接信息 -->
<context:property-placeholder location="classpath:db.properties"/>
加入扫描dao包的mapperScanner的bean配置
我们写的dao方法,需要MapperScannerConfigurer,扫描Mapper接口,配置sqlsessionFactory引用
<!-- mapperScanner的bean配置 -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!-- 注入 basePackage ,mapper所在的包(去com.etc.dao扫描mapper)-->
<property name="basePackage" value="com.etc.dao"></property>
<!-- 注入sqlSessionFactoryBean,!!!!注意是beanName不是ref 而是value!!!! -->
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property>
</bean>
修改Dao方法,把该Mapper的实现类删除,加上@Repository
@Repository
public interface BlogMapper {
// 查询单个记录
@Select("select * from blogs where blogid = #{blogid}")
public Blog selectBlog(int blogid);
}
记得添加mysql依赖坐标
<!-- 添加mysql驱动包 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.16</version>
</dependency>
Spring单元测试
Junit5 -> 右键加入构建路径 ->
TestBlog.java测试类
@SpringJUnitConfig(locations = "classpath:applicationContext.xml")
public class TestBlog {
//注入BlogMapper
@Autowired
private BlogMapper blogMapper;
@Test
public void getBlog() {
System.out.println(blogMapper.selectBlog(1));
}
}
加入Log4j日志记录
为了能给分查看执行的SQL语句和参数以及结果等信息
- pom.xml文件加入Log4j 1.2.17
<!-- 日志记录 -->
<!-- https://mvnrepository.com/artifact/log4j/log4j -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
- 搭配一个log4j.propeties文件
# \u5168\u5C40
log4j.rootLogger=ERROR, stdout
# MyBatis\u65E5\u5FD7\u914D\u7F6E
log4j.logger.com.etc.dao=TRACE
log4j.logger.com.etc.test=TRACE
# \u63A7\u5236\u53F0\u8F93\u51FA
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n
- 添加Mybatis-config.xml文件(日志使用,可以再扩展其他配置)
<?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>
<!-- 配置日志工具log4j -->
<settings>
<setting name="logImpl" value="log4j"></setting>
</settings>
</configuration>
4.在applicationContext.xml文件中加入读取mybatis-config.xml配置
<!-- 创建sqlSessionFactory的bean -->
<bean id="sqlSessionFactory"
class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<!-- 这边新增连接mybatis的配置 -->
<property name="configLocation" value="classpath:mybatis-config.xml"></property>
</bean>
加入德鲁伊监控
- 添加druid连接池包1.0.11
<!-- 添加druid连接池包 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.0.12</version>
</dependency>
- applicationContext.xml加入相关监控参数配置
<!-- 不要漏了init-method和destroy-method -->
<bean name="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
<!-- 初始化连接大小 -->
<bean>
<property name="filters" value="${filters}" />
<!-- 最大并发连接数 -->
<property name="maxActive" value="${maxActive}" />
<!-- 初始化连接数量 -->
<property name="initialSize" value="${initialSize}" />
<!-- 配置获取连接等待超时的时间 -->
<property name="maxWait" value="${maxWait}" />
<!-- 最小空闲连接数 -->
<property name="minIdle" value="${minIdle}" />
<!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
<property name="timeBetweenEvictionRunsMillis"
value="${timeBetweenEvictionRunsMillis}" />
<!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->
<property name="minEvictableIdleTimeMillis"
value="${minEvictableIdleTimeMillis}" />
<property name="validationQuery" value="${validationQuery}" />
<property name="testWhileIdle" value="${testWhileIdle}" />
<property name="testOnBorrow" value="${testOnBorrow}" />
<property name="testOnReturn" value="${testOnReturn}" />
<property name="maxOpenPreparedStatements"
value="${maxOpenPreparedStatements}" />
<!-- 打开 removeAbandoned 功能 -->
<property name="removeAbandoned" value="${removeAbandoned}" />
<!-- 1800 秒,也就是 30 分钟 -->
<property name="removeAbandonedTimeout"
value="${removeAbandonedTimeout}" />
<!-- 关闭 abanded 连接时输出错误日志 -->
<property name="logAbandoned" value="${logAbandoned}" />
</bean>
- 配置db.properties文件
加入上面对应字段的默认值
filters=stat,wall
maxActive=20
initialSize=1
maxWait=60000
minIdle=10
maxIdle=15
timeBetweenEvictionRunsMillis=60000
minEvictableIdleTimeMillis=300000
validationQuery=SELECT 'x'
testWhileIdle=true
testOnBorrow=false
testOnReturn=false
maxOpenPreparedStatements=20
removeAbandoned=true
removeAbandonedTimeout=1800
logAbandoned=true
- 配置druid监控spring jdbc
<!-- 配置druid监控spring jdbc -->
<bean id="druid-stat-interceptor" class="com.alibaba.druid.support.spring.stat.DruidStatInterceptor">
</bean>
<bean id="druid-stat-pointcut" class="org.springframework.aop.support.JdkRegexpMethodPointcut" scope="prototype">
<property name="patterns">
<list>
<!-- 监控路径 -->
<value>com.etc.dao.*</value>
</list>
</property>
</bean>
<aop:config>
<aop:advisor advice-ref="druid-stat-interceptor" pointcut-ref="druid-stat-pointcut" />
</aop:config>
记得添加aop的命名空间namespaces
5. 在web.xml添加德鲁伊的登录页
<!--连接池 启用 Web 监控统计功能 -->
<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>profileEnable</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>DruidWebStatFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<servlet>
<servlet-name>DruidStatView</servlet-name>
<servlet-class>com.alibaba.druid.support.http.StatViewServlet</servlet-class>
<init-param>
<!-- 用户名 -->
<param-name>loginUsername</param-name>
<param-value>root</param-value>
</init-param>
<init-param>
<!-- 密码 -->
<param-name>loginPassword</param-name>
<param-value>root</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>DruidStatView</servlet-name>
<url-pattern>/druid/*</url-pattern>
</servlet-mapping>
<!-- 连接池 启用 Web 监控统计功能 -->
- tomcat服务上运行,访问地址http://localhost:8080/maven01/druid/index.html
默认用户名:root 密码:root
首页页面,可以查看信息
但是我们发现一个bug,导致不能监控到SQL
更改druid版本就行,版本更改为1.0.11
<!-- https://mvnrepository.com/artifact/com.alibaba/druid -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.0.11</version>
</dependency>
再运行一次,结果如下
注:jar包说明:
Spring jar包 | 说明 | 备注 |
---|---|---|
aopalliance-1.0.jar | AOP | |
aspectjweaver-1.8.9 | AOP | |
commons-dbcp-1.2.2.jar | 连接池 | |
commons-logging-1.1.3.jar | 日志记录 | |
commons-pool-1.4.jar | 连接池 | |
jackson-annotations-2.9.10.jar | 注解包(可选),提供注解功能 | java语言的开源json格式解析工具 |
jackson-core-2.9.10.jar | 核心包(必须),提供基于“流模式”解析的API | java语言的开源json格式解析工具 |
jackson-databind-2.9.10.jar | 数据绑定包(可选)提供基于“对象绑定”和“树模型”相关API | java语言的开源json格式解析工具 |
javax.servlet.jsp.jstl.jar | JSTL标签库 | |
jstl-impl.jar | JSTL标签库 | |
log4j-1.2.17.jar | 日志记录Log4j | |
mybatis-3.5.1.jar | Mybatis框架核心jar包 | |
mybatis-spring-2.0.3.jar | MyBatis-Spring 会帮助你将 MyBatis 代码无缝地整合到 Spring 中 | |
mysql-connector-java-5.1.18-bin.jar | Java连接mysql的数据库驱动包 | 会替换为8的版本 |
spring-aop-5.1.1.RELEASE.jar | AOP | |
spring-aspects-5.1.1.RELEASE.jar | AOP | |
spring-beans-5.1.1.RELEASE.jar | Bean管理 | |
spring-context-5.1.1.RELEASE.jar | 上下文 | |
spring-context-support-5.1.1.RELEASE.jar | 上下文 | |
spring-context-support-5.1.1.RELEASE.jar | Core | |
spring-expression-5.1.1.RELEASE.jar | 表达式 | |
spring-jdbc-5.1.1.RELEASE.jar | Jdbc,xml事务管理 | |
spring-tx-5.1.1.RELEASE.jar | 注解事务管理 | tx |
spring-web-5.1.1.RELEASE.jar | Web支持 | |
spring-webmvc-5.1.1.RELEASE.jar | Springmvc支持 | |
spring-test-5.1.1.RELEASE.jar | Spring自带的测试 | |
spring-core 5.1.1.RELEASE | Core核心包 | |
Commons-fileupload | 文件上传 | |
Commons-io | 文件上传 | |
Druid 1.0.12 | 阿里的连接池产品 | |
Junit -4.13 | 单元测试 |
注:数据库连接池补充:
initialSize :连接池启动时创建的初始化连接数量(默认值为0)
maxActive :连接池中可同时连接的最大的连接数(默认值为8,调整为20,高峰单机器在20并发左右,自己根据应用场景定)
maxIdle:连接池中最大的空闲的连接数,超过的空闲连接将被释放,如果设置为负数表示不限制(默认为8个,maxIdle不能设置太小,因为假如在高负载的情况下,连接的打开时间比关闭的时间快,会引起连接池中idle的个数 上升超过maxIdle,而造成频繁的连接销毁和创建,类似于jvm参数中的Xmx设置)
minIdle:连接池中最小的空闲的连接数,低于这个数量会被创建新的连接(默认为0,调整为5,该参数越接近maxIdle,性能越好,因为连接的创建和销毁,都是需要消耗资源的;但是不能太大,因为在机器很空闲的时候,也会创建低于minidle个数的连接,类似于jvm参数中的Xmn设置)
maxWait :最大等待时间,当没有可用连接时,连接池等待连接释放的最大时间,超过该时间限制会抛出异常,如果设置-1表示无限等待(默认为无限,调整为60000ms,避免因线程池不够用,而导致请求被无限制挂起)
poolPreparedStatements:开启池的prepared(默认是false,未调整,经过测试,开启后的性能没有关闭的好。)
maxOpenPreparedStatements:开启池的prepared 后的同时最大连接数(默认无限制,同上,未配置)
minEvictableIdleTimeMillis :连接池中连接,在时间段内一直空闲, 被逐出连接池的时间
(默认为30分钟,可以适当做调整,需要和后端服务端的策略配置相关)
removeAbandonedTimeout :超过时间限制,回收没有用(废弃)的连接(默认为 300秒,调整为180)
removeAbandoned :超过removeAbandonedTimeout时间后,是否进 行没用连接(废弃)的回收(默认为false,调整为true)