- 浏览: 1087458 次
- 性别:
- 来自: 成都
文章分类
最新评论
-
skyesx:
这是2PC实现,更常用的是一个柔性事务的实现,可以参考http ...
Spring分布式事务实现 -
ddbird:
这第一句就不严谨“分布式事务是指操作多个数据库之间的事务”,显 ...
Spring分布式事务实现 -
呵呵6666:
基于互联网支付系统的微服务架构分布式事务解决方案http:// ...
Spring分布式事务实现 -
小黄牛:
写得不错,交流群:472213887
Spring分布式事务实现 -
jiaoqf321456:
这明明是用的apache的压缩,给ant.jar有半毛钱关系吗 ...
使用ant.jar进行文件zip压缩
Spring3 Annotation + Hibernate3-jpa2.0 + CGLIB + 多数据源
- 博客分类:
- Spring/Hibernate/iBatis
一、定义一个测试用Entity。
二、applicationContext.xml与META-INF/persistent.xml
三、在Spring 2.0.1中引入了AbstractRoutingDataSource, 该类充当了DataSource的路由中介, 能有在运行时, 根据某种key值来动态切换到真正的DataSource上, 同时对于不支持事务隔离级别的JTA事务来说, Spring还提供了另外一个类IsolationLevelDataSourceRouter来处理。IsolationLevelDataSourceRouter: 会根据当前Spring受管事务启用的隔离级别来选定合适的DataSource数据源。
四、数据访问Dao
五、测试
六、关于Spring-AOP: JDK代理和CGLIB代理
1、如果目标对象实现了接口,默认会采用JDK的动态代理机制实现AOP
2、如果目标对象实现了接口,可以强制使用CGLIB实现AOP
3、如果目标对象没有实现接口,必须使用CGLIB生成代理,spring会自动在CGLIB和JDK动态代理之间切换
4、如何强制使用CGLIB生成代理?
(1)添加CGLIB库,SPRING_HOME/lib/cglib/*.jar
(2)在spring的配置文件中加入:<aop:aspectj-autoproxy proxy-target-class="true"/>
5、JDK代理和CGLIB代理的区别?
(1)JDK代理只能对实现了接口的类生成代理,而不能针对类
(2)CGLIB是针对类实现代理的,主要对指定的类生成一个子类,并覆盖其中的方法,因为是继承,所以不能使用final来修饰类或方法
七、关于IsolationLevelDataSourceRouter
public class IsolationLevelDataSourceRouterextends AbstractRoutingDataSourceDataSource that routes to one of various target DataSources based on the current transaction isolation level. The target DataSources need to be configured with the isolation level name as key, as defined on the TransactionDefinition interface.
This is particularly useful in combination with JTA transaction management (typically through Spring's JtaTransactionManager). Standard JTA does not support transaction-specific isolation levels. Some JTA providers support isolation levels as a vendor-specific extension (e.g. WebLogic), which is the preferred way of addressing this. As alternative (e.g. on WebSphere), the target database can be represented through multiple JNDI DataSources, each configured with a different isolation level (for the entire DataSource). The present DataSource router allows to transparently switch to the appropriate DataSource based on the current transaction's isolation level.
The configuration can for example look like this, assuming that the target DataSources are defined as individual Spring beans with names "myRepeatableReadDataSource", "mySerializableDataSource" and "myDefaultDataSource":
这是怎么回事?
@Entity public class Person implements Serializable { private static final long serialVersionUID = 1L; @Id @GeneratedValue @Column(name = "id") private Integer id; @Column(name = "last_name") private String lastName; @Column(name = "first_name") private String firstName; public String getFirstName(){return firstName;} public void setFirstName(String firstName){this.firstName = firstName;} public String getLastName(){return lastName;} public void setLastName(String lastName){this.lastName = lastName; } public Integer getId(){return id;} public void setId(Integer id){this.id = id;} }
二、applicationContext.xml与META-INF/persistent.xml
<?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:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-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/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd"> <!--指定spring容器自动扫描的包:@Repository...--> <context:component-scan base-package="com.logcd.test,com.logcd.dao,com.logcd.service"/> <!--使用CGLIB代理--> <aop:aspectj-autoproxy proxy-target-class="true"/> <bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor"/> <bean id="ds1" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/springapp"/> <property name="username" value="root"/> <property name="password" value="root"/> </bean> <bean id="ds2" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/test"/> <property name="username" value="root"/> <property name="password" value="root"/> </bean> <!--动态选择数据源--> <bean id="dataSource" class="com.logcd.util.DynamicDataSource"> <property name="targetDataSources"> <map key-type="java.lang.String"> <entry key="1" value-ref="ds1"/> <entry key="2" value-ref="ds2"/> </map> </property> <property name="defaultTargetDataSource" ref="ds1"/> </bean> <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" destroy-method="destroy"> <property name="dataSource" ref="dataSource" /> <property name="jpaVendorAdapter"> <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"> <property name="database" value="MYSQL"/> <property name="generateDdl" value="true"/> <property name="showSql" value="true"/> </bean> </property> </bean> <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"> <property name="dataSource" ref="dataSource"/> <property name="entityManagerFactory" ref="entityManagerFactory"/> </bean> <tx:annotation-driven transaction-manager="transactionManager"/> </beans>
<persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistencehttp://java.sun.com/xml/ns/persistence/persistence_1_0.xsd" version="1.0"> <!-- local or global(JTA) transaction --> <persistence-unit name="SpringJpa" transaction-type="RESOURCE_LOCAL"/> </persistence>
三、在Spring 2.0.1中引入了AbstractRoutingDataSource, 该类充当了DataSource的路由中介, 能有在运行时, 根据某种key值来动态切换到真正的DataSource上, 同时对于不支持事务隔离级别的JTA事务来说, Spring还提供了另外一个类IsolationLevelDataSourceRouter来处理。IsolationLevelDataSourceRouter: 会根据当前Spring受管事务启用的隔离级别来选定合适的DataSource数据源。
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource; public class DynamicDataSource extends AbstractRoutingDataSource { @Override protected Object determineCurrentLookupKey() { return DbContextHolder.getDbType(); } }
public class DbContextHolder { private static final ThreadLocal<Object> contextHolder = new ThreadLocal<Object>(); public static void setDbType(Object dbType) { contextHolder.set(dbType); } public static String getDbType() { return (String) contextHolder.get(); } public static void clearDbType() { contextHolder.remove(); } }
四、数据访问Dao
import java.io.Serializable; import java.util.List; import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; import javax.persistence.Query; import org.springframework.stereotype.Repository; import org.springframework.transaction.annotation.Transactional; @Repository @Transactional public class BaseDao<T>{ @PersistenceContext protected EntityManager em; public void persist(T t) { em.persist(t); } @Transactional(readOnly = false, propagation = Propagation.REQUIRED, rollbackFor = Exception.class) public T save(T t) { return em.merge(t); } public void delete(T t) { em.remove(t); } @Transactional(readOnly = true, isolation=Isolation.READ_COMMITTED) public T find(Class<T> clazz, Serializable id) { return em.getReference(clazz, id); } @SuppressWarnings("unchecked") public List<T> find(String jpql) { return em.createQuery(jpql).getResultList(); } @SuppressWarnings("unchecked") public List<T> find(String jpql, Object param) { return em.createQuery(jpql).setParameter(1, param).getResultList(); } @SuppressWarnings("unchecked") public List<T> find(String jpql, Object[] param) { Query query = em.createQuery(jpql); for (int i = 1; i <= param.length; i++) { query.setParameter(i, param[i - 1]); } return query.getResultList(); } public int findTotalCount(String jpql) { return ((Long) em.createQuery(jpql).getSingleResult()).intValue(); } }
五、测试
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import java.util.List; import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import com.logcd.dao.BaseDao; import com.logcd.entity.Person; import com.logcd.util.DbContextHolder; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration("classpath:applicationContext.xml") public class TestBaseDao extends AbstractJUnit4SpringContextTests{ @Autowired private BaseDao<Person> baseDao; @Test public void findPersonById(){ List<Person> persons = baseDao.find("from Person a where a.id = ?", new Integer(1)); assertNotNull(persons); assertEquals(persons.size(), 1); for(Person person: persons){ System.out.println(person.getLastName()+" "+person.getFirstName()); } } @Test public void savePerson(){ DbContextHolder.setDbType("2"); Person person = new Person(); person.setFirstName("Bella"); person.setLastName("Edward"); person = baseDao.save(person); System.out.println(person.getId()); DbContextHolder.clearDbType(); } @Ignore public void deletePerson(){ baseDao.delete(baseDao.find(Person.class, new Integer(7))); } }
六、关于Spring-AOP: JDK代理和CGLIB代理
1、如果目标对象实现了接口,默认会采用JDK的动态代理机制实现AOP
2、如果目标对象实现了接口,可以强制使用CGLIB实现AOP
3、如果目标对象没有实现接口,必须使用CGLIB生成代理,spring会自动在CGLIB和JDK动态代理之间切换
4、如何强制使用CGLIB生成代理?
(1)添加CGLIB库,SPRING_HOME/lib/cglib/*.jar
(2)在spring的配置文件中加入:<aop:aspectj-autoproxy proxy-target-class="true"/>
5、JDK代理和CGLIB代理的区别?
(1)JDK代理只能对实现了接口的类生成代理,而不能针对类
(2)CGLIB是针对类实现代理的,主要对指定的类生成一个子类,并覆盖其中的方法,因为是继承,所以不能使用final来修饰类或方法
七、关于IsolationLevelDataSourceRouter
public class IsolationLevelDataSourceRouterextends AbstractRoutingDataSourceDataSource that routes to one of various target DataSources based on the current transaction isolation level. The target DataSources need to be configured with the isolation level name as key, as defined on the TransactionDefinition interface.
This is particularly useful in combination with JTA transaction management (typically through Spring's JtaTransactionManager). Standard JTA does not support transaction-specific isolation levels. Some JTA providers support isolation levels as a vendor-specific extension (e.g. WebLogic), which is the preferred way of addressing this. As alternative (e.g. on WebSphere), the target database can be represented through multiple JNDI DataSources, each configured with a different isolation level (for the entire DataSource). The present DataSource router allows to transparently switch to the appropriate DataSource based on the current transaction's isolation level.
The configuration can for example look like this, assuming that the target DataSources are defined as individual Spring beans with names "myRepeatableReadDataSource", "mySerializableDataSource" and "myDefaultDataSource":
<bean id="dataSourceRouter" class="org.springframework.jdbc.datasource.lookup.IsolationLevelDataSourceRouter"> <property name="targetDataSources"> <map> <entry key="ISOLATION_REPEATABLE_READ" value-ref="myRepeatableReadDataSource"/> <entry key="ISOLATION_SERIALIZABLE" value-ref="mySerializableDataSource"/> </map> </property> <property name="defaultTargetDataSource" ref="myDefaultDataSource"/> </bean>Alternatively, the keyed values can also be data source names, to be resolved through a DataSourceLookup: by default, JNDI names for a standard JNDI lookup. This allows for a single concise definition without the need for separate DataSource bean definitions.
<bean id="dataSourceRouter" class="org.springframework.jdbc.datasource.lookup.IsolationLevelDataSourceRouter"> <property name="targetDataSources"> <map> <entry key="ISOLATION_REPEATABLE_READ" value="java:comp/env/jdbc/myrrds"/> <entry key="ISOLATION_SERIALIZABLE" value="java:comp/env/jdbc/myserds"/> </map> </property> <property name="defaultTargetDataSource" value="java:comp/env/jdbc/mydefds"/> </bean>Note: If you are using this router in combination with Spring's JtaTransactionManager, don't forget to switch the "allowCustomIsolationLevels" flag to "true". (By default, JtaTransactionManager will only accept a default isolation level because of the lack of isolation level support in standard JTA itself.)
<bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager"> <property name="allowCustomIsolationLevels" value="true"/> </bean>
评论
7 楼
yuyujulin
2011-07-28
楼主你这个好像还是JPA-1.0耶,
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistencehttp://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
version="1.0">
<!-- local or global(JTA) transaction -->
<persistence-unit name="SpringJpa" transaction-type="RESOURCE_LOCAL"/>
</persistence>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistencehttp://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
version="1.0">
<!-- local or global(JTA) transaction -->
<persistence-unit name="SpringJpa" transaction-type="RESOURCE_LOCAL"/>
</persistence>
6 楼
weir2009
2011-05-20
Caused by: org.springframework.beans.NotWritablePropertyException: Invalid property 'dataSource' of bean class [org.springframework.orm.jpa.LocalEntityManagerFactoryBean]: Bean property 'dataSource' is not writable or has an invalid setter method. Does the parameter type of the setter match the return type of the getter? at org.springframework.beans.BeanWrapperImpl.setPropertyV
这是怎么回事?
5 楼
angellin0
2011-04-30
LZ, 为什么我在用的时候发现entityManager只实例化了一次,当调用Service时是直接调用的存储,而没有去切换datasource.
4 楼
lshoo
2011-03-13
很好的例子,多谢!
3 楼
naoda
2010-11-10
刚好项目需要使用多数据源,感谢你的分享!
2 楼
naoda
2010-11-10
刚好项目上用到了多数据源,感谢你的分享!
1 楼
niukai_2000
2010-11-10
写的不错,赞一个
发表评论
-
SpringBoot开发WebService之Axis
2019-07-14 23:56 4598一、服务器端发布WebService服务 1、POM.xml文 ... -
SpringBoot开发WebService之CXF
2019-07-14 23:56 1197一、在服务器端的WebSerivce服务发布 1、POM.xm ... -
SpringBoot项目非web方式启动
2019-07-03 17:02 46611、springboot 1.x中以非web方式启动 @S ... -
SpringBoot使用Druid数据库密码加密
2019-03-06 23:28 14191、生成公钥、私钥和密码加密串 java -cp drui ... -
Spring Annotation
2010-12-02 17:14 0Spring2.x引入了组件自动扫描机制,可以在类路径底 ... -
Spring分布式事务实现
2010-11-10 14:28 83116分布式事务是指操作多个数据库之间的事务,spring的 ... -
使用iBatis2.0
2010-05-26 10:20 0一、NULL问题 ibatis操作oracle数据库时, ... -
使用AspectJ LTW(Load Time Weaving)
2010-01-04 14:25 10707在Java 语言中,从 ... -
Spring2.0 AOP AspectJ 注释实现
2010-01-04 14:24 5533一、AOP基本概念 切面(Aspect): 一个关注点的模块 ... -
Spring + JPA + Hibernate配置
2010-01-04 14:24 34688<1>persistence.xml放到类路径下的 ... -
配置spring数据源
2009-11-06 16:47 1207配置一个数据源 Spring在第三方依赖包中包含了两 ... -
hibernate的dialect
2009-07-23 10:04 5399一、hibernate的dialect RDBM ... -
spring ibatis入门
2009-04-20 14:16 3835一、applicationContext.xml <?x ... -
Hibernate缓存配置/批量处理
2009-03-25 21:50 10897Hibernate除了自动对Se ... -
Hibernate的一级与二级缓存
2009-03-25 21:24 1669缓存是介于应用程序和物理数据源之间,其作用是为了降低应用 ... -
spring jdbcTemplate使用
2008-07-15 17:17 78157一、使用示例 (1)springJdbcContext.xml ... -
Spring2.X以AspectJ 式AOP 配置事务
2008-07-10 13:23 2027(1)配置: Spring的事务管理是通过AOP代理实 ... -
spring 事务管理
2008-07-08 16:35 11915声明式的事务管理(Declarative transactio ... -
Hibernate中one-to-many/many-to-one和many-to-many
2008-06-28 17:03 3927<1>one-to-many/many-to-on ... -
Hibernate中的对象one-to-one关系
2008-06-26 22:55 2438(1) 通过主健参考,限制2个数据表中的主健使用相同的值 c ...
相关推荐
GSH:spring3.1.0M2+Hibernate3.5+GWT2.4+JPA+Annotation+Spring4gwt0.0.1亲手整合,也可以上新浪博客去看 http://blog.sina.com.cn/s/blog_687dfecb0100yrmf.html
hibernate-annotation3.4.0 + hibernate-distribution3.3.2 + slf4j-1.5.8.rar,完整jar包
使用jsf1.2+spring3.0+hibernate3.3实现集成,利用annotation实现自动对象管理注入,用户表的登录增删改查操作,包括验证码ajax集成,消息机制,国际化处理,自定义转换器,自定义验证器等 qq:38732796 欢迎讨论
SpringMVC+Hibernate+annotation+Easyui权限管理系统,Session过期控制(包括Ajax请求的过期控制),访问权限控制(权限控制到按钮),hibernate数据库用户名与密码加密,其它的不说了,绝对物有所值
原创资源,码超所值,价廉物美。...所用的技术比较多,如Spring的IOC,AOP,Transactiion,Annotation,Spring_JUnit_Test及Log4j;Hibernate的JPA Annotation;BoneCP的数据库连接测等。是很好的学习资料!
hibernate-distribution 3.3.2+annotation3.4.0+slf4j-1.5.8.rar )
Spring3Annotation+Struts2Annotation+Hibernate3Annotation 全注解集成开发,操作Emp表
赠送源代码:jakarta.annotation-api-1.3.5-sources.jar; 赠送Maven依赖信息文件:jakarta.annotation-api-1.3.5.pom; 包含翻译后的API文档:jakarta.annotation-api-1.3.5-javadoc-API文档-中文(简体)版.zip; ...
弹簧动力jpa Spring Dynamic JPA将使使用JpaRepository轻松实现动态查询变得容易。如何使用? 添加依赖implementation ' ... Spring启动版spring-dynamic-jpa版本2.0.x.发布2.0.3 2.1.x.发布2.1.3
spring+hibernate3.2+struts2.0 注解,超级简化,省略hbm.xml、bean注入xml配置等,一切annotation
jquery easyUI+struts2+spring+hibernate基于annotation实现的CRM
Struts2+Spring2+Hibernate3+Annotation所需JAR包
赠送源代码:javax.annotation-api-1.2-sources.jar; 赠送Maven依赖信息文件:javax.annotation-api-1.2.pom; 包含翻译后的API文档:javax.annotation-api-1.2-javadoc-API文档-中文(简体)版.zip; Maven坐标:...
整合S2SH+Freemarker+oscache,后台用Spring管理各个bean,Hibernate做数据库持久化,viewer用Freemarker。整合中对Struts2,Hibernate,Spring都采用Annotation进行注解类。
赠送源代码:javax.annotation-api-1.3.2-sources.jar; 赠送Maven依赖信息文件:javax.annotation-api-1.3.2.pom; 包含翻译后的API文档:javax.annotation-api-1.3.2-javadoc-API文档-中文(简体)版.zip; Maven...
基于 spring2.5 hibernate3.3 jpa 的annotation注解来减少配置文件的大小 通过jersey实现restful形式请求
annotation-mulidatasource](https://github.com/ityouknow/spring-boot-examples/tree/master/spring-boot-mybatis/spring-boot-mybatis-annotation-mulidatasource):Spring Boot + Mybatis(注解版)多数据源最简...
JSF+Spring+Hibernate(Annotation)的login小实例,建议入门的朋友看看,老鸟就免了,呵呵。环境:SQLSever2000+jdk5.0+spring2.0+hibernate3.2+jsf
hibernate helloword annotation version