3.Spring整合MyBatis
本章目标
- Spring整合MyBatis(掌握)
- Druid连接池介绍及使用(扩展)
本章内容
本章为Spring中整合MyBatis初级版,目的为了加深对ioc的理解
一、Spring整合MyBatis
为了更好的理解依赖注入,我们先把Spring和MyBatis整合到一起
传统的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>
<properties resource="jdbc.properties">
<property name="db.password" value="root1"/>
</properties>
<settings>
<setting name="cacheEnabled" value="true"/>
<setting name="lazyLoadingEnabled" value="true"/> <!--懒加载:当使用时再去加载-->
</settings>
<typeAliases>
<typeAlias type="com.it.store.entity.Emp" alias="Emp"/>
</typeAliases>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${db.driver}"/>
<property name="url" value="${db.url}"/>
<property name="username" value="${db.username}"/>
<property name="password" value="${db.password}"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="mapper/EmpMapper.xml"/>
<mapper resource="mapper/TeacherMapper.xml"/>
<mapper resource="mapper/ClassesMapper.xml"/>
</mappers>
</configuration>
SqlSessionFactory —>SqlSesssion—>Mapper(映射器接口类型的对象) 都交给Spring管理
1、 pom添加依赖
<properties>
<spring.version>5.3.10</spring.version>
<mybatis.version>3.5.7</mybatis.version>
<mybatis-spring.version>2.0.6</mybatis-spring.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<!-- https://mvnrepository.com/artifact/com.github.pagehelper/pagehelper -->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>6.1.0</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-expression</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/aopalliance/aopalliance -->
<dependency>
<groupId>aopalliance</groupId>
<artifactId>aopalliance</artifactId>
<version>1.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-aspects -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>${mybatis.version}</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>${mybatis-spring.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.alibaba/druid -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.2.6</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.29</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.24</version>
<scope>provided</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.24</version>
<scope>provided</scope>
</dependency>
</dependencies>
2、通过MybatisX生成实体类的相关信息
首先生成这些相关信息,方便配置spring-config.xml文件相关内容
实体类:
@Data:作用于类上,是以下注解的集合:@ToString @EqualsAndHashCode @Getter @Setter @RequiredArgsConstructor
注意要使用lombok,需要先安装插件,然后导入如下依赖才可以使用@Data注解
package com.woniuxy.ssm.entity;
import java.io.Serializable;
import java.util.Date;
import lombok.Data;
/**
*
* @TableName user
*/
@Data
public class User implements Serializable {
private Integer id;
private String userName;
private String password;
private Integer age;
private Date createDate;
private String headImg;
private Integer deptId;
private static final long serialVersionUID = 1L;
}
Mapper接口:
package com.woniuxy.ssm.mapper;
import com.woniuxy.ssm.entity.User;
import java.util.List;
public interface UserMapper {
List<User> queryAll();
}
映射文件:
<?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.woniuxy.ssm.mapper.UserMapper">
<select id="queryAll" resultType="User">
select * from user
</select>
</mapper>
3、关键配置
Spring整合mybatis时,要把数据源的生成,以及SqlSession的生成都通过Spring依赖注入的方式来实现,涉及到如下配置
- 配置DataSource数据源
- 配置SqlSessionFactoryBean
- 编写测试类测试运行结果
3.1 配置DataSource数据源
在resources目录下创建添加jdbc.properties文件,内容如下
属性文件的key不能直接为username和password,可能会出现得不到值的情况
jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/hrms?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai
jdbc.username=root
jdbc.password=123456
在spring配置文件中配置数据源
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd">
<!--加载jdbc.properties中配置信息-->
<context:property-placeholder location="classpath:config.properties"/>
<bean id="dataSource" destroy-method="close" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
</beans>
注意<context标签的引入方式,可以通过官网搜索到相应的头部信息
此处使用的是阿里的连接池
3.2 配置SqlSessionFactoryBean
拷贝过来直接使用
通过mybatis-spring中提供的SqlSessionFactoryBean来实现对SqlSessionFactory的创建,确保pom.xml文件中添加起步依赖
<!--配置SqlSessionFactoryBean,SqlSessionFactoryBean会根据数据源创建sqlSessionFactory对象-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!--注入数据源-->
<property name="dataSource" ref="dataSource"/>
<!--配置实体类所处的包为别名包,多个包之间用逗号隔开-->
<property name="typeAliasesPackage" value="com.woniuxy.hrms.entity"/>
<!--配置映射文件的路径-->
<property name="mapperLocations" value="mapper/*"/>
<!--配置实mybatis其他的相关配置-->
<property name="configuration">
<bean class="org.apache.ibatis.session.Configuration">
<!--配置SQL日志的打印,懒加载的配置-->
<property name="logImpl" value="org.apache.ibatis.logging.stdout.StdOutImpl"/>
<property name="cacheEnabled" value="true"/>
<property name="lazyLoadingEnabled" value="true"/>
</bean>
</property>
<!--配置pagehelper插件-->
<property name="plugins">
<array>
<bean class="com.github.pagehelper.PageInterceptor"/>
</array>
</property>
<!--如果想加载mybatis-config的主配置文件-->
<property name="configLocation" value="classpath:mybatis-config.xml"/>
</bean>
mybatis交给spring管理之后 ,不再需要mybatis-config.xml文件
typeAliasesPackage中value属性可以有多个值,多个值之间用逗号隔开
4、Mapper接口实现类
注意:需要给sqlSessionFactory
添加set方法,通过设置注入方式来实现注入
Mybatis默认是手动提交事务的
JDBC默认是自动提交事务的
当Spring整合Mybatis时,事务默认是自动提交的
package com.woniuxy.ssm.mapper.impl;
import com.woniuxy.ssm.entity.User;
import com.woniuxy.ssm.mapper.UserMapper;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import java.util.List;
public class UserMapperImpl implements UserMapper {
//需要spring注入进来sqlSessionFactory
private SqlSessionFactory sqlSessionFactory;
public void setSqlSessionFactory(SqlSessionFactory sqlSessionFactory) {
this.sqlSessionFactory = sqlSessionFactory;
}
@Override
public List<User> queryAll() {
List<User> list;
try(SqlSession sqlSession = sqlSessionFactory.openSession()){
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
list = UserMapper.queryAll();
}
return list;
}
}
https://mybatis.org/mybatis-3/zh/getting-started.html中有相关内容
try括号中可以写多行语句,会自动关闭括号中的资源
带参数的try(){}语法含义
最简形式为
try(Resource res = xxx)//可指定多个资源 { work with res }
try块退出时,会自动调用res.close()方法,关闭资源。
需要注意的是
try()的括号中可以写多行声明,每个声明的变量类型都必须是Closeable的子类,用分号隔开。
5、Service层代码
Service接口:
package com.woniuxy.ssm.service;
import com.woniuxy.ssm.entity.User;
import java.util.List;
public interface UserService {
List<User> queryAll();
}
Service实现类:
注意:给userMapper添加set方法,通过设置注入的方式注入
package com.woniuxy.ssm.service.impl;
import com.woniuxy.ssm.entity.User;
import com.woniuxy.ssm.mapper.UserMapper;
import com.woniuxy.ssm.service.UserService;
import java.util.List;
public class UserServiceImpl implements UserService {
//需要spring注入进来
private UserMapper userMapper;
public void setUserMapper(UserMapper userMapper) {
this.userMapper = userMapper;
}
@Override
public List<User> queryAll() {
return userMapper.queryAll();
}
}
6、完善spring-config.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<!--加载配置文件信息-->
<context:property-placeholder location="classpath:config.properties"/>
<!-- 配置数据源-->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
<bean id="sessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="typeAliasesPackage" value="com.woniuxy.entity"/>
<property name="mapperLocations" value="mapper/*"/>
<property name="configuration">
<bean class="org.apache.ibatis.session.Configuration">
<property name="logImpl" value="org.apache.ibatis.logging.stdout.StdOutImpl"/>
</bean>
</property>
<property name="plugins">
<array>
<bean class="com.github.pagehelper.PageInterceptor"/>
</array>
</property>
</bean>
<bean id="employeeMapper" class="com.woniuxy.mapper.impl.EmployeeMapperImpl">
<property name="sqlSessionFactory" ref="sessionFactory"/>
</bean>
<bean id="employeeService" class="com.woniuxy.service.impl.EmployeeServiceImpl">
<property name="employeeMapper" ref="employeeMapper"/>
</bean>
</beans>
7、测试
public class SSMApplication {
public static void main(String[] args) {
ApplicationContext ac = new ClassPathXmlApplicationContext("spring-config.xml");
UserService UserService = ac.getBean("userService", UserService.class);
List<User> list = UserService.queryAll();
for (User user:list) {
System.out.println(user);
}
}
}
二、Druid连接池介绍及使用(扩展)
/ˈdruːɪd/
1、连接池的定义
什么叫连接池?顾名思义,连接池就是将应用所需的连接对象放在池中,每次访问时从池中获取,使用完毕再放回池中,以达到连接复用的目的。连接池和线程池很像,都是为了减少连接对象在创建、销毁连接过程中不必要消耗的资源。
大家接触最多的连接池、大概是数据库连接或者tomcat连接池,C3P0、DBCP、Tomcat Jdbc Pool、BoneCP、Druid等。这些连接池的目的都非常的纯粹,即在服务启动的时候,预先生成若干条连接,每当有请求过来,就从中取出一个,执行操作,执行完成后再放回,从而避免反复的建立和销毁连接,以提升性能。
2、主流数据库连接池
常用的主流开源数据库连接池有C3P0、DBCP、Tomcat Jdbc Pool、BoneCP、Druid等
名称 | 介绍 |
---|---|
C3p0 | 开源的JDBC连接池,实现了数据源和JNDI绑定,支持JDBC3规范和JDBC2的标准扩展。目前使用它的开源项目有Hibernate、Spring等。单线程,性能较差,适用于小型系统,代码600KB左右 |
DBCP | (Database Connection Pool):由Apache开发的一个Java数据库连接池项目, Jakarta commons-pool对象池机制,Tomcat使用的连接池组件就是DBCP。单独使用dbcp需要3个包:common-dbcp.jar,common-pool.jar,common-collections.jar,预先将数据库连接放在内存中,应用程序需要建立数据库连接时直接到连接池中申请一个就行,用完再放回。单线程,并发量低,性能不好,适用于小型系统 |
Tomcat Jdbc Pool | Tomcat在7.0以前都是使用common-dbcp做为连接池组件,但是dbcp是单线程,为保证线程安全会锁整个连接池,性能较差,dbcp有超过60个类,也相对复杂。Tomcat从7.0开始引入了新增连接池模块叫做Tomcat jdbc pool,基于Tomcat JULI,使用Tomcat日志框架,完全兼容dbcp,通过异步方式获取连接,支持高并发应用环境,超级简单核心文件只有8个,支持JMX,支持XA Connection |
BoneCP | 官方说法BoneCP是一个高效、免费、开源的Java数据库连接池实现库。设计初衷就是为了提高数据库连接池性能,根据某些测试数据显示,BoneCP的速度是最快的,要比当时第二快速的连接池快25倍左右,完美集成到一些持久化产品如Hibernate和DataNucleus中。BoneCP特色:高度可扩展,快速;连接状态切换的回调机制;允许直接访问连接;自动化重置能力;JMX支持;懒加载能力;支持XML和属性文件配置方式;较好的Java代码组织,100%单元测试分支代码覆盖率;代码40KB左右 |
Druid | Druid是Java语言中最好的数据库连接池,Druid能够提供强大的监控和扩展功能,是一个可用于大数据实时查询和分析的高容错、高性能的开源分布式系统,尤其是当发生代码部署、机器故障以及其他产品系统遇到宕机等情况时,Druid仍能够保持100%正常运行。主要特色:为分析监控设计;快速的交互式查询;高可用;可扩展;Druid是一个开源项目,源码托管在github上 |
3、Druid连接池介绍及使用
Druid是Java语言中最好的数据库连接池,在功能、性能、扩展性方面,都超过其他数据库连接池,包括DBCP、C3P0、Proxool、JBoss DataSource。Druid已经在阿里巴巴部署了超过600个应用,经过生产环境大规模部署的严苛考验。
Druid连接池为监控而生,内置强大的监控功能,监控特性不影响整体性能。功能强大,能防SQL注入,内置Loging能诊断Hack应用行为
4、配置Druid连接池
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
<!-- jdbc_url是MySQL的连接地址URL。-->
<property name="url" value="${jdbc_url}" />
<!-- jdbc_user是MySQL中的用户账号:高权限账号或者普通账号。 -->
<property name="username" value="${jdbc_user}" />
<!-- jdbc_password是 MySQL用户账号对应的密码。 -->
<property name="password" value="${jdbc_password}" />
<!-- 配置初始化连接池大小、最小连接数、最大连接数。 -->
<property name="initialSize" value="5" />
<property name="minIdle" value="10" />
<property name="maxActive" value="20" />
<!-- 配置获取连接等待超时的时间。 -->
<property name="maxWait" value="60000" />
<!-- 配置一个连接在连接池中的最小生存时间、最大生存时间,超过最大生存时间会被移除,单位毫秒。 -->
<property name="minEvictableIdleTimeMillis" value="600000" />
<property name="maxEvictableIdleTimeMillis" value="900000" />
<!-- 配置间隔多久进行一次检测,检测需要关闭的空闲连接,单位毫秒。 默认是60s,太长可能会导致无法及时检测到连接中断。 -->
<property name="timeBetweenEvictionRunsMillis" value="2000" />
<!-- 配置从连接池获取连接时,当连接空闲时间大于timeBetweenEvictionRunsMillis时是否检查连接有效性,true每次都检查;false不检查。 -->
<property name="testWhileIdle" value="true" />
<!-- 配置从连接池获取连接时和向连接池归还连接时,是否检查连接有效性。 -->
<!-- 每次获取或归还连接都检测太频繁,除非特别重要或网络特别不可靠等情况,建议用testWhileIdle + timeBetweenEvictionRunsMillis代替。 -->
<property name="testOnBorrow" value="false" />
<property name="testOnReturn" value="false" />
<!-- 配置是否定期探活、探活间隔。 -->
<property name="keepAlive" value="true" />
<property name="keepAliveBetweenTimeMillis" value="3000" /> <!-- 默认120s。 -->
<!-- 探活、验证链接有效性的查询,新版本默认使用mysqlPing代替。 -->
<property name="validationQuery" value="select 1" />
<!-- 配置监控统计拦截的filters。 -->
<property name="filters" value="stat" />
</bean>
本文来自博客园,作者:icui4cu,转载请注明原文链接:https://www.cnblogs.com/icui4cu/p/18839016