spring 整合 mybatis 中数据源的几种配置方式

  因为spring 整合mybatis的过程中, 有好几种整合方式,尤其是数据源那块,经常看到不一样的配置方式,总感觉有点乱,所以今天有空总结下。

  

  一、采用org.mybatis.spring.mapper.MapperScannerConfigurer

  其实逆向工程也是这种方式

  1、数据源配配置文件

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <beans xmlns="http://www.springframework.org/schema/beans"
 3     xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"
 4     xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
 5     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 6     xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
 7     http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
 8     http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
 9     http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd">
10 
11     <!-- 加载配置文件 -->
12     <context:property-placeholder location="classpath:resource/*.properties" />
13 
14     <!-- 数据库连接池 -->
15     <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"
16         destroy-method="close">
17         <property name="driverClassName" value="${jdbc.driver}" />
18         <property name="url" value="${jdbc.url}" />
19         <property name="username" value="${jdbc.username}" />
20         <property name="password" value="${jdbc.password}" />
21         <property name="maxActive" value="10" />
22         <property name="minIdle" value="5" />
23     </bean>
24     <!-- sqlsessionFactory -->
25     <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
26         <property name="configLocation" value="classpath:mybatis/SqlMapConfig.xml"></property>
27         <property name="dataSource" ref="dataSource"></property>
28     </bean>
29 
30     <!-- 加载mapper代理对象 -->
31     <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
32         <property name="basePackage" value="com.jdd.mapper"></property>
33         <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property>
34     </bean>
35 
36 </beans>

  2、DAO文件

 1 package com.jdd.mapper;
 2 
 3 import com.jdd.pojo.Employee;
 4 import java.util.List;
 5 
 6 public interface EmployeeMapper {
 7 
 8     public Employee getEmployeeById(int id);
 9 
10     public List<Employee> findAllEmployees();
11 
12 }

  3、Mapper.xml 文件

 1 <?xml version="1.0" encoding="UTF-8" ?>
 2 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 3 "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 4 
 5 <mapper namespace="com.jdd.mapper.EmployeeMapper">
 6 
 7     <select id="getEmployeeById" parameterType="int" resultType="com.jdd.pojo.Employee">
 8         <![CDATA[
 9             select * from employee where id = #{id};
10         ]]>
11     </select>
12     
13     <select id="findAllEmployees" resultType="com.jdd.pojo.Employee">
14         <![CDATA[
15             select * from employee where status='1';
16         ]]>
17     </select>
18 
19     
20 </mapper>

  这样在service类里就可以直接注入dao接口了

 1 package com.jdd.service.impl;
 2 
 3 import com.jdd.mapper.EmployeeMapper;
 4 import com.jdd.pojo.Employee;
 5 import com.jdd.service.EmployeeService;
 6 import org.springframework.beans.factory.annotation.Autowired;
 7 import org.springframework.stereotype.Service;
 8 import java.util.List;
 9 
10 @Service("employeeService")
11 public class EmployeeServiceImpl implements EmployeeService{
12 
13     @Autowired
14     private EmployeeMapper employeeMapper;
15 
16     @Override
17     public Employee getEmployeeById(int id) {
18         return employeeMapper.getEmployeeById(id);
19     }
20 
21     @Override
22     public List<Employee> findAllEmployees() {
23         return employeeMapper.findAllEmployees();
24     }
25 
26 }

  

  二、 采用抽象类org.mybatis.spring.support.SqlSessionDaoSupport, 给它注入 sqlSessionFactory的方式

  1、数据源配置文件

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <beans xmlns="http://www.springframework.org/schema/beans"
 3     xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"
 4     xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
 5     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 6     xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
 7     http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
 8     http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
 9     http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd">
10 
11     <!-- 加载配置文件 -->
12     <context:property-placeholder location="classpath:resource/*.properties" />
13 
14     <!-- 数据库连接池 -->
15     <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"
16         destroy-method="close">
17         <property name="driverClassName" value="${jdbc.driver}" />
18         <property name="url" value="${jdbc.url}" />
19         <property name="username" value="${jdbc.username}" />
20         <property name="password" value="${jdbc.password}" />
21         <property name="maxActive" value="10" />
22         <property name="minIdle" value="5" />
23     </bean>
24 
25     
26     <!-- sqlsessionFactory -->
27     <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
28         <property name="configLocation" value="classpath:mybatis/SqlMapConfig.xml"></property>
29         <property name="dataSource" ref="dataSource"></property>
30         <property name="mapperLocations" value="classpath:com/jdd/mapper/*.xml"></property>
31     </bean>
32     
34 </beans>

  2、baseDao类

 1 package com.hd.dao;
 2 
 3 import org.apache.ibatis.session.SqlSessionFactory;
 4 import org.mybatis.spring.support.SqlSessionDaoSupport;
 5 import javax.annotation.Resource;
 6 
 7 public abstract class BaseDao extends SqlSessionDaoSupport {
 8 
 9     @Resource
10     public void setSqlSessionFactory(SqlSessionFactory sqlSessionFactory) {
11         super.setSqlSessionFactory(sqlSessionFactory);
12     }
13 
14 }

  3、接口 EmployeeDao.java 类

 1 package com.hd.dao;
 2 
 3 import com.hd.pojo.Employee;
 4 
 5 import java.util.List;
 6 
 7 public interface EmployeeDao {
 8 
 9     Employee getEmployeeById(int id);
10 
11     List<Employee> findAllEmployees();
12 
13 }

  4、dao实现类 EmployeeDaoImpl

 1 package com.hd.dao.impl;
 2 
 3 import com.hd.dao.BaseDao;
 4 import com.hd.dao.EmployeeDao;
 5 import com.hd.pojo.Employee;
 6 import org.springframework.stereotype.Repository;
 7 import java.util.List;
 8 
 9 @Repository("employeeDao")
10 public class EmployeeDaoImpl extends BaseDao implements EmployeeDao {
11 
12     @Override
13     public Employee getEmployeeById(int id) {
14         return this.getSqlSession().selectOne("com.jdd.dao.EmployeeDao.getEmployeeById", id);
15     }
16 
17     @Override
18     public List<Employee> findAllEmployees() {
19         return this.getSqlSession().selectList("com.jdd.dao.EmployeeDao.findAllEmployees");
20     }
21 
22    
23 }

  5、这样就可以在service类里注入 employeeDao了

  三、采用 org.mybatis.spring.SqlSessionTemplate 模板类

  1、数据源文件

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <beans xmlns="http://www.springframework.org/schema/beans"
 3     xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"
 4     xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
 5     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 6     xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
 7     http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
 8     http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
 9     http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd">
10 
11     <!-- 加载配置文件 -->
12     <context:property-placeholder location="classpath:resource/*.properties" />
13 
14     <!-- 数据库连接池 -->
15         <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"
16         destroy-method="close">
17         <property name="driverClassName" value="${jdbc.driver}" />
18         <property name="url" value="${jdbc.url}" />
19         <property name="username" value="${jdbc.username}" />
20         <property name="password" value="${jdbc.password}" />
21         <property name="maxActive" value="10" />
22         <property name="minIdle" value="5" />
23     </bean>
24     
25     <!-- sqlsessionFactory -->
26     <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
27         <property name="configLocation" value="classpath:mybatis/SqlMapConfig.xml"></property>
28         <property name="dataSource" ref="dataSource"></property>
29         <property name="mapperLocations" value="classpath:com/jdd/mapper/*.xml"></property>
30     </bean>
31 
32     <bean id="sqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate">
33         <constructor-arg index="0" ref="sqlSessionFactory"/>
34     </bean>
35 
36 </beans>

  2、 basedao.java 类

 1 package com.hd.dao;
 2 
 3 import org.mybatis.spring.SqlSessionTemplate;
 4 import javax.annotation.Resource;
 5 
 6 public abstract class BaseDao {
 7 
 8     public SqlSessionTemplate sqlSessionTemplate;
 9     @Resource
10     public void setSqlSessionTemplate(SqlSessionTemplate sqlSessionTemplate) {
11         this.sqlSessionTemplate = sqlSessionTemplate;
12     }
13 }

  3、接口 EmployeeDao.java 类

 1 package com.hd.dao;
 2 
 3 import com.hd.pojo.Employee;
 5 import java.util.List;
 6 
 7 public interface EmployeeDao {
 8 
 9     Employee getEmployeeById(int id);
10 
11     List<Employee> findAllEmployees();
12 }

  4、dao实现类 EmployeeDaoImpl

 1 package com.hd.dao.impl;
 2 
 3 import com.hd.dao.BaseDao;
 4 import com.hd.dao.EmployeeDao;
 5 import com.hd.pojo.Employee;
 6 import org.springframework.stereotype.Repository;
 7 import java.util.List;
 8 
 9 @Repository("employeeDao")
10 public class EmployeeDaoImpl extends BaseDao implements EmployeeDao {
11 
12     @Override
13     public Employee getEmployeeById(int id) {
14         return sqlSessionTemplate.selectOne("com.jdd.dao.EmployeeDao.getEmployeeById", id);
15     }
16 
17     @Override
18     public List<Employee> findAllEmployees() {
19         return sqlSessionTemplate.selectList("com.jdd.dao.EmployeeDao.findAllEmployees");
20     }
21 
22 
23 }

  5、同样现在也可以在service类里直接注入 employeeDao使用了。

  注:这里basedao的注入比较灵活,也可以注入 SqlSessionFactory, 然后再setter方法里创建 SqlSessionTemplate,如下:

 1 package com.hd.dao;
 2 
 3 import org.apache.ibatis.session.SqlSessionFactory;
 4 import org.mybatis.spring.SqlSessionTemplate;
 5 
 6 import javax.annotation.Resource;
 7 
 8 public abstract class BaseDao {
 9 
10     public SqlSessionTemplate sqlSessionTemplate;
11     @Resource
12     public void setSqlSessionFactory(SqlSessionFactory sqlSessionFactory) {
13         sqlSessionTemplate = new SqlSessionTemplate(sqlSessionFactory);
14     }
15 
16 }

  

  其实不管是采用 继承SqlSessionDaoSupport类, 注入 sqlSessionFactory的方式, 还是直接注入 SqlSessionTemplate 的方式, 本质上是一样的。

  如果你采用 注入 sqlSessionFactory的方式, 它在底层也是通过sqlSessionFactory 来创建 SqlSessionTemplate ,然后通过其api来操作。

  不信给你们看下 SqlSessionDaoSupport 的源码:

 1 //
 2 // Source code recreated from a .class file by IntelliJ IDEA
 3 // (powered by Fernflower decompiler)
 4 //
 5 
 6 package org.mybatis.spring.support;
 7 
 8 import org.apache.ibatis.session.SqlSession;
 9 import org.apache.ibatis.session.SqlSessionFactory;
10 import org.mybatis.spring.SqlSessionTemplate;
11 import org.springframework.dao.support.DaoSupport;
12 import org.springframework.util.Assert;
13 
14 public abstract class SqlSessionDaoSupport extends DaoSupport {
15     private SqlSession sqlSession;
16     private boolean externalSqlSession;
17 
18     public SqlSessionDaoSupport() {
19     }
20 
21     public void setSqlSessionFactory(SqlSessionFactory sqlSessionFactory) {
22         if (!this.externalSqlSession) {
23             this.sqlSession = new SqlSessionTemplate(sqlSessionFactory);
24         }
25 
26     }
27 
28     public void setSqlSessionTemplate(SqlSessionTemplate sqlSessionTemplate) {
29         this.sqlSession = sqlSessionTemplate;
30         this.externalSqlSession = true;
31     }
32 
33     public SqlSession getSqlSession() {
34         return this.sqlSession;
35     }
36 
37     protected void checkDaoConfig() {
38         Assert.notNull(this.sqlSession, "Property 'sqlSessionFactory' or 'sqlSessionTemplate' are required");
39     }
40 }

  同样 SqlSessionTemplate 继承了 SqlSession 接口, 因此不管操作哪个效果都一样

  1 //
  2 // Source code recreated from a .class file by IntelliJ IDEA
  3 // (powered by Fernflower decompiler)
  4 //
  5 
  6 package org.mybatis.spring;
  7 
  8 import java.lang.reflect.InvocationHandler;
  9 import java.lang.reflect.Method;
 10 import java.lang.reflect.Proxy;
 11 import java.sql.Connection;
 12 import java.util.List;
 13 import java.util.Map;
 14 import org.apache.ibatis.exceptions.PersistenceException;
 15 import org.apache.ibatis.executor.BatchResult;
 16 import org.apache.ibatis.reflection.ExceptionUtil;
 17 import org.apache.ibatis.session.Configuration;
 18 import org.apache.ibatis.session.ExecutorType;
 19 import org.apache.ibatis.session.ResultHandler;
 20 import org.apache.ibatis.session.RowBounds;
 21 import org.apache.ibatis.session.SqlSession;
 22 import org.apache.ibatis.session.SqlSessionFactory;
 23 import org.springframework.dao.support.PersistenceExceptionTranslator;
 24 import org.springframework.util.Assert;
 25 
 26 public class SqlSessionTemplate implements SqlSession {
 27     private final SqlSessionFactory sqlSessionFactory;
 28     private final ExecutorType executorType;
 29     private final SqlSession sqlSessionProxy;
 30     private final PersistenceExceptionTranslator exceptionTranslator;
 31 
 32     public SqlSessionTemplate(SqlSessionFactory sqlSessionFactory) {
 33         this(sqlSessionFactory, sqlSessionFactory.getConfiguration().getDefaultExecutorType());
 34     }
 35 
 36     public SqlSessionTemplate(SqlSessionFactory sqlSessionFactory, ExecutorType executorType) {
 37         this(sqlSessionFactory, executorType, new MyBatisExceptionTranslator(sqlSessionFactory.getConfiguration().getEnvironment().getDataSource(), true));
 38     }
 39 
 40     public SqlSessionTemplate(SqlSessionFactory sqlSessionFactory, ExecutorType executorType, PersistenceExceptionTranslator exceptionTranslator) {
 41         Assert.notNull(sqlSessionFactory, "Property 'sqlSessionFactory' is required");
 42         Assert.notNull(executorType, "Property 'executorType' is required");
 43         this.sqlSessionFactory = sqlSessionFactory;
 44         this.executorType = executorType;
 45         this.exceptionTranslator = exceptionTranslator;
 46         this.sqlSessionProxy = (SqlSession)Proxy.newProxyInstance(SqlSessionFactory.class.getClassLoader(), new Class[]{SqlSession.class}, new SqlSessionTemplate.SqlSessionInterceptor());
 47     }
 48 
 49     public SqlSessionFactory getSqlSessionFactory() {
 50         return this.sqlSessionFactory;
 51     }
 52 
 53     public ExecutorType getExecutorType() {
 54         return this.executorType;
 55     }
 56 
 57     public PersistenceExceptionTranslator getPersistenceExceptionTranslator() {
 58         return this.exceptionTranslator;
 59     }
 60 
 61     public <T> T selectOne(String statement) {
 62         return this.sqlSessionProxy.selectOne(statement);
 63     }
 64 
 65     public <T> T selectOne(String statement, Object parameter) {
 66         return this.sqlSessionProxy.selectOne(statement, parameter);
 67     }
 68 
 69     public <K, V> Map<K, V> selectMap(String statement, String mapKey) {
 70         return this.sqlSessionProxy.selectMap(statement, mapKey);
 71     }
 72 
 73     public <K, V> Map<K, V> selectMap(String statement, Object parameter, String mapKey) {
 74         return this.sqlSessionProxy.selectMap(statement, parameter, mapKey);
 75     }
 76 
 77     public <K, V> Map<K, V> selectMap(String statement, Object parameter, String mapKey, RowBounds rowBounds) {
 78         return this.sqlSessionProxy.selectMap(statement, parameter, mapKey, rowBounds);
 79     }
 80 
 81     public <E> List<E> selectList(String statement) {
 82         return this.sqlSessionProxy.selectList(statement);
 83     }
 84 
 85     public <E> List<E> selectList(String statement, Object parameter) {
 86         return this.sqlSessionProxy.selectList(statement, parameter);
 87     }
 88 
 89     public <E> List<E> selectList(String statement, Object parameter, RowBounds rowBounds) {
 90         return this.sqlSessionProxy.selectList(statement, parameter, rowBounds);
 91     }
 92 
 93     public void select(String statement, ResultHandler handler) {
 94         this.sqlSessionProxy.select(statement, handler);
 95     }
 96 
 97     public void select(String statement, Object parameter, ResultHandler handler) {
 98         this.sqlSessionProxy.select(statement, parameter, handler);
 99     }
100 
101     public void select(String statement, Object parameter, RowBounds rowBounds, ResultHandler handler) {
102         this.sqlSessionProxy.select(statement, parameter, rowBounds, handler);
103     }
104 
105     public int insert(String statement) {
106         return this.sqlSessionProxy.insert(statement);
107     }
108 
109     public int insert(String statement, Object parameter) {
110         return this.sqlSessionProxy.insert(statement, parameter);
111     }
112 
113     public int update(String statement) {
114         return this.sqlSessionProxy.update(statement);
115     }
116 
117     public int update(String statement, Object parameter) {
118         return this.sqlSessionProxy.update(statement, parameter);
119     }
120 
121     public int delete(String statement) {
122         return this.sqlSessionProxy.delete(statement);
123     }
124 
125     public int delete(String statement, Object parameter) {
126         return this.sqlSessionProxy.delete(statement, parameter);
127     }
128 
129     public <T> T getMapper(Class<T> type) {
130         return this.getConfiguration().getMapper(type, this);
131     }
132 
133     public void commit() {
134         throw new UnsupportedOperationException("Manual commit is not allowed over a Spring managed SqlSession");
135     }
136 
137     public void commit(boolean force) {
138         throw new UnsupportedOperationException("Manual commit is not allowed over a Spring managed SqlSession");
139     }
140 
141     public void rollback() {
142         throw new UnsupportedOperationException("Manual rollback is not allowed over a Spring managed SqlSession");
143     }
144 
145     public void rollback(boolean force) {
146         throw new UnsupportedOperationException("Manual rollback is not allowed over a Spring managed SqlSession");
147     }
148 
149     public void close() {
150         throw new UnsupportedOperationException("Manual close is not allowed over a Spring managed SqlSession");
151     }
152 
153     public void clearCache() {
154         this.sqlSessionProxy.clearCache();
155     }
156 
157     public Configuration getConfiguration() {
158         return this.sqlSessionFactory.getConfiguration();
159     }
160 
161     public Connection getConnection() {
162         return this.sqlSessionProxy.getConnection();
163     }
164 
165     public List<BatchResult> flushStatements() {
166         return this.sqlSessionProxy.flushStatements();
167     }
168 
169     private class SqlSessionInterceptor implements InvocationHandler {
170         private SqlSessionInterceptor() {
171         }
172 
173         public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
174             SqlSession sqlSession = SqlSessionUtils.getSqlSession(SqlSessionTemplate.this.sqlSessionFactory, SqlSessionTemplate.this.executorType, SqlSessionTemplate.this.exceptionTranslator);
175 
176             Object unwrapped;
177             try {
178                 Object result = method.invoke(sqlSession, args);
179                 if (!SqlSessionUtils.isSqlSessionTransactional(sqlSession, SqlSessionTemplate.this.sqlSessionFactory)) {
180                     sqlSession.commit(true);
181                 }
182 
183                 unwrapped = result;
184             } catch (Throwable var11) {
185                 unwrapped = ExceptionUtil.unwrapThrowable(var11);
186                 if (SqlSessionTemplate.this.exceptionTranslator != null && unwrapped instanceof PersistenceException) {
187                     SqlSessionUtils.closeSqlSession(sqlSession, SqlSessionTemplate.this.sqlSessionFactory);
188                     sqlSession = null;
189                     Throwable translated = SqlSessionTemplate.this.exceptionTranslator.translateExceptionIfPossible((PersistenceException)unwrapped);
190                     if (translated != null) {
191                         unwrapped = translated;
192                     }
193                 }
194 
195                 throw (Throwable)unwrapped;
196             } finally {
197                 if (sqlSession != null) {
198                     SqlSessionUtils.closeSqlSession(sqlSession, SqlSessionTemplate.this.sqlSessionFactory);
199                 }
200 
201             }
202 
203             return unwrapped;
204         }
205     }
206 }
原文地址:https://www.cnblogs.com/xiexin2015/p/8998331.html