Spring MyBatis 版本如下:
spring
4.2.6.RELEASE
mybatis 3.4.0
mybatis-spring 1.3.0
Spring集成MyBatis的DAO层两种实现方式如下
第一种基于传统DAO层接口实现类方式:
public interface IUserDAO extends IGenericDAO<User, Long> {
}
@Repository("userDAO")
public class UserDAOImpl extends GenericDAOImpl<User, Long> implements IUserDAO {
}
@Repository("genericDAO")
public class GenericDAOImpl<Entity extends Serializable, PK extends Serializable>
extends SqlSessionDaoSupport implements IGenericDAO<Entity, PK> {
@Resource(name = "sqlSessionTemplate")
protected SqlSessionTemplate sqlSessionTemplate = null;
public static final String INSERT = "insert";
public static final String INSERT_BATCH = "insertBatch";
public static final String UPDATE = "update";
public static final String UPDATE_BATCH = "updateBatch";
public static final String DELETE_BY_PK = "deleteByPK";
public static final String READ_DATA_BY_PK = "readDataByPK";
public static final String READ_DATA_BY_CONDITION = "readDataByCondition";
public static final String READ_DATA_LIST_BY_CONDITION = "readDataListByCondition";
public static final String READ_DATA_PAGINATION_BY_CONDITION = "readDataPaginationByCondition";
public static final String READ_COUNT_BY_CONDITION = "readCountByCondition";
private Class<Entity> entityClass = null;
@SuppressWarnings("unchecked")
public GenericDAOImpl() {
Type type = getClass().getGenericSuperclass();
if (type instanceof ParameterizedType) {
entityClass = (Class<Entity>) ((ParameterizedType) type).getActualTypeArguments()[0];
}
}
@Override
@Resource(name = "sqlSessionTemplate")
public void setSqlSessionTemplate(SqlSessionTemplate sqlSessionTemplate) {
super.setSqlSessionTemplate(sqlSessionTemplate);
}
protected SqlSession sqlSession() {
return sqlSessionTemplate.getSqlSessionFactory().openSession();
}
protected void closeSession(SqlSession sqlSession) {
if (null != sqlSession) sqlSession.close();
}
protected SqlSession batchSqlSession() {
return sqlSessionTemplate.getSqlSessionFactory().openSession(ExecutorType.BATCH);
}
protected String obtainSQLID(String sqlId) {
Configuration configuration = sqlSessionTemplate.getConfiguration();
String dialect = "mysql";
if (null != configuration.getVariables()) {
dialect = configuration.getVariables().getProperty("dialect");
}
StringBuffer sb = new StringBuffer();
sb.append(dialect).append(".").append(entityClass.getName()).append(".").append(sqlId);
return sb.toString();
}
@Override
public void insert(Entity entity) {
sqlSessionTemplate.insert(obtainSQLID(INSERT), entity);
}
@Override
public void insert(List<Entity> entities) throws DataException {
SqlSession sqlSession = batchSqlSession();
for (int i = 0, len = entities.size(); i < len; i++) {
sqlSession.insert(obtainSQLID(INSERT), entities.get(i));
}
sqlSession.flushStatements();
closeSession(sqlSession);
}
@Override
public void update(Entity entity) {
sqlSessionTemplate.update(obtainSQLID(UPDATE), entity);
}
@Override
public void update(List<Entity> entities) throws DataException {
SqlSession sqlSession = batchSqlSession();
for (int i = 0, len = entities.size(); i < len; i++) {
sqlSession.update(obtainSQLID(UPDATE), entities.get(i));
}
sqlSession.flushStatements();
closeSession(sqlSession);
}
@Override
public void delete(Entity entity) throws DataException {
}
@Override
public void deleteByPK(PK primaryKey) {
sqlSessionTemplate.delete(obtainSQLID(DELETE_BY_PK), primaryKey);
}
@SuppressWarnings("unchecked")
@Override
public Entity readDataByPK(PK pk) {
return (Entity) sqlSessionTemplate.selectOne(obtainSQLID(READ_DATA_BY_PK), pk);
}
@SuppressWarnings("unchecked")
@Override
public Entity readDataByCondition(Query query) {
Map<String, Object> map = query.getCondition();
return (Entity) sqlSessionTemplate.selectOne(obtainSQLID(READ_DATA_BY_CONDITION), map);
}
@SuppressWarnings("unchecked")
@Override
public List<Entity> readDataListByCondition(Query query) throws DataException {
Map<String, Object> map = query.getCondition();
List<Object> resultList = (List<Object>) sqlSessionTemplate.selectList(
obtainSQLID(READ_DATA_LIST_BY_CONDITION), map);
List<Entity> entities = new ArrayList<Entity>();
for (int i = 0, len = resultList.size(); i < len; i++) {
entities.add((Entity) resultList.get(i));
}
return entities;
}
@SuppressWarnings("unchecked")
@Override
public QueryResult<Entity> readDataPaginationByCondition(Query query) throws DataException {
Map<String, Object> map = query.getCondition();
List<Object> resultList = (List<Object>) sqlSessionTemplate.selectList(
obtainSQLID(READ_DATA_PAGINATION_BY_CONDITION), map);
List<Entity> entities = new ArrayList<Entity>();
for (int i = 0, len = resultList.size(); i < len; i++) {
entities.add((Entity) resultList.get(i));
}
int totalRowNum = (Integer) map.get(Query.TOTAL_ROW_NUM);
return new QueryResult<Entity>(totalRowNum, entities);
}
@Override
public Long readCountByCondition(Query query) throws DataException {
Map<String, Object> map = query.getCondition();
return (Long) sqlSessionTemplate.selectOne(obtainSQLID(READ_COUNT_BY_CONDITION), map);
}
@Override
public void flush() throws DataException {
sqlSessionTemplate.clearCache();
}
}
这里需要注意的是
mybatis-spring 1.1.0或是之前版本,可以不用以下代码
@Override
@Resource(name = "sqlSessionTemplate")
public void setSqlSessionTemplate(SqlSessionTemplate sqlSessionTemplate) {
super.setSqlSessionTemplate(sqlSessionTemplate);
}
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${driverClassName}"></property>
<property name="url" value="${url}"></property>
<property name="username" value="${username}"></property>
<property name="password" value="${password}"></property>
<property name="initialSize" value="${dbcp.initialSize}"></property>
<property name="maxActive" value="${dbcp.maxActive}"></property>
<property name="maxIdle" value="${dbcp.maxIdle}"></property>
<property name="minIdle" value="${dbcp.minIdle}"></property>
<property name="maxWait" value="${dbcp.maxWait}"></property>
<property name="removeAbandoned" value="${dbcp.removeAbandoned}"></property>
<property name="defaultAutoCommit" value="${dbcp.defaultAutoCommit}"></property>
<property name="removeAbandonedTimeout" value="${dbcp.removeAbandonedTimeout}"></property>
</bean>
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="typeAliasesPackage" value="org.plat.modules.user.entity" />
<property name="configLocation" value="classpath:mybatis/mybatis-config.xml" />
<property name="mapperLocations" value="classpath*:org/plat/modules/*/mapper/**/*.xml" />
</bean>
<bean id="sqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate">
<constructor-arg index="0" ref="sqlSessionFactory" />
</bean>
typeAliasesPackage的多个选项可以用逗号分隔
<mapper namespace="mysql.org.plat.modules.user.entity.User">
传统DAO层的这种实现方式需要指定对应的SQLID。
第二种基于Mapper接口的动态代理方式:
@Repository("userMapper")
public interface UserMapper extends GenericMapper<User, Long> {
}
public interface GenericMapper <Entity extends Serializable, PK extends Serializable> {
public void insert(Entity entity) throws DataException;
public void insert(List<Entity> entities) throws DataException;
public void update(Entity entity) throws DataException;
public void update(List<Entity> entities) throws DataException;
public void delete(Entity entity) throws DataException;
public void deleteByPK(PK pk) throws DataException;
public Entity readDataByPK(PK pk) throws DataException;
public Entity readDataByCondition(Query query) throws DataException;
public List<Entity> readDataListByCondition(Query query) throws DataException;
public QueryResult<Entity> readDataPaginationByCondition(Query query) throws DataException;
public Long readCountByCondition(Query query) throws DataException;
public void flush() throws DataException;
}
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="org.plat.modules.*.mapper" />
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
</bean>
<mapper namespace="org.plat.modules.user.mapper.UserMapper">
Mappper代理的这种实现方式不需要指定对应的SQLID,接口类里面的方法名字即对应的SQLID,namespace需要指定到对应的Mapper接口。
这里需要注意的是MapperScannerConfigurer的配置,可能会遇到无法加载DataSource相关属性的异常,这时候需要配置MapperScannerConfigurer的sqlSessionFactoryBeanName属性,并且检查下有没有配置default-autowire="byName",有的话去掉。