精华帖 (0) :: 良好帖 (0) :: 新手帖 (1) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2006-08-18
以下是我BaseDaoImpl的代码: package mypack.dao; import org.hibernate.SessionFactory; import org.springframework.orm.hibernate3.HibernateCallback; import org.springframework.orm.hibernate3.HibernateTemplate; import org.springframework.orm.ibatis.SqlMapClientTemplate; import com.ibatis.sqlmap.client.SqlMapClient; public abstract class BaseDaoImpl implements BaseDAO { //iBatis的Template private SqlMapClientTemplate sqlMapClientTemplate ; //Hibernate的Template private HibernateTemplate hibernateTemplate ; //设置Hibernate public final void setSessionFactory(SessionFactory sessionFactory); { if(this.hibernateTemplate == null);{ this.hibernateTemplate = new HibernateTemplate(sessionFactory);; }else{ this.hibernateTemplate.setSessionFactory(sessionFactory);; } } //设置ibatis public final void setSqlMapClient(SqlMapClient sqlMapClient); { if(this.sqlMapClientTemplate == null);{ this.sqlMapClientTemplate = new SqlMapClientTemplate();; } this.sqlMapClientTemplate.setSqlMapClient(sqlMapClient);; } //获取Hibernate的模板 protected HibernateTemplate getHibernateTemplate();{ return hibernateTemplate } //获取iBatis的模板 protected SqlMapClientTemplate getSqlMapClientTemplate(); { return sqlMapClientTemplate; } //一些Hibernate 的通用方法, //当然也可不必声明,子类通过hibernateTemplate来操作 protected void save(Object object); { hibernateTemplate.save(object);; } protected void saveOrUpdate(Object object); { hibernateTemplate.saveOrUpdate(object);; } protected void update(Object object); { hibernateTemplate.update(object);; } protected void delete(Object object);{ hibernateTemplate.delete(object);; } protected Object getObject(Class clazz, Serializable id);{ return hibernateTemplate.get(clazz, id);; } //子类通过iBatis 的sqlMapClientTemplate来操作 } 即以组合方式,将HibernateTemplate和sqlMapClientTemplate集成起来,完成类似SqlMapClientDaoSupport和HibernateDaoSupport的工作,由于Java无法多类继承,所以只得以组合方式来做。不过Spring的两个Support代码不多,自己做满好,满好--记得这是梁家辉在《棋王》上最爱说说的:) 在Spring中的主要配置是这样的: 首先配置Hibernate的SessionFactory: <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"> <!-- 引用上述定义的数据源 --> <property name="dataSource"> <ref local="dataSource"/> </property> <!-- 定义Hibernate映射文件(资源) --> <property name="mappingDirectoryLocations"> <list> <value>classpath:/mypack</value> </list> </property> <!-- 定义Hibernate配置属性 --> <property name="hibernateProperties"> <props> <prop key="hibernate.dialect">${hibernate.dialect}</prop> <prop key="hibernate.show_sql">${hibernate.show_sql}</prop> <prop key="hibernate.cglib.use_reflection_optimizer">${hibernate.cglib.use_reflection_optimizer}</prop> </props> </property> <property name="useTransactionAwareDataSource" value="true"></property> </bean> 再是iBatis的sqlMapClient <bean id="sqlMapClient" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean"> <property name="configLocation" value="sql-map-config.xml"/> <property name="dataSource" ref="dataSource"/> <property name="useTransactionAwareDataSource" value="true"></property> </bean> 两者是useTransactionAwareDataSource属性都设置为ture,看Spring的Javadoc,说这可以在多Orm框架中保持事务的一致性,即通过DataSource关联,果真如此否?我还没有确定出来。 事务管理器,用Hibernate的 <!-- 事务处理的AOP配置 --> <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> <property name="sessionFactory"> <ref local="sessionFactory"/> </property> </bean > <bean id="txProxyTemplate" abstract="true" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"> <!-- 指定事务管理器 --> <property name="transactionManager" > <ref local="transactionManager"/> </property> <!-- 指定业务策略 --> <property name="transactionAttributes"> <props> <prop key="get*">PROPAGATION_REQUIRED,readOnly</prop> <prop key="add*">PROPAGATION_REQUIRED</prop> <prop key="update*">PROPAGATION_REQUIRED</prop> <prop key="delete*">PROPAGATION_REQUIRED</prop> </props> </property> </bean> 然后做两个Dao,一个是CustomerDao,这个走Hibernate,直接看其实现: package mypack.dao; import mypack.Customer; public class CustomerDaoImpl extends BaseDaoImpl implements CustomerDao { public void update(Customer customer); { super.save(customer);; } } 再看OrderDao的实现,这个走iBatis(先分道扬镳,再殊途同归): package mypack.dao; import java.sql.SQLException; import org.springframework.orm.ibatis.SqlMapClientCallback; public class OrderDaoImpl extends BaseDaoImpl implements OrderDao { /** * update ibatis */ public void updateOrderPrice(float rate); { getSqlMapClientTemplate();.update("updateOrderPrice",null);; } } 再在一个Service中同时用这两上Dao完成一个事务: package mypack.service; import mypack.Customer; import mypack.dao.CustomerDao; import mypack.dao.OrderDao; public class CustomerServiceImpl implements CustomerService { private CustomerDao customerDao; private OrderDao orderDao; public void updateCustomerAndOrder(Customer customer, float rate); { customerDao.update(customer);; orderDao.updateOrderPrice(rate);; } public CustomerDao getCustomerDao(); { return customerDao; } public void setCustomerDao(CustomerDao customerDao); { this.customerDao = customerDao; } public OrderDao getOrderDao(); { return orderDao; } public void setOrderDao(OrderDao orderDao); { this.orderDao = orderDao; } } 插入一条Customer记录,再Update所有Order(纯粹研究,没有实际意义) 走: package test.service; import org.apache.log4j.PropertyConfigurator; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class SysInit { public static ApplicationContext factory = null; private static String[] filepath = {"applicationContext_service.xml"}; public static void init(); { PropertyConfigurator.configure("D:\\personalWork\\proGroup\\hiTestPro\\src\\log4j.properties");; if (factory == null); { try { factory = new ClassPathXmlApplicationContext(filepath);; } catch (Exception e); { e.printStackTrace();; } } try { } catch (Exception e); { e.printStackTrace();; } } public static Object getBean(String name); { if (factory == null); { init();; } return factory.getBean(name);; } public static void main(String[] args); { SysInit.init();; } } package test.service; import junit.framework.TestCase; import mypack.Customer; import mypack.service.CustomerService; public class CustomerServiceTest extends TestCase { protected void setUp(); throws Exception { super.setUp();; SysInit.init();; } protected void tearDown(); throws Exception { super.tearDown();; } public void testupdateCustomerAndOrder(); { CustomerService customerService = (CustomerService);SysInit.getBean("customerService");; Customer customer = new Customer();; customer.setId(3L);; customer.setFirstname("xiong");; customer.setLastname("hua");; customer.setSex('F');; customerService.updateCustomerAndOrder(customer, 2);; } } 我测试了一下,如果iBatis的操作有问题,Customer也是没有办法插入了,所以基本上判断,这两个框架是可以做事务的。 各位看客以为如何?引玉中.... 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2006-08-18
hibernate缓存。。。怎么办?
|
|
返回顶楼 | |
发表时间:2006-08-18
Hibernate的缓存确实是一个问题,不过可以通过合理分配两者的工作来解决,比如Hibernate负责增删改,而ibatis只负责查询。
目前我的应用就是简要列表查询的数据由iBatis负责获取,从简要列表进入后的操作由Hibernate负责。 不过,如果这样限定后,也就没有必须管事务的事了。整合的目的只是为了提高Dao的内聚性并屏蔽掉具体实现。 |
|
返回顶楼 | |
发表时间:2006-08-18
在一个工具出来的时候,要能在最大的限度上杜绝工具的使用者
去理解工具发明者的一些潜规则 你这样定义了一些使用的潜规则,但是一般的程序员不一定能理解你的思想,就会滥用,肯定有bug的时候。所以这个思路我认为不好的。 其实阿,ibaits和hibernate难道没有别的方法取长补短吗?放开思维就可以了 |
|
返回顶楼 | |
发表时间:2006-08-18
不是已经有帖子证明过这个事情是可行的嘛?除了要自己处理缓存。
另外,你为什么要自己写?extends HibernateDaoSupport,然后在你的DAO里面去创建一个SqlMapClient对象不就好了? |
|
返回顶楼 | |
发表时间:2006-08-18
downpour 写道 不是已经有帖子证明过这个事情是可行的嘛?除了要自己处理缓存。
另外,你为什么要自己写?extends HibernateDaoSupport,然后在你的DAO里面去创建一个SqlMapClient对象不就好了? 不错,象你说的这样确实可以减少代码,只是这样一来,Hibernate和iBatis就处于不同地位了,这个Dao is a hernate Support and has a iBatis Support,我不想让两者的地位不一致。 |
|
返回顶楼 | |
发表时间:2006-08-18
两者本来就不处于同一个地位,你一定要让他们在一起使用,难道还要顾及你意念上的什么is-a或者has-a的所谓划分?这不是重复发明轮子嘛?
还有就是事务类型,你不妨试试在分布式环境下做这个事情。因为我记得Spring文档提到过Mix ORM工具的前提是你访问同一个数据库。 |
|
返回顶楼 | |
发表时间:2006-08-18
downpour 写道 两者本来就不处于同一个地位,你一定要让他们在一起使用,难道还要顾及你意念上的什么is-a或者has-a的所谓划分?这不是重复发明轮子嘛?
还有就是事务类型,你不妨试试在分布式环境下做这个事情。因为我记得Spring文档提到过Mix ORM工具的前提是你访问同一个数据库。 我也有点觉得将两个ORM放到一个Dao中有点别扭?另一方案是将Hibernate的 走Hibernate的Dao,iBatis的 走iBatis的Dao,各自为政,但在系统级上做集成,两者不位于同一个事务中。这种方案如何? 另:Spring走ORM,不一定是访问同一个数据库,只要TransactionManager配置成Jta的TransactionManager就可以了,下面是具体的配置。 <bean id="dataSource11" class="org.springframework.jndi.JndiObjectFactoryBean" singleton="true" lazy-init="default" autowire="default" dependency-check="default"> <property name="jndiName"> <value>jdbc/test11</value> </property> </bean> <bean id="dataSource249" class="org.springframework.jndi.JndiObjectFactoryBean" singleton="true" lazy-init="default" autowire="default" dependency-check="default"> <property name="jndiName"> <value>jdbc/test249</value> </property> </bean> ... <bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager" singleton="true" lazy-init="default" autowire="default" dependency-check="default"> </bean> |
|
返回顶楼 | |
发表时间:2006-08-18
为什么你们要用ibaits呢?难道ibaits的优势就不能用hibernate取代吗?
就拼个sql嘛!! |
|
返回顶楼 | |
发表时间:2006-08-18
welllove53 写道 为什么你们要用ibaits呢?难道ibaits的优势就不能用hibernate取代吗?
就拼个sql嘛!! iBatis主要是可以将Sql和代码解耦,使Java代码更纯一些,而Hibernate有在查询数据时有一个不好的地方是,结果集中的记录要对应Domain Class,这就限制了结果集字段的灵活性,数据库中的结果集构造是很灵活的,而不是仅对应Domain Classs。另外Hibernate还要为每条结果集构造对象,数据缓存等工作,如果仅是查询,这种工作是没有必要而费时的。 总之,我觉得Hibernate不太适合于构造简要列表时的查询,它的强项在于对一个Domain Class的增,删,改,查,而非业务数据查询。 |
|
返回顶楼 | |