MyBatis 是一款優(yōu)秀的持久層框架,它支持定制化 SQL、存儲過程以及高級映射。MyBatis 避免了幾乎所有的 JDBC 代碼和手動設(shè)置參數(shù)以及獲取結(jié)果集。MyBatis 可以使用簡單的 XML 或注解來配置和映射原生信息,將接口和 Java 的 POJOs(Plain Old Java Objects,普通的 Java對象)映射成數(shù)據(jù)庫中的記錄。每個MyBatis應(yīng)用程序主要都是使用SqlSessionFactory實例的,一個SqlSessionFactory實例可以通過SqlSessionFactoryBuilder獲得。SqlSessionFactoryBuilder可以從一個xml配置文件或者一個預(yù)定義的配置類的實例獲得。今天我們看一下,他如何同spring boot結(jié)合再一起。
首先我們知道,spring boot 他可以支持xml形式配置Bean,但是它更為推崇的方式是通過代碼的方式,也就是配置類實現(xiàn)配置,因為這樣,我們可以更好的保持代碼的統(tǒng)一性,這樣也會幫助我們更好的查看源碼,所以我們接下來的課程中的所以實例都采用配置類的形式替代xml的配置。
首先還是看下我們的pom文件中引入的jar
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 有數(shù)據(jù)庫鏈接需求時打開-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
</dependency>
上面兩個我們不做贅述了,上一講已經(jīng)提到了,下面我們剩下的。spring-boot-starter-jdbc 主要是spring boot 幫我們封裝好關(guān)于事務(wù)方面需要引入的jar。mybatis 是 mybatis框架所需要的核心包,mybatis-spring是mybatis與spring 結(jié)合需要的bridge包。我們實例中演示中的數(shù)據(jù)庫使用mysql,所以需要mysql-connector-java包,代表了數(shù)據(jù)庫的驅(qū)動。lombok是一個可以通過簡單的注解的形式來幫助我們簡化消除一些必須有但顯得很臃腫的 Java 代碼的工具。druid是阿里巴巴開源的一款數(shù)據(jù)庫連接池的jar,很輕松的引入連接池的功能,相同功能的還有c3p0與dbcp。
剩下的我們講一下我們最重要的配置文件
/**
* pajk.com Inc.
* Copyright (c) 2014-2015 All Rights Reserved.
*/
package com.shuqi;
import com.alibaba.druid.filter.Filter;
import com.alibaba.druid.filter.stat.StatFilter;
import com.alibaba.druid.pool.DruidDataSource;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.Resource;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.transaction.support.TransactionTemplate;
import javax.sql.DataSource;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
@Configuration
@MapperScan(basePackages = "com.shuqi.dal",sqlSessionFactoryRef = "sqlSessionFactory")
@EnableTransactionManagement
public class DalConfig {
@Value(value = "classpath:mybatis/sqlmap/*.xml")
private Resource[] mapperLocations;
@Value(value = "classpath:mybatis/mybatis-config.xml")
private Resource configLocation;
@Bean
public SqlSessionFactoryBean sqlSessionFactory(DruidDataSource dataSource) {
SqlSessionFactoryBean ssfb = new SqlSessionFactoryBean();
ssfb.setMapperLocations(mapperLocations);
ssfb.setConfigLocation(configLocation);
ssfb.setTypeAliasesPackage("com.shuqi.dal.model");
ssfb.setDataSource(dataSource);
return ssfb;
}
@Bean(initMethod = "init", destroyMethod = "close")
public DruidDataSource dataSource(@Value("${ds.jdbc.url}") String url,
@Value("${ds.jdbc.username}") String username,
@Value("${ds.jdbc.password}") String password) throws SQLException {
DruidDataSource druidDataSource = new DruidDataSource();
druidDataSource.setUrl(url);
druidDataSource.setUsername(username);
druidDataSource.setPassword(password);
druidDataSource.setMaxActive(60);
druidDataSource.setInitialSize(1);
druidDataSource.setMaxWait(60000);//60s
druidDataSource.setMinIdle(1);
druidDataSource.setTimeBetweenEvictionRunsMillis(3000);
druidDataSource.setMinEvictableIdleTimeMillis(300000);
druidDataSource.setValidationQuery("select 1");
druidDataSource.setTestWhileIdle(true);
druidDataSource.setTestOnBorrow(false);
druidDataSource.setTestOnReturn(false);
druidDataSource.setPoolPreparedStatements(true);
druidDataSource.setMaxPoolPreparedStatementPerConnectionSize(20);
druidDataSource.setFilters("config");
Properties properties = new Properties();
properties.put("config.decrypt", "false");
druidDataSource.setConnectProperties(properties);
StatFilter statFilter = new StatFilter();
statFilter.setSlowSqlMillis(10000);//10s。。慢
statFilter.setMergeSql(true);
statFilter.setLogSlowSql(true);
List<Filter> filterList = new ArrayList<Filter>();
filterList.add(statFilter);
druidDataSource.setProxyFilters(filterList);
return druidDataSource;
}
@Bean
public TransactionTemplate transactionTemplate(PlatformTransactionManager transactionManager) {
return new TransactionTemplate(transactionManager);
}
@Bean
public PlatformTransactionManager transactionManager(DataSource dataSource) throws SQLException {
return new DataSourceTransactionManager(dataSource);
}
}
@Configuration 注解表示是一個配置類,功能相當(dāng)于傳統(tǒng)的xml配置文件,spring 發(fā)現(xiàn)這個注解,就知道里面的內(nèi)容是Bean,所以也是說被@Configuration注解修飾的類是Bean的容器。@EnableTransactionManagement表示開啟了數(shù)據(jù)庫的事務(wù)。@ MapperScan表示掃描Mapper接口basePackages表示從哪里掃描出的類作為我們的mapper接口,sqlSessionFactoryRef 指定SqlSessionFactoryBean。在這里我們插一句,對不了解mybatis的同學(xué)說,Mybatis的常用使用形式是定義Mapper接口,注意是接口,那么實現(xiàn)呢?一般情況下是使用配置文件,他們怎么關(guān)聯(lián)起來,通過配置文件中的namespace屬性,他里面的值是被實現(xiàn)接口的全限定名稱。下面我們會再提到這里。我們再說dataSource就是使用druid來定義的。他可以支持很多特性,比如對慢SQL的一些監(jiān)控等。有了數(shù)據(jù)源,我們就可以根據(jù)它來定義一個事務(wù)管理器transactionManager。如果你喜歡編程式事務(wù)也可以定義一個transactionTemplate,如果喜歡聲明式事務(wù),就可以直接加@Transactional注解了。當(dāng)然最重要的還是我們的SqlSessionFactoryBean,他設(shè)置了數(shù)據(jù)源DataSource,Mapper文件的地址MapperLocations,也就是Mapper文件存放的地址。Mybatis的配置文件的地址ConfigLocation,也就是mybatis-config存放的地址。基本上都配置好了。下面我們再看看Mapper Interface的內(nèi)容
package com.shuqi.dal.mapper;
import com.shuqi.dal.model.UserDO;
public interface UserMapper {
void create(UserDO userDO);
void modify(UserDO userDO);
UserDO findByName(String name);
}
與 Mapper 文件的內(nèi)容
<?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.shuqi.dal.mapper.UserMapper">
<resultMap id="UserDOResultMap" type="com.shuqi.dal.model.UserDO">
<id column="id" property="id"/>
<result column="gmt_modified" property="gmtModified"/>
<result column="gmt_created" property="gmtCreated"/>
<result column="name" property="name"/>
<result column="status" property="status"/>
</resultMap>
<sql id="Base_Column_List">
gmt_created,id,gmt_modified,`name`,`status`
</sql>
<insert id="create" useGeneratedKeys="true" keyProperty="id">
INSERT INTO `user`
(
gmt_modified ,
gmt_created ,
`name`,
status
)
VALUES (
now() ,
now() ,
#{name},
#{status}
);
</insert>
<update id="modify">
UPDATE `user`
<set>
gmt_modified=now()
<if test="gmtCreated !=null">
,gmt_created = #{gmtCreated}
</if>
<if test="name !=null">
,`name` = #{name}
</if>
<if test="status !=null">
,`status` = #{status}
</if>
</set>
where
id=#{id};
</update>
<select id="findByName" resultMap="UserDOResultMap">
SELECT
<include refid="Base_Column_List"/>
from `user` where name=#{name}
</select>
</mapper>
看下namespace的定義就知道他們是怎么關(guān)聯(lián)的了。看一下每個代碼塊中的ID,就知道怎么和接口中的方法對應(yīng)了。
下節(jié)將的內(nèi)容是:SpringBoot基礎(chǔ)教程(三)——多數(shù)據(jù)源結(jié)合