- 浏览: 15526 次
- 性别:
- 来自: 深圳
最近访客 更多访客>>
最新评论
-
wei841118z:
我一个项目有两个数据源,所以有两个缓存配置文件,但是始终只认一 ...
ehcache第三次接触 -
wei841118z:
ak121077313 写道经过不懈的努力 我还是去掉了默认的 ...
ehcache第三次接触 -
kewei89767396:
...
spring+hibernate多数据源+动态切换 事务 lazyload一应俱全 -
summertse:
你数据量小,想怎么搞就怎么搞吧,至少在数据量小的情况下,效果差 ...
善意的谎言: AdapterView、Adapter优化 -
yin_bp:
<div class="quote_title ...
spring+hibernate多数据源+动态切换 事务 lazyload一应俱全
1、使用场景:
以自己为例,现有一个后台管理系统管理着游戏数据。以前是一个后台地址对应一个后台管理一个游戏后台,现在改进为一个后台管理多个游戏数据。在登录或者其他地方切换下就可以查询数据。
2、步骤分为:多数据源配置和动态切换配置和事务+OpenSessionInViewFilter配置
先不考虑动态切换配置,一个datasource对应一个sessionFactory对应一个hibernateTemplate对应一个transactionManager对应一个OpenSessionInViewFilter
在多数据源模式下有多个sessionFactory,所以配置hibernateTemplate,transactionManager,OpenSessionInViewFilter的时候要指定sessionFactory!
<filter> <filter-name>OpenSessionInViewFilter</filter-name> <filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class> <init-param> <param-name>sessionFactoryBeanName</param-name> <param-value>sessionFactory1</param-value> </init-param> </filter> <filter-mapping> <filter-name>OpenSessionInViewFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping><filter>
<filter-name>OpenSessionInViewFilter4</filter-name> <filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class> <init-param> <param-name>sessionFactoryBeanName</param-name> <param-value>sessionFactory4</param-value> </init-param> </filter> <filter-mapping> <filter-name>OpenSessionInViewFilter4</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
<bean id="transactionManager4"
class="org.springframework.orm.hibernate3.HibernateTransactionManager" autowire="byName"> <property name="sessionFactory" ref="sessionFactory4"></property> </bean>
其中transactionManager有一个问题,就是配置aop的时候要注意2个transactionManager不重叠。
3、在dao中注入不同的sessionfactory/hibernateTemplate 操作各自所属数据源数据
HibernateTemplate hibernateTemplate; @Resource(name = "hibernateTemplate4") public void setHibernateTemplate(HibernateTemplate hibernateTemplate) { this.hibernateTemplate = hibernateTemplate; }HibernateTemplate hibernateTemplate;
@Resource(name = "hibernateTemplate1") public void setHibernateTemplate(HibernateTemplate hibernateTemplate) { this.hibernateTemplate = hibernateTemplate; }
4、动态切换数据源(用来切换服务器)
public class DynamicDataSource extends AbstractRoutingDataSource { private static final Logger log = Logger.getLogger(DynamicDataSource.class); @Override protected Object determineCurrentLookupKey() { String i= CustomerContextHolder.getCustomerType(); return i; } }<bean id="dataSource00" class="com.xxx.util.DynamicDataSource">
<property name="targetDataSources"> <map key-type="java.lang.String"> <entry key="2" value-ref="dataSource2" /> <entry key="1" value-ref="dataSource1" /> </map> </property> <property name="defaultTargetDataSource" ref="dataSource1" /> </bean>
动态切换很简单,datasource配置改为AbstractRoutingDataSource实现类指定一个defaultTargetDataSource和targetDataSources
在需要切换的地方
public class CustomerContextHolder { private static final ThreadLocal contextHolder = new ThreadLocal(); public static void setCustomerType(String customerType) { contextHolder.set(customerType); } public static String getCustomerType() { return (String) contextHolder.get(); } public static void clearCustomerType() { contextHolder.remove(); } }CustomerContextHolder.setCustomerType("2");//切换key为2的数据源
User uu = userService.get(User.class, "id = ?", 3l);
就这样查询出来的就是第二个数据源的数据了
不出意外的话,是可以看到效果的。如果出现了事务问题就要查找下是否sessionfactory和aop配置正确。如果你把一个service类在aop中配置2次会出现错误的。
多数据源:管理系统数据源+游戏数据源
动态切换:游戏数据各服务器之间切换。
评论
你可以看看开源项目bbossgroups的持久层框架,可以方便地动态指定数据库操作所对应的数据库,看看能不能满足你的需求,呵呵,以下是一个测试用例:
/* * Copyright 2008 biaoping.yin * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.frameworkset.spi.mvc; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; import org.junit.Test; import com.frameworkset.common.poolman.Record; import com.frameworkset.common.poolman.SQLExecutor; import com.frameworkset.common.poolman.handle.NullRowHandler; import com.frameworkset.common.poolman.handle.RowHandler; import com.frameworkset.util.ListInfo; public class SimpleApiTest { @Test public void insertOpera()throws SQLException { ListBean lb = new ListBean(); lb.setFieldLable("tttt"); lb.setFieldName("testttt"); lb.setFieldType("int"); lb.setIsprimaryKey(false); lb.setRequired(true); lb.setSortorder("ppp"); lb.setFieldLength(20); lb.setIsvalidated(6); //用List存放Bean,在某特定的连接池中进行crud操作 List<ListBean> beans = new ArrayList<ListBean>(); beans.add(lb); String sql = "insert into LISTBEAN(ID,FIELDNAME,FIELDLABLE,FIELDTYPE,SORTORDER,ISPRIMARYKEY,REQUIRED,FIELDLENGTH,ISVALIDATED) " + "values(#[id],#[fieldName],#[fieldLable],#[fieldType],#[sortorder]," + "#[isprimaryKey],#[required],#[fieldLength],#[isvalidated])"; SQLExecutor.insertBeans("mysql",sql,beans); SQLExecutor.insertBean("mysql", sql, lb); SQLExecutor.insertBeans("mysql", sql, beans); SQLExecutor.insertBean(sql, lb); sql ="insert into LISTBEAN(ID,FIELDNAME,FIELDLABLE,FIELDTYPE) " + "values(?,?,?,?)"; // SQLExecutor.insert(sql,122,lb.getFieldName(),lb.getFieldLable(),lb.getFieldType()); // SQLExecutor.insertWithDBName("mysql", sql,101,"insertOpreation","ttyee","int"); } @Test public void updateOpera() throws SQLException { //在某特定的连接池中直接crud对象 ListBean bean = new ListBean(); bean.setId(88); bean.setFieldLable("tttt"); bean.setFieldName("test"); bean.setFieldType("int"); bean.setIsprimaryKey(false); bean.setRequired(true); bean.setSortorder("ppp"); bean.setFieldLength(20); bean.setIsvalidated(6); List<ListBean> beans = new ArrayList<ListBean>(); String sql =""; beans.add(bean); sql ="update LISTBEAN set FIELDNAME='yyyy' where ID=#[id]"; SQLExecutor.updateBeans("mysql", sql, beans); sql ="update LISTBEAN set FIELDNAME=#[fieldName] where ID=#[id]"; SQLExecutor.updateBean(sql,bean); sql ="update LISTBEAN set FIELDNAME=#[fieldName] where ID=#[id]"; SQLExecutor.updateBean("mysql",sql,bean); sql ="update LISTBEAN set FIELDNAME=#[fieldName] where ID=#[id]"; SQLExecutor.updateBeans(sql,beans); sql = "update LISTBEAN set FIELDNAME=? where ID=?"; SQLExecutor.update(sql, "mytest",100); sql = "update LISTBEAN set FIELDNAME=? where ID=?"; SQLExecutor.updateWithDBName("mysql", sql, "zhansans",101); } @Test public void deleteOpera() throws SQLException { //在特定的连接池中对数组对象进行crud ListBean lb = new ListBean(); lb.setId(85); lb.setFieldLable("tttt"); lb.setFieldName("testttt"); lb.setFieldType("int"); lb.setIsprimaryKey(false); lb.setRequired(true); lb.setSortorder("ppp"); lb.setFieldLength(20); lb.setIsvalidated(6); ListBean lb2 = new ListBean(); lb2.setId(15); lb2.setFieldName("this is lb2"); List<ListBean> beans = new ArrayList<ListBean>(); beans.add(lb); beans.add(lb2); String sql = ""; sql = "delete from LISTBEAN where ID=?"; SQLExecutor.delete(sql,68); sql = "delete from LISTBEAN where ID=?"; SQLExecutor.deleteByKeys(sql,67); sql ="delete from LISTBEAN where ID=#[id]"; SQLExecutor.deleteBean(sql,lb); sql = "delete from LISTBEAN where ID=#[id]"; SQLExecutor.deleteBeans(sql, beans); sql ="delete from LISTBEAN where ID=#[id]"; SQLExecutor.deleteBean("mysql",sql,lb); sql ="delete from LISTBEAN where ID=#[id]"; SQLExecutor.deleteBeans("mysql",sql,beans); sql = "delete from LISTBEAN where ID=?"; SQLExecutor.deleteWithDBName("mysql", sql, 3); sql = "delete from LISTBEAN where FIELDNAME=?"; SQLExecutor.deleteByKeysWithDBName("mysql", sql,"pppp"); } @Test public void queryOprea() throws SQLException{ List<ListBean> beans = null; String sql ="select * from LISTBEAN where ID=?"; sql = "select * from LISTBEAN where id=?"; List<ListBean> lbs = (List<ListBean>) SQLExecutor.queryList(ListBean.class, sql,22); sql = "select * from LISTBEAN where fieldName=?"; beans = (List<ListBean>) SQLExecutor.queryListWithDBName(ListBean.class,"mysql",sql,"testttt"); for(int i=0;i<beans.size();i++) System.out.println(beans.get(i).getId()); sql = "select * from LISTBEAN where fieldName=?"; List<ListBean> dbBeans = (List<ListBean>) SQLExecutor.queryListWithDBName(ListBean.class, "mysql", sql, "testttt"); for(int i=0;i<dbBeans.size();i++) System.out.println(dbBeans.get(i).getFieldName()); sql = "select * from LISTBEAN where fieldName=? and id=?"; ListBean bean = SQLExecutor.queryObject(ListBean.class, sql,"object",22); System.out.println(bean.getId()); sql="select * from LISTBEAN where FIELDNAME=? or id=?"; lbs = (List<ListBean>) SQLExecutor.queryList(ListBean.class, sql, "testttt",100); sql = "select FIELDNAME from LISTBEAN where ID=?"; String lbs1 = SQLExecutor.queryField(sql,2); System.out.println(lbs1); sql="select FIELDNAME from LISTBEAN where ID=?"; String result = SQLExecutor.queryFieldWithDBName("mysql", sql, 100); System.out.println(result); sql = "select * from LISTBEAN where ID=?"; ListBean lb = (ListBean)SQLExecutor.queryObjectWithDBName(ListBean.class,"mysql",sql,20); sql="select * from LISTBEAN where ID<? and ID>?"; ListInfo lif = SQLExecutor.queryListInfo(ListBean.class, sql, 0, 10, 20,10); beans = lif.getDatas(); for(int i=0;i<beans.size();i++) System.out.println(beans.get(i).getFieldName()+"......."); bean = new ListBean(); bean.setFieldName("testttt"); bean.setFieldLable("lisi"); sql ="select * from LISTBEAN where ID=?"; // bean = (ListBean)SQLExecutor.queryObjectBean(ListBean.class, sql, bean); sql ="select * from LISTBEAN where FIELDNAME=#[fieldName]"; result = SQLExecutor.queryFieldBean(sql, bean); System.out.println(result); result = SQLExecutor.queryFieldBeanWithDBName("mysql", sql, bean); System.out.println(result); beans = (List<ListBean>) SQLExecutor.queryListBean(ListBean.class, sql, bean); for(int i=0;i<beans.size();i++) System.out.println(beans.get(i).getId()); beans = (List<ListBean>) SQLExecutor.queryListBeanWithDBName(ListBean.class, "mysql", sql, bean); for(int i=0;i<beans.size();i++) System.out.println(beans.get(i).getId()); sql = "select * from LISTBEAN where ID>?"; lif = SQLExecutor.queryListInfoWithDBName(ListBean.class, "mysql", sql, 0, 10,80); for(int i=0;i<beans.size();i++) System.out.println(beans.get(i).getFieldName()+"^^^^^"); sql = "select * from LISTBEAN where FIELDNAME=#[fieldName]"; lif = SQLExecutor.queryListInfoBean(ListBean.class, sql, 0, 4, bean); for(int i=0;i<beans.size();i++) System.out.println(beans.get(i).getId()); lif = SQLExecutor.queryListInfoBeanWithDBName(ListBean.class, "mysql", sql, 0, 5, bean); for(int i=0;i<beans.size();i++) System.out.println(beans.get(i).getId()); bean = SQLExecutor.queryObjectBeanWithDBName(ListBean.class, "mysql", sql, bean); System.out.println(bean.getId()); } @Test public void rowHandlerQuery() throws SQLException{ String sql =""; List<ListBean> beans = null; ListBean bean = new ListBean(); ListInfo lif = new ListInfo(); final List<ListBean> lbs = new ArrayList<ListBean>(); bean.setFieldName("testttt"); bean.setFieldLable("lisi"); sql ="select * from LISTBEAN where ID=?"; SQLExecutor.queryByNullRowHandler(new NullRowHandler(){ @Override public void handleRow(Record record) throws Exception { ListBean lb = new ListBean(); lb.setId(record.getInt("id")); lb.setFieldName(record.getString("fieldName")); lbs.add(lb); }}, sql, 22); System.out.println(lbs.size()+"9999999"); sql = "select * from LISTBEAN where ID>?"; beans = (List<ListBean>) SQLExecutor.queryListByRowHandler(new RowHandler(){ @Override public void handleRow(Object rowValue, Record record) throws Exception { System.out.println("queryListByRowHandler test Result**:"+record.getString("fieldName")); ListBean lb = new ListBean(); lb.setId(record.getInt("id")); lb.setFieldName(record.getString("fieldName")); lbs.add(lb); }}, ListBean.class, sql, 80); for(int i=0;i<lbs.size();i++) System.out.println(lbs.get(i).getId()+"*****"); lbs.clear(); System.out.println(lbs.size()); lif = SQLExecutor.queryListInfoByRowHandler(new RowHandler<ListBean>(){ @Override public void handleRow(ListBean rowValue, Record record) throws Exception { rowValue.setId(record.getInt("id")); rowValue.setFieldName(record.getString("fieldName")); }}, ListBean.class, sql, 0, 10, 20); System.out.println(lif.getTotalSize()+"----"); sql = "select * from LISTBEAN where FIELDNAME=#[fieldName]"; lbs.clear(); beans = (List<ListBean>) SQLExecutor.queryListBeanByRowHandler(new RowHandler<ListBean>(){ @Override public void handleRow(ListBean rowValue, Record record) throws Exception { rowValue.setId(record.getInt("id")); rowValue.setFieldName(record.getString("fieldName")); }}, ListBean.class, sql, bean); for(int i=0;i<beans.size();i++) System.out.println(beans.get(i).getId()+" ggg"); lbs.clear(); beans = (List<ListBean>) SQLExecutor.queryListBeanWithDBNameByRowHandler(new RowHandler<ListBean>(){ @Override public void handleRow(ListBean rowValue, Record record) throws Exception { // TODO Auto-generated method stub rowValue.setId(record.getInt("id")); rowValue.setFieldName(record.getString("fieldName")); }}, ListBean.class, "mysql", sql, bean); for(int i=0;i<beans.size();i++) System.out.println(beans.get(i).getId()+" ccccccccc"); lbs.clear(); lif = (ListInfo) SQLExecutor.queryListInfoBeanByRowHandler(new RowHandler<ListBean>(){ @Override public void handleRow(ListBean rowValue, Record record) throws Exception { // TODO Auto-generated method stub rowValue.setId(record.getInt("id")); rowValue.setFieldName(record.getString("fieldName")); }},ListBean.class, sql, 5, 5, bean); beans = lif.getDatas(); for(int i=0;i<beans.size();i++) System.out.println(beans.get(i).getId()+" ddddddddddddddddddddddddd"); lbs.clear(); lif = SQLExecutor.queryListInfoBeanWithDBNameByRowHandler(new RowHandler<ListBean>(){ @Override public void handleRow(ListBean rowValue, Record record) throws Exception { // TODO Auto-generated method stub rowValue.setId(record.getInt("id")); rowValue.setFieldName(record.getString("fieldName")); }},ListBean.class, "mysql",sql, 0, 5, bean); for(int i=0;i<lbs.size();i++) System.out.println(lbs.get(i).getId()+" ffff"); sql = "select * from LISTBEAN where ID=#[id]"; bean.setId(2); ListBean lb1 =SQLExecutor.queryObjectBeanByRowHandler(new RowHandler<ListBean>(){ @Override public void handleRow(ListBean rowValue, Record record) throws Exception { // TODO Auto-generated method stub rowValue.setId(record.getInt("id")); rowValue.setFieldName(record.getString("fieldName")); }}, ListBean.class, sql, bean); System.out.println(lb1.getFieldName()); sql = "select * from LISTBEAN where ID<?"; lbs.clear(); lif = SQLExecutor.queryListInfoWithDBNameByRowHandler(new RowHandler(){ @Override public void handleRow(Object rowValue, Record record) throws Exception { ListBean lb = new ListBean(); lb.setId(record.getInt("id")); lbs.add(lb); lb.setFieldName(record.getString("fieldName")); }},ListBean.class,"mysql", sql, 0, 5, 20); for(int i=0;i<lbs.size();i++) System.out.println(lbs.get(i).getId()+" kkkk"); beans = (List<ListBean>) SQLExecutor.queryListWithDBNameByRowHandler(new RowHandler<ListBean>(){ @Override public void handleRow(ListBean rowValue, Record record) throws Exception { rowValue.setId(record.getInt("id")); rowValue.setFieldName(record.getString("fieldName")); }}, ListBean.class, "mysql", sql, 20); for(int i=0;i<beans.size();i++) System.out.println(beans.get(i).getFieldName()+" wwwww"); ListBean lb3 = SQLExecutor.queryObjectByRowHandler(new RowHandler<ListBean>(){ @Override public void handleRow(ListBean rowValue, Record record) throws Exception { rowValue.setId(record.getInt("id")); rowValue.setFieldName(record.getString("fieldName")); }}, ListBean.class, sql, 20); System.out.println(lb3.getFieldName()+"lbbbbb"); ListBean lb4 = SQLExecutor.queryObjectWithDBNameByRowHandler(new RowHandler<ListBean>(){ @Override public void handleRow(ListBean rowValue, Record record) throws Exception { rowValue.setId(record.getInt("id")); rowValue.setFieldName(record.getString("fieldName")); }}, ListBean.class,"mysql", sql, 20); System.out.println(lb4.getFieldName()+"lb4444"); sql = "select * from LISTBEAN where ID=#[id]"; ListBean lb2 = SQLExecutor.queryObjectBeanWithDBNameByRowHandler(new RowHandler<ListBean>(){ @Override public void handleRow(ListBean rowValue, Record record) throws Exception { // TODO Auto-generated method stub rowValue.setId(record.getInt("id")); rowValue.setFieldName(record.getString("fieldName")); }}, ListBean.class, "mysql", sql, bean); System.out.println(lb2.getId()+"++++"); } @Test public void nullRowHandlerQuery() throws SQLException{ String sql = ""; List<ListBean> beans = null; ListBean b = new ListBean(); b.setFieldName("testttt"); b.setFieldLable("lisi"); sql = "select * from LISTBEAN where id>?"; beans = null; final List<ListBean> lbs = new ArrayList<ListBean>(); ListInfo lif = SQLExecutor.queryListInfoByNullRowHandler(new NullRowHandler(){ @Override public void handleRow(Record record) throws Exception { // TODO Auto-generated method stub ListBean lb = new ListBean(); lb.setId(record.getInt("id")); lb.setFieldName(record.getString("fieldName")); lbs.add(lb); System.out.println("queryListInfoByNullRowHandler test result:"+record.getInt("id")); }}, sql, 0, 5, 10); beans = (List<ListBean>)lif.getDatas(); // for(int i=0;i<beans.size();i++) // System.out.println(beans.get(i).getId()+"......."); for(int i=0;i<lbs.size();i++) System.out.println(lbs.get(i).getFieldName()+"####"); lbs.clear(); lif =SQLExecutor.queryListInfoWithDBNameByNullRowHandler(new NullRowHandler(){ @Override public void handleRow(Record record) throws Exception { // TODO Auto-generated method stub ListBean lb = new ListBean(); lb.setId(record.getInt("id")); lb.setFieldName(record.getString("fieldName")); lbs.add(lb); System.out.println("queryListInfoByNullRowHandler test result:"+record.getInt("id")); }},"mysql", sql, 0, 5, 10); for(int i=0;i<lbs.size();i++) System.out.println(lbs.get(i).getFieldName()+"oooooooo"); lbs.clear(); SQLExecutor.queryWithDBNameByNullRowHandler(new NullRowHandler(){ @Override public void handleRow(Record record) throws Exception { // TODO Auto-generated method stub ListBean lb = new ListBean(); lb.setId(record.getInt("id")); lb.setFieldName(record.getString("fieldName")); lbs.add(lb); }}, "mysql", sql, 80); for(int i=0;i<lbs.size();i++) System.out.println(lbs.get(i).getFieldName()+"ppppp"); sql = "select * from LISTBEAN where FIELDNAME=#[fieldName]"; lbs.clear(); SQLExecutor.queryBeanByNullRowHandler(new NullRowHandler(){ @Override public void handleRow(Record record) throws Exception { // TODO Auto-generated method stub ListBean lb = new ListBean(); lb.setId(record.getInt("id")); lb.setFieldName(record.getString("fieldName")); lbs.add(lb); }}, sql, b); for(int i=0;i<lbs.size();i++) System.out.println(lbs.get(i).getId()+"yyyyy"); lbs.clear(); SQLExecutor.queryBeanWithDBNameByNullRowHandler(new NullRowHandler(){ @Override public void handleRow(Record record) throws Exception { // TODO Auto-generated method stub ListBean lb = new ListBean(); lb.setId(record.getInt("id")); lb.setFieldName(record.getString("fieldName")); lbs.add(lb); }}, "mysql",sql, b); for(int i=0;i<lbs.size();i++) System.out.println(lbs.get(i).getId()+"rrrrrrr"); lbs.clear(); lif = SQLExecutor.queryListInfoBeanByNullRowHandler(new NullRowHandler(){ @Override public void handleRow(Record record) throws Exception { // TODO Auto-generated method stub ListBean lb = new ListBean(); lb.setId(record.getInt("id")); lb.setFieldName(record.getString("fieldName")); lbs.add(lb); }}, sql, 0, 5, b); for(int i=0;i<lbs.size();i++) System.out.println(lbs.get(i).getId()+"eeee"); SQLExecutor.queryListInfoBeanWithDBNameByNullRowHandler(new NullRowHandler(){ @Override public void handleRow(Record record) throws Exception { // TODO Auto-generated method stub ListBean lb = new ListBean(); lb.setId(record.getInt("id")); lb.setFieldName(record.getString("fieldName")); lbs.add(lb); }}, "mysql",sql, 0, 5, b); for(int i=0;i<lbs.size();i++) System.out.println(lbs.get(i).getId()+"-----"); } }
你没明白使用场景,多数据源归多数据源 动态切换归动态切换。
每个seesionfactory 榜定一个数据源,多个seesionfactory 不就是多数据源了吗?
动态的切换seesionfactory 不就是切换数据源了吗,可能我真没理解,哈哈
你没明白使用场景,多数据源归多数据源 动态切换归动态切换。
用JOTM配合JTA,配置多个数据源,多个seesionfactory
还能确保事务一致呢
jta没用过。 上面说的大概对于简单的系统没什么问题
数据唯一性 是什么问题?。不切换数据源怎么看多个数据库的数据?
还有我这个系统2个数据源的数据没有关联的。
用JOTM配合JTA,配置多个数据源,多个seesionfactory
还能确保事务一致呢
不然会存在数据唯一性 的问题
private static final ThreadLocal<String> contextHolder = new ThreadLocal<String>();
-------------------------
这个地方不要用ThreadLocal 。。。 设置一个static变量来保存key值就行了。
虽然他也是转载的,虽然找不到原博主,虽然上面描述的事务问题没有遇到
但是描述的很详细,分析步骤很清晰!
相关推荐
Struts2+Spring+Hibernate 中的Action单元测试环境搭建 在软件开发中,单元测试是一种非常重要的测试方法,可以帮助我们确保代码的可靠性和稳定性。在 Struts2+Spring+Hibernate 框架中,对 Action 的单元测试环境...
SSH,即Struts、Spring和Hibernate,是Java开发中常用的一种技术栈,主要用于构建企业级应用。这三种框架分别在MVC模式中的表现层、业务层和服务层起到关键作用。以下是对SSH面试题中涉及的一些核心知识点的详细解释...
在"spring+structs+hibernate 框架的整合demo"中,我们将探讨如何将这三个强大的工具集成到一起,实现一个完整的Web应用程序。 首先,Spring框架是整个应用的核心,它提供了IoC(Inversion of Control)和AOP...
### Struts+Spring+Hibernate面试知识点详解 #### 一、Struts2框架 **Struts2** 是基于 **Struts1** 的一个升级版本,它采用了更为简洁的MVC架构模型,增强了对Web开发的支持。Struts2的核心是 **Interceptor**...
总结,这个"spring+hibernate代码实例集"涵盖了Spring和Hibernate的集成应用,包括关系映射、事务管理和延迟加载等核心概念。通过实际的代码示例,开发者可以深入理解并掌握这些技术,提升Java后端开发的能力。
5. **多数据源支持**:允许在一个应用中连接并操作多个数据库,提高了灵活性。 结合这两个框架,开发者可以构建出高效、松散耦合的Java应用。Spring 2.5 提供了对Hibernate的集成支持,可以方便地通过Spring的事务...
在Java Web开发中,Struts、Spring和Hibernate是最常见的三大框架,它们各自承担着不同的职责。以下将分别介绍这些框架的核心概念以及在面试中可能涉及的知识点。 1. Struts作为MVC框架,负责控制层的处理。MVC模式...
### 如何实现WebWork+Spring+Hibernate框架结合 随着企业级应用需求的不断增加和技术的不断发展,集成多种技术栈成为一种趋势。WebWork+Spring+Hibernate是早期比较流行的一种技术组合,它们各自解决的问题域不同,...
### Spring与Hibernate处理大字段(CLOB/BLOB) 在企业级应用开发中,经常会遇到需要存储大量文本或二进制数据的情况,这时就需要用到数据库的大字段类型如CLOB(Character Large Object)和BLOB(Binary Large ...
Flex+Gilead+BlazeDS+Spring+Hibernate示例Demo,使用1:n和m:n两个双向关系,很好的演示了Gilead的Hibernate Lazy Killer特性,借助Gilead可以有效规避DTO模式的大量繁琐代码。效果图展示地址:...
### Struts2+Spring+Hibernate集成过程 #### 一、集成环境搭建 1. **开发环境**:在开始集成之前,首先要确保安装了正确的开发工具和技术版本,具体为: - JDK版本:JDK 7 - Web服务器:Tomcat 6 - IDE:...
基于Spring+SpringMVC+Hibernate的全注解开发,允许开发者摆脱传统的XML配置文件,转而使用注解来实现组件的配置,大大简化了开发流程,提高了开发效率。 **Spring框架** 是一个全面的后端应用管理框架,它提供了...
Spring通过Java的反射机制,在运行时动态地创建和装配对象。这样做的好处是可以降低组件之间的耦合度,提高代码的可测试性和可维护性。 此外,Spring还提供了面向切面编程(Aspect-Oriented Programming,简称AOP)...
在我们的网络书城项目中,Spring将管理各个组件的生命周期,如数据源、事务、以及WebWork和Hibernate的配置。我们将学习如何通过Spring的XML配置文件或注解来声明和注入依赖,以及如何使用Spring的事务管理功能来...
Spring和Hibernate框架结合使用可以有效地进行CLOB字段的操作。以下是实现这一功能的关键步骤和注意事项: 1. **配置SessionFactory** 在Spring配置文件中,你需要创建一个`SessionFactory` bean,同时指定一个`...
### Struts+Spring+Hibernate快速入门 #### 一、引言 在当今的企业级Web应用程序开发中,Struts、Spring 和 Hibernate 这三大框架被广泛应用于构建高效、可维护的应用程序。本文旨在介绍如何利用这三种技术搭建一个...
Spring 包括多个模块,如核心容器、数据访问/集成、Web、AOP、工具和测试等。 1. **核心容器**:包括 BeanFactory 和 ApplicationContext,是 Spring 的基础,负责创建、配置和管理应用中的对象。 2. **数据访问/...
这个压缩包“struts2.3.2+spring4.1.6+hibernate4.2”包含了这三个框架的特定版本,适用于构建一个功能完备、松耦合的Web应用程序。 Struts2是Action导向的MVC框架,它提供了处理HTTP请求、控制业务流程以及展现...
Struts2处理MVC(Model-View-Controller)架构中的控制层,Hibernate专注于对象关系映射(ORM)以简化数据库交互,而Spring则提供全面的依赖注入(DI)和面向切面编程(AOP),以及事务管理等核心服务。将这三个框架...