首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 其他教程 > 开源软件 >

spring日志(九):整合其他ORM框架

2013-04-09 
spring日记(九):整合其他ORM框架 在spring中使用myBatismybatis没有特殊的事务策略,除了JDBC Connection

spring日记(九):整合其他ORM框架

>> 在spring中使用myBatis

mybatis没有特殊的事务策略,除了JDBC Connection外,也没有特殊的事务资源。它和spring JDBC事务管理方式完全一致,采用和spring JDBC相同的DataSourceTransactionManager事务管理器。

第一种方式:

先看一下myBatisConfig.xml配置文件:

1234567891011121314151617181920<?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>????<settings>????????<setting name="lazyLoadingEnabled" value="false" />????</settings>????<typeAliases>????????<typeAlias alias="Forum" type="com.baobaotao.domain.Forum" />????????<typeAlias alias="Topic" type="com.baobaotao.domain.Topic" />????????<typeAlias alias="Post" type="com.baobaotao.domain.Post" />????</typeAliases>?????????<mappers>????????<mapper resource="com/baobaotao/domain/mybatis/Forum.xml" />????????<mapper resource="com/baobaotao/domain/mybatis/Topic.xml" />????????<mapper resource="com/baobaotao/domain/mybatis/Post.xml" />????</mappers></configuration>

再看下单个DAO的sql语句映射文件:

123456789101112131415161718192021222324252627282930313233<?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.baobaotao.dao.mybatis.ForumMybatisDao">????<select id="getForum" resultType="Forum" parameterType="int" >????????SELECT ?????????forum_id? forumId,?????????forum_name? forumName,?????????forum_desc? forumDesc????????FROM t_forum ????????WHERE forum_id = #{forumId}???</select>????<select id="getForumNum" resultType="int">????????SELECT COUNT(forum_id) FROM t_forum f??</select>????<select id="findForumByName" resultType="Forum" parameterType="string">????????SELECT ?????????forum_id? forumId,?????????forum_name? forumName,?????????forum_desc? forumDesc????????FROM t_forum f????????WHERE f.forum_name LIKE #{forumName}??</select>?<insert id="addForum" parameterType="Forum">????????INSERT INTO t_forum(forum_id,forum_name,forum_desc)????????VALUES(#{forumId},#{forumName}, #{forumDesc})??</insert>??<update id="updateForum" parameterType="Forum">????????UPDATE t_forum f????????SET forum_name=#{forumName},forum_desc=#{forumDesc}????????WHERE f.forum_id = #{forumId}??</update></mapper>

接下来引入mabatis-spring的依赖jar包,然后配置spring的配置文件:

12345678910111213141516171819202122232425262728293031323334353637383940414243<?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:p="http://www.springframework.org/schema/p"????xmlns:tx="http://www.springframework.org/schema/tx"????xmlns:context="http://www.springframework.org/schema/context"????xsi:schemaLocation="http://www.springframework.org/schema/beans????//http://www.springframework.org/schema/beans/spring-beans-3.0.xsd????//http://www.springframework.org/schema/context????//http://www.springframework.org/schema/context/spring-context-3.0.xsd????//http://www.springframework.org/schema/tx????//http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">????<context:component-scan base-package="com.baobaotao.dao.mybatis" />????<context:component-scan base-package="com.baobaotao.service.mybatis" />????<context:property-placeholder location="classpath:jdbc.properties" />????<bean id="dataSource"????????class="org.apache.commons.dbcp.BasicDataSource"????????destroy-method="close"????????p:driverClassName="com.mysql.jdbc.Driver"????????p:url="jdbc:mysql://localhost:3306/sampledb"????????p:username="root"????????p:password="123456" />?????????????<bean id="sqlSessionFactory"??????class="org.mybatis.spring.SqlSessionFactoryBean"??????p:dataSource-ref="dataSource"??????p:configLocation="classpath:myBatisConfig.xml"??????p:mapperLocations="classpath:com/baobaotao/domain/mybatis/*.xml"/>????????<bean class="org.mybatis.spring.SqlSessionTemplate">??????<constructor-arg ref="sqlSessionFactory"/>???</bean> ???????????<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"??????????p:sqlSessionFactory-ref="sqlSessionFactory"??????????p:basePackage="com.baobaotao.dao.mybatis"/>???????????<bean id="transactionManager"?????????class="org.springframework.jdbc.datasource.DataSourceTransactionManager"?????????p:dataSource-ref="dataSource"/>???????????????<tx:annotation-driven transaction-manager="transactionManager"/>???? </beans>

使用SqlSessionTemplate模板类编写mybatis的DAO:

第一步是在spring中配置好SqlSessionTemplate 这个Bean:

123<bean class="org.mybatis.spring.SqlSessionTemplate">???<constructor-arg ref="sqlSessionFactory"/></bean>

接下来编写DAO:

1234567891011121314151617181920package com.baobaotao.dao.mybatis;?import org.mybatis.spring.SqlSessionTemplate;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Repository;?import com.baobaotao.domain.Forum;?@Repositorypublic class ForumMybatisTemplateDao{???????@Autowired???private SqlSessionTemplate sessionTemplate;???????public Forum getForum(int forumId){???????return (Forum)sessionTemplate.selectOne(???????????????"com.baobaotao.dao.mybatis.ForumMybatisDao.getForum",???????????????forumId);? ???}}

第二种方式:

实际上,在上面使用SqlSessionTemplate直接去调用SQL映射项的时候必须要使用com.baobaotao.dao.mybatis.ForumMybatisDao.getFrum这个字符串去定位statement。这个字符串是很容易出错的,而且编译器不会报错。

下面使用映射接口,非常强大,非常方便:

mybatis特别提供了一种可将SQL映射文件中的映射项通过名称匹配接口进行调用的方法:接口的名称和映射命名空间相同,接口方法和映射的ID相同。

下面我们为Forum.xml定义一个调用接口:

12345678910111213package com.baobaotao.dao.mybatis;?import java.util.List;?import com.baobaotao.domain.Forum;?public interface ForumMybatisDao{????void addForum(Forum forum); ????void updateForum(Forum forum) ;????Forum getForum(int forumId) ;????long getForumNum() ;????List<Forum> findForumByName(String forumName);}

类名为:com.baobaotao.dao.mybatis.ForumMybatisDao,Forum.xml中的每个映射项对应一个接口方法,接口方法的签名和映射项的声明匹配。

定义好了这个DAO接口后,下面通过SqlSessionTemplate获取接口实例:

12345public Forum getForum2(int forumId){????ForumMybatisDao forumMybatisDao =????????sessionTemplate.getMapper(ForumMybatisDao.class);????return forumMybatisDao.getForum(forumId);}

这种方法也有缺点,就是必须要比之前直接用字符串多写几个接口,每个Sql Mapper的xml文件都要写个接口。比较安全,不过通过getMapper方法(Class<T> type)这个还不是最优的方法。对于spring应用来讲,我们更希望在Service类中通过@Autowired的方法直接注入接口实例,而非每次都通过getMapper(Class<T> type)来获取DAO的实例。

第三种方式:

mybatis-spring提供了一个神奇的转换器MapperScannerConfigurer,它可以将映射接口直接装换为spring容器中的bean,这样你就可以在service类中直接注入映射接口的bean了。

假设我们已经为三个SQL映射文件分别定义了对应的接口类,使用如下配置可以将接口装换为Bean:

123<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"??????p:sqlSessionFactoryBeanName="sqlSessionFactory"??????p:basePackage="com.baobaotao.dao.mybatis"/>

然后我们就可以在service里面直接注入DAO了,尼玛整个DAO层就几个SQL Mapper配置文件夹外加几个接口类了。

1234567891011121314151617181920212223242526272829303132333435import java.util.List;?import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;import org.springframework.transaction.annotation.Transactional;?import com.baobaotao.dao.mybatis.ForumMybatisDao;import com.baobaotao.dao.mybatis.PostMybatisDao;import com.baobaotao.dao.mybatis.TopicMybatisDao;import com.baobaotao.domain.Forum;import com.baobaotao.domain.Post;import com.baobaotao.domain.Topic;?@Transactional@Servicepublic class BbtForumSerive{?????????@Autowired????private ForumMybatisDao forumDao;?????????@Autowired????private TopicMybatisDao topicDao;?????????@Autowired????private PostMybatisDao postDao;?????????public void addForum(Forum forum) {????????forumDao.addForum(forum);????}????public void addTopic(Topic topic) {????????topicDao.addTopic(topic);????}????????......?}

注意上面的@Transactional注解,可以在spring配置文件中声明式事务,直接扫描注解,非常强大,这个之前的spring事务章节已经讲过了,不多说鸟 –

总结:以上三个使用方式,一个比一个方便安全,所以第三种spring方式的最优,优先使用第三种方式。

>> 谈谈DAO层的设计:

对于使用Hibernate的应用来讲,可以定义一个BaseDao的泛型类,在其中实现泛型参数化查找更新操作等,可以极大的提高效率:

1234567891011121314151617181920212223242526272829303132333435363738package com.baobaotao.dao;?import java.io.Serializable;import java.lang.reflect.ParameterizedType;import java.lang.reflect.Type;?import org.springframework.beans.factory.annotation.Autowired;import org.springframework.orm.hibernate3.HibernateTemplate;?public class BaseDao<T> { ????????@Autowired?????private HibernateTemplate hibernateTemplate;???private Class entityClass;???????public BaseDao(){????????Type genType = getClass().getGenericSuperclass();????????Type[] params = ((ParameterizedType) genType).getActualTypeArguments();????????entityClass = (Class) params[0];????}????????public T get(Serializable id){????????return (T)hibernateTemplate.get(entityClass, id);????}?????????public void save(T entity){????????hibernateTemplate.save(entity);????}?????????public void update(T entity){????????hibernateTemplate.update(entity);????}?????public HibernateTemplate getHibernateTemplate() {????????return hibernateTemplate;????}?????}

最后,关于参数传递的方法:最佳实践是使用Map parms的形式:

List<Order> findOrder(String sql, Map params)

>> 分页查询接口设计

分页技术大致可以分成三种:

* 客户端分页:直接将全部多页结果一次性返回客户端,客户端通过展览细件前台js实现分页

* 数据库分页:每次查询数据只有一页数据

* 服务器端分页:从数据库返回全部数据,在服务器端缓冲起来,但只返回一页给客户端

第三种服务器分页既能够提高系统交互性,又能有效减小数据库访问次数,因此最优,但是又要涉及到数据缓冲、同步等问题,因此复杂性比较高。但俗话说的好,不入虎穴不得虎子(⊙o⊙),最终的王道还是钻研技术,才能做出高可靠高可用高性能的应用了来。

热点排行