MyBatis學習-使用Druid連線池將Maybatis整合到spring
目錄
前言
在MyBatis學習-連線oracle實現CURD操作實現了MyBatis基本配置與CRUD操作。但是每次都是手工建立SqlSessionFactory本篇將通過spring來管理bean,同時使用Druid連線池替換自帶的連線池。
什麼是Druid連線池
Druid是一個JDBC元件,它包括三部分:
- DruidDriver 代理Driver,能夠提供基於Filter-Chain模式的外掛體系。
- DruidDataSource 高效可管理的資料庫連線池。
- SQLParser
Druid可以做什麼?
- 可以監控資料庫訪問效能,Druid內建提供了一個功能強大的StatFilter外掛,能夠詳細統計SQL的執行效能,這對於線上分析資料庫訪問效能有幫助。
- 替換DBCP和C3P0。Druid提供了一個高效、功能強大、可擴充套件性好的資料庫連線池。
- 資料庫密碼加密。直接把資料庫密碼寫在配置檔案中,這是不好的行為,容易導致安全問題。DruidDruiver和DruidDataSource都支援PasswordCallback。
- SQL執行日誌,Druid提供了不同的LogFilter,能夠支援Common-Logging、Log4j和JdkLog,你可以按需要選擇相應的LogFilter,監控你應用的資料庫訪問情況。
擴充套件JDBC,如果你要對JDBC層有程式設計的需求,可以通過Druid提供的Filter-Chain機制,很方便編寫JDBC層的擴充套件外掛。
匯入庫包
連線oracle
如果我們要連線oracle資料庫,需要匯入oralce的jdbc的包。但是由於oracle收費, 因此maven沒有oracle庫包,需要我們自己手工匯入外部包。或者也可以將oracle的jar匯入到maven庫中。具體匯入步驟可以檢視
<dependency>
<groupId>com.oracle.jdbc</groupId>
<artifactId>ojdbc6</artifactId>
<version>11.2.0.1.0</version>
</dependency>
連線mysql
由於mysql是免費的,我們可以通過maven直接安裝mysql的jdbc資料庫連線包
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.21</version>
</dependency>
匯入mybatis
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.5</version>
</dependency>
匯入druid
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.11</version>
</dependency>
匯入spring-jdbc包
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.2.8.RELEASE</version>
</dependency>
匯入spring包
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.8.RELEASE</version>
</dependency>
匯入spring事務相關包
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>5.2.8.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.2.8.RELEASE</version>
</dependency>
匯入mybatis-spring整合包
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.3.1</version>
</dependency>
配置
下面使用過mysql資料庫為例。
資料庫配置
在resources目錄下新建一個mysql.properities檔案,用於配置連線資料庫的相關配置。
druid.url=jdbc:mysql://localhost:3306/mysql?serverTimezone=UTC
#這個可以預設的,會根據url自動識別
druid.driverClassName=com.mysql.cj.jdbc.Driver
druid.username=root
druid.password=123456
##初始連線數,預設0
druid.initialSize=10
#最大連線數,預設8
druid.maxActive=30
#最小閒置數
druid.minIdle=10
#獲取連線的最大等待時間,單位毫秒
druid.maxWait=2000
#快取PreparedStatement,預設false
druid.poolPreparedStatements=true
#快取PreparedStatement的最大數量,預設-1(不快取)。大於0時會自動開啟快取PreparedStatement,所以可以省略上一句設定
druid.maxOpenPreparedStatements=20
druid配置
在resources目錄下新建一個applicationContext-mysql.xml檔案,用於配置mysql的druid的資料庫連線池配置以及注入到spring的bean。
- 資料來源的配置從mysql.propertie獲取的
<!--從mysql.properties載入配置-->
<context:property-placeholder location="classpath:mysql.properties" />
<!--druid連線池-->
<bean name="druidDataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="url" value="${druid.url}" />
<property name="driverClassName" value="${druid.driverClassName}" />
<property name="username" value="${druid.username}" />
<property name="password" value="${druid.password}" />
<property name="initialSize" value="${druid.initialSize}"/>
<property name="maxActive" value="${druid.maxActive}" />
<property name="minIdle" value="${druid.minIdle}" />
<property name="maxWait" value="${druid.maxWait}" />
<property name="poolPreparedStatements" value="${druid.poolPreparedStatements}" />
<property name="maxOpenPreparedStatements" value="${druid.maxOpenPreparedStatements}" />
</bean>
- spring管理事務
<!--事務管理-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="druidDataSource"/>
</bean>
<!-- 使用annotation註解方式配置事務 -->
<tx:annotation-driven transaction-manager="transactionManager"/>
- 根據mapper生成代理
sqlSessionFactory需要注入資料來源和配置檔案路徑,spring會生成runoob_tblMapper
,我們通過這個值取bean就能對資料庫進行操作了。
<!-- 配置sqlSessionFactory,SqlSessionFactoryBean是用來產生sqlSessionFactory的 -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!--注入資料來源-->
<property name="dataSource" ref="druidDataSource"/>
<property name="configLocation" value="classpath:conf.xml"/>
</bean>
<!-- MapperFactoryBean:根據mapper介面生成的代理物件 -->
<bean id="runoob_tblMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">
<property name="mapperInterface" value="mysql.dao.runoob_tblMapper"/>
<property name="sqlSessionFactory" ref="sqlSessionFactory" />
</bean>
完整配置如下
<context:property-placeholder location="classpath:mysql.properties" />
<!--druid連線池-->
<bean name="druidDataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="url" value="${druid.url}" />
<property name="driverClassName" value="${druid.driverClassName}" />
<property name="username" value="${druid.username}" />
<property name="password" value="${druid.password}" />
<property name="initialSize" value="${druid.initialSize}"/>
<property name="maxActive" value="${druid.maxActive}" />
<property name="minIdle" value="${druid.minIdle}" />
<property name="maxWait" value="${druid.maxWait}" />
<property name="poolPreparedStatements" value="${druid.poolPreparedStatements}" />
<property name="maxOpenPreparedStatements" value="${druid.maxOpenPreparedStatements}" />
</bean>
<!--事務管理-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="druidDataSource"/>
</bean>
<!-- 使用annotation註解方式配置事務 -->
<tx:annotation-driven transaction-manager="transactionManager"/>
<!--mybatis工廠-->
<!-- 配置sqlSessionFactory,SqlSessionFactoryBean是用來產生sqlSessionFactory的 -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!--注入資料來源-->
<property name="dataSource" ref="druidDataSource"/>
<property name="configLocation" value="classpath:conf.xml"/>
</bean>
<!-- MapperFactoryBean:根據mapper介面生成的代理物件 -->
<bean id="runoob_tblMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">
<property name="mapperInterface" value="mysql.dao.runoob_tblMapper"/>
<property name="sqlSessionFactory" ref="sqlSessionFactory" />
</bean>
- 新增conf.xml 配置對映的檔案
<configuration>
<mappers>
<mapper resource="mapper/runoob_tblMapper.xml"></mapper>
</mappers>
</configuration>
- 在resources/mapper下新增runoob_tblMapper.xml
<mapper namespace="mysql.dao.runoob_tblMapper">
<insert id="insert" parameterType="mysql.dto.runoob_tbl" keyProperty="runoob_id" useGeneratedKeys="true">
insert into runoob_tbl(runoob_title, runoob_author, submission_date) values(#{runoob_title},#{runoob_author},#{submission_date})
</insert>
</mapper>
新增一個dto
在mysql.dto新增類
public class runoob_tbl {
public String runoob_id;
public String runoob_title;
public String runoob_author;
public Date submission_date;
@Override
public String toString() {
return this.runoob_id + "," + this.runoob_title + "," + this.runoob_author + "," + this.submission_date;
}
public String getRunoob_id() {
return runoob_id;
}
public void setRunoob_id(String runoob_id) {
this.runoob_id = runoob_id;
}
public String getRunoob_title() {
return runoob_title;
}
public void setRunoob_title(String runoob_title) {
this.runoob_title = runoob_title;
}
public String getRunoob_author() {
return runoob_author;
}
public void setRunoob_author(String runoob_author) {
this.runoob_author = runoob_author;
}
public Date getSubmission_date() {
return submission_date;
}
public void setSubmission_date(Date submission_date) {
this.submission_date = submission_date;
}
}
在資料庫中新增表
create table runoob_tbl
(
runoob_id int unsigned auto_increment primary key,
runoob_title varchar(100) not null,
runoob_author varchar(40) not null,
submission_date date null
)charset = utf8;
建立mapper
在mysql.dao新增runoob_tblMapper.java
這個介面名需要和runoob_tblMapper配置的名稱空間一致
public interface runoob_tblMapper {
int insert(runoob_tbl tbl);
}
新增入庫的單元測試
需要在pom引入junit包
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
新增ruidmybatistest單元測試,插入一條記錄。
public class ruidmybatistest {
@Test
public void testGetUserList(){
try
{
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext-mysql.xml");
runoob_tblMapper mapper = ctx.getBean("runoob_tblMapper",runoob_tblMapper.class);
runoob_tbl tbl = new runoob_tbl();
tbl.setRunoob_author("jake");
tbl.setRunoob_title("redis");
tbl.setSubmission_date(new Date());
int count = mapper.insert(tbl);
System.out.println(count);
}catch (Exception exception)
{
System.out.println(exception.getMessage());
}
}
}
通過MapperScannerConfigurer減少配置
通過上面配置,每個mapper都需要配置bean,若mapper比較多,配置的就很麻煩,可以通過MapperScannerConfigurer實現自動掃描,而無需配置mapper了
在sqlSessionFactory新增一個mapperLocations屬性,對映mapper下所有Mapper結尾的配置。
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!--注入資料來源-->
<property name="dataSource" ref="druidDataSource"/>
<property name="configLocation" value="classpath:mapperConf.xml"/>
<property name="mapperLocations" value="classpath:mapper/*Mapper.xml"/>
</bean>
<!-- <bean id="runoob_tblMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">-->
<!-- <property name="mapperInterface" value="mysql.dao.runoob_tblMapper"/>-->
<!-- <property name="sqlSessionFactory" ref="sqlSessionFactory" />-->
<!-- </bean>-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="mysql.dao" />
</bean>
新增一個student表
create table student
(
name varchar(32) null,
age int null,
id int auto_increment,
constraint student_pk
primary key (id)
);
新增studentdto
public class student {
public String id;
public String name;
public int age;
@Override
public String toString() {
return this.id + "," + this.name + "," + this.age;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
新增studentdao
public interface studentMapper {
List<runoob_tbl> selectByNames(List<String> name);
}
新增studentmapper.xml
在resources/mapper下新增studentmapper.xml
<mapper namespace="mysql.dao.studentMapper">
<select id="selectByNames" resultType="mysql.dto.student">
select * from student where name in
<foreach item="name" index="index" collection="list" open="(" separator="," close=")">#{name}</foreach>
</select>
</mapper>
新增單元測試
public class studenttest {
@Test
public void testGetList(){
try
{
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext-mysql.xml");
studentMapper mapper = ctx.getBean("studentMapper",studentMapper.class);
List<Integer> ages= new ArrayList<Integer>();
ages.add(10);
ages.add(20);
List<student> blog = mapper.selectByAge(ages);
for (student item : blog) {
System.out.println(item);
}
}catch (Exception exception)
{
System.out.println(exception.getMessage());
}
}
}