系统总是离不开数据的持久化,说起来用hibernate的时间也不短了,从2.x就在用,现在已经到3.1了,不过为了符合标准,只是把 hibernate作为持久化的提供者,以前使用的是hibernate的EJB实现还有spring的Annotation事务,配置一般都是:
[hibernate.cfg.xml]--hibernate的配置文件,配置数据库连接,用户,密码等等
<hibernate-configuration><session-factory><mapping class="com.jl.domain.Customer">
[spring-dao.xml] spring的配置文件,配置了事务处理,dao及service
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> <property name="sessionFactory"><bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"><bean class="org.springframework.transaction.interceptor.TransactionAttributeSourceAdvisor"><bean id="transactionInterceptor" class="org.springframework.transaction.interceptor.TransactionInterceptor"> <property name="transactionManager"><bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"><bean id="ActivemqMsgDAO" class="com.jl.example.dao.ActivemqMsgDAO"><bean id="activeMsgService" class="com.jl.example.service.ActiveMsgService">
本来这样已经万事大吉,一般的使用也都是这样在用的,不过,我们这里情况有点特殊,
我们的系统比较大,会分成很多的子系统,每个子系统都由不同的人负责,每个子系统
都会使用一个公共数据源也有可能使用不同的数据源,而且由于配置管理的改进,每个
子系统的负责人员之间最好互不影响,最好每个子系统的人员都使用各自的配置文件,
公用的配置文件放到统一的位置,只需要在启动的时候把所有文件加载……,不过问题出
现了:
1、貌似<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator">
在所有文件中只允许有一个,这个好办,放到公用的文件里面去
2、spring由于每个子系统都会使用公用的连接池,但会映射不同的表,貌似spring的2个TransactionManager
检测到使用统一的数据源的话是不行的,会出错,这就要求把TransactionManager也放到公用配置文件里面去,
可是,如果这样的话,势必导致所有的人都可以修改公用配置文件,和配置管理的原则不符……,而且,这样子
的话每个子系统的hibernate.cfg.xml配置文件还是要各子系统自己维护,会产生多个,而一个
org.springframework.orm.hibernate3.LocalSessionFactoryBean,又貌似只支持一个hibernate配置文件
(spring 1.2.x)
还有虽然号称是使用EJB3的规范,但是还是使用的hibernate让自己心里有点别扭
这么多的貌似和自己的别扭,搞得挺烦的,不过听说最近出了JPA的规范,spring也支持,虽然还是spring2.0的m2,
拿来先用再说,呵呵 </bean></bean></bean></bean></property> </bean></bean></bean></property> </bean></mapping></session-factory></hibernate-configuration>
[hibernate.cfg.xml]--hibernate的配置文件,配置数据库连接,用户,密码等等
<hibernate-configuration><session-factory><mapping class="com.jl.domain.Customer">
xml 代码
- <?xml version="1.0" encoding="UTF-8"?>
- <!DOCTYPE hibernate-configuration PUBLIC
- "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
- "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
- <hibernate-configuration>
- <session-factory>
- <property name="hibernate.hbm2ddl.auto">create-drop</property>
- <!--这里的create-drop会每次在系统启动的时候根据映射把数据表重新删除再建立一遍,在一般使用的时候可以设置为auto -->
- <property name="hibernate.dialect">org.hibernate.dialect.PostgreSQLDialect</property>
- <property name="hibernate.cglib.use_reflection_optimizer">true</property>
- <property name="default-lazy">false</property>
- <property name="show_sql">true</property>
- <!-- 用于hibernate持久化的对象" -->
- <mapping class="com.jl.domain.Customer"/>
- <mapping class="com.jl.domain.Order"/>
- <mapping class="com.jl.domain.LineItem"/>
- <!-- 用于hibernate已经定义的事件" -->
- <!--<listener type="pre-update" class="org.hibernate.validator.event.ValidatePreUpdateEventListener"/>
- <listener type="pre-insert" class="org.hibernate.validator.event.ValidatePreInsertEventListener"/> -->
- </session-factory>
- </hibernate-configuration>
[spring-dao.xml] spring的配置文件,配置了事务处理,dao及service
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> <property name="sessionFactory"><bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"><bean class="org.springframework.transaction.interceptor.TransactionAttributeSourceAdvisor"><bean id="transactionInterceptor" class="org.springframework.transaction.interceptor.TransactionInterceptor"> <property name="transactionManager"><bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"><bean id="ActivemqMsgDAO" class="com.jl.example.dao.ActivemqMsgDAO"><bean id="activeMsgService" class="com.jl.example.service.ActiveMsgService">
xml 代码
- <!--如果自己定义连接池,datasource可以这样配置-->
- <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
- <property name="driverClassName">
- <value>org.postgresql.Driver</value>
- </property>
- <property name="url">
- <value>jdbc:postgresql:activemq</value>
- </property>
- <property name="username">
- <value>root</value>
- </property>
- <property name="password">
- <value>800314</value>
- </property>
- </bean>
- <!--datasource完毕-->
- <!--用已经配置好的连接池的话,可以这样-->
- <bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
- <property name="jndiName"><value>java:comp/env/jdbc/opendb</value></property><!--这里是数据源名称-->
- </bean>
- <!--datasource完毕-->
- <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
- <property name="sessionFactory"><ref bean="sessionFactory"/></property>
- <property name="dataSource"><ref bean="dataSource"/></property>
- </bean>
- <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"/>
- <bean class="org.springframework.transaction.interceptor.TransactionAttributeSourceAdvisor">
- <property name="transactionInterceptor"><ref bean="transactionInterceptor"/></property>
- </bean>
- <bean id="transactionInterceptor" class="org.springframework.transaction.interceptor.TransactionInterceptor">
- <property name="transactionManager"><ref local="transactionManager"/></property>
- <property name="transactionAttributeSource">
- <bean class="org.springframework.transaction.annotation.AnnotationTransactionAttributeSource"/>
- </property>
- </bean>
- <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
- <property name="dataSource"><ref local="dataSource"/></property>
- <property name="configurationClass"><value>org.hibernate.cfg.AnnotationConfiguration</value></property>
- <property name="configLocation"><value>/WEB-INF/hibernate.cfg.xml</value></property> <!--这里是刚才hibernate配置文件的位置-->
- </bean>
- <!--下面就是把自己的DAO和service放进来就可以了-->
- <bean id="ActivemqMsgDAO" class="com.jl.example.dao.ActivemqMsgDAO">
- <!--dao需要继承自org.springframework.orm.hibernate3.support.HibernateDaoSupport,才可以访问hibernate的上下文-->
- <property name="sessionFactory">
- <ref local="sessionFactory"/>
- </property>
- </bean>
- <bean id="activeMsgService" class="com.jl.example.service.ActiveMsgService">
- <property name="activemqdao"><ref local="ActivemqMsgDAO"/></property>
- </bean>
本来这样已经万事大吉,一般的使用也都是这样在用的,不过,我们这里情况有点特殊,
我们的系统比较大,会分成很多的子系统,每个子系统都由不同的人负责,每个子系统
都会使用一个公共数据源也有可能使用不同的数据源,而且由于配置管理的改进,每个
子系统的负责人员之间最好互不影响,最好每个子系统的人员都使用各自的配置文件,
公用的配置文件放到统一的位置,只需要在启动的时候把所有文件加载……,不过问题出
现了:
1、貌似<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator">
在所有文件中只允许有一个,这个好办,放到公用的文件里面去
2、spring由于每个子系统都会使用公用的连接池,但会映射不同的表,貌似spring的2个TransactionManager
检测到使用统一的数据源的话是不行的,会出错,这就要求把TransactionManager也放到公用配置文件里面去,
可是,如果这样的话,势必导致所有的人都可以修改公用配置文件,和配置管理的原则不符……,而且,这样子
的话每个子系统的hibernate.cfg.xml配置文件还是要各子系统自己维护,会产生多个,而一个
org.springframework.orm.hibernate3.LocalSessionFactoryBean,又貌似只支持一个hibernate配置文件
(spring 1.2.x)
还有虽然号称是使用EJB3的规范,但是还是使用的hibernate让自己心里有点别扭
这么多的貌似和自己的别扭,搞得挺烦的,不过听说最近出了JPA的规范,spring也支持,虽然还是spring2.0的m2,
拿来先用再说,呵呵 </bean></bean></bean></bean></property> </bean></bean></bean></property> </bean></mapping></session-factory></hibernate-configuration>
真的不好意思,讲了这么久,还没有说JPA是什么呢,JPA是Java Persistence API的缩写
是JSR 220: Enterprise JavaBeans,Version 3.0规范的一部分,是J2EE4中Entity Bean的
继承者,是一个java开发的通用持久化规范Java Persistence API 1.0, 其实就是完全重新
定义了的Entity Bean规范。Java Persistence AP(JPA)吸取了Hiberante,JDO,TopLink等优
秀技术和框架,将这几年发展成熟起来的基于POJO模型的O/R Mapping技术标准化,成为在
J2EE和J2SE环境中通用的java持久化API。值得注意的是Java Persistence API并不是J2EE环境
专用,而是在java中的通用API。意味着我们可以在任何需要访问关系数据库的地方使用JPA,
甚至包括面应用。JPA也不要求一定在J2EE容器中才能运行,而是任何有JVM的环境都可以运用。
这就使得我们可以很容易的把JPA作为一个持久化组件自由的和各种容器/框架(EJB3容器, Spring等等)组合。
JPA最主要的是一个统一的persistence.xml配置文件,可以放到每一个jar的META-INF/目录下面,配置内容主要有
(以hibernate为例)
1、数据库连接的配置文件
2、数据库方言、连接URL、用户名、密码
3、ORM映射的列表(Class)
4、配置其它的Hibernate属性(其他的Provider属性)
5、cache
主要内容,详细内容请看hibernate的reference
spring配置
这样就好了,可以使用entitymanager,每个jar里面可以相互不用影响,而且这个也符合我们新过程改进推进的每个子系统用jar发布的原则,当然这里的还有作service层,对于子系统之间的交互,我觉得,原则上应该仅允许他们在service的层面上进行,在DAO之间不应该有相互的交叉,不过隐约觉
得还有很多东西要做,嗯,很晚了,肚子饿,明天再想,呵呵
哦,对了,Spring真是好东西,封装了这么多东西给我们用,真是期待更好的版本出来啊,
还有,在j2se环境里,也可以通过代码的方式取得JPA的api
是JSR 220: Enterprise JavaBeans,Version 3.0规范的一部分,是J2EE4中Entity Bean的
继承者,是一个java开发的通用持久化规范Java Persistence API 1.0, 其实就是完全重新
定义了的Entity Bean规范。Java Persistence AP(JPA)吸取了Hiberante,JDO,TopLink等优
秀技术和框架,将这几年发展成熟起来的基于POJO模型的O/R Mapping技术标准化,成为在
J2EE和J2SE环境中通用的java持久化API。值得注意的是Java Persistence API并不是J2EE环境
专用,而是在java中的通用API。意味着我们可以在任何需要访问关系数据库的地方使用JPA,
甚至包括面应用。JPA也不要求一定在J2EE容器中才能运行,而是任何有JVM的环境都可以运用。
这就使得我们可以很容易的把JPA作为一个持久化组件自由的和各种容器/框架(EJB3容器, Spring等等)组合。
JPA最主要的是一个统一的persistence.xml配置文件,可以放到每一个jar的META-INF/目录下面,配置内容主要有
(以hibernate为例)
1、数据库连接的配置文件
2、数据库方言、连接URL、用户名、密码
3、ORM映射的列表(Class)
4、配置其它的Hibernate属性(其他的Provider属性)
5、cache
主要内容,详细内容请看hibernate的reference
xml 代码
- xml version="1.0" encoding="UTF-8"?>
- <persistence>
- <persistence-unit name="TestEntityManager" transaction-type="RESOURCE_LOCAL">
- <provider>org.hibernate.ejb.HibernatePersistence provider>
- <class>com.jl.sub1.mapping.Product class>
- <class>com.jl.sub1.mapping.ProductItem class>
- <properties>
- <property name="hibernate.dialect" value="org.hibernate.dialect.DB2Dialect" />
- <property name="hibernate.connection.driver_class" value="com.ibm.db2.jcc.DB2Driver" />
- <property name="hibernate.connection.password" value="db2admin" />
- <property name="hibernate.connection.url" value="jdbc:db2://10.1.1.10:50000/dbjl" />
- <property name="hibernate.connection.username" value="db2admin" />
- <property name="hibernate.ejb.autodetection" value="class" />
- properties>
- persistence-unit>
- persistence>
- <property name="kodo.ConnectionDriverName" value="..."/>
- <property name="kodo.ConnectionURL" value="..."/>
- <property name="kodo.ConnectionUserName" value="..."/>
- <property name="kodo.ConnectionPassword" value="..."/>
- <property name="kodo.Log" value="DefaultLevel=INFO, Runtime=DEBUG, Tool=INFO"/>
spring配置
xml 代码
- <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">
- <property name="entityManagerName" value="TestEntityManager" />
- <property name="jpaProperties">
- <props></props>
- </property>
- </bean>
- <!-- 此处的名字要和persistence.xml中定义的name一致-->
- <!-- jpaProperties此属性必须要加,hibernate3.1.2的一个bug,否则会抛NullPointerException,springframework论坛告诉我的:)-->
- <bean class=
- "org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"/>
- <!--貌似这个部分所有spring配置文件还是仅允许一个,可以配置到公共的xml中-->
- <!--引用上面建立的entityManagerFactory-->
- <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
- <property name="entityManagerFactory“ ref="entityManagerFactory" />
- </bean>
- <bean id="transactionInterceptor"
- class="org.springframework.transaction.interceptor.TransactionInterceptor">
- <property name="transactionManager" ref="transactionManager" />
- <property name="transactionAttributeSource">
- <bean class=
- "org.springframework.transaction.annotation.AnnotationTransactionAttributeSource" />
- </property>
- </bean>
- <bean class="org.springframework.transaction.interceptor.TransactionAttributeSourceAdvisor">
- <property name="transactionInterceptor" ref="transactionInterceptor" />
- </bean>
- <!--自定义DAO-->
- <bean id="numberDao" class="dao.JpaNumberDAO">
- <property name="entityManagerFactory“ ref="entityManagerFactory" />
- </bean>
- <!--DAO需继承自org.springframework.orm.jpa.support.JpaDaoSupport-->
- <!--DAO中可以通过getJpaTemplate()的各种方法进行持久化操作-->
这样就好了,可以使用entitymanager,每个jar里面可以相互不用影响,而且这个也符合我们新过程改进推进的每个子系统用jar发布的原则,当然这里的还有作service层,对于子系统之间的交互,我觉得,原则上应该仅允许他们在service的层面上进行,在DAO之间不应该有相互的交叉,不过隐约觉
得还有很多东西要做,嗯,很晚了,肚子饿,明天再想,呵呵
哦,对了,Spring真是好东西,封装了这么多东西给我们用,真是期待更好的版本出来啊,
还有,在j2se环境里,也可以通过代码的方式取得JPA的api
java 代码
- EntityManagerFactory emf =
- Peristence.createEntityManagerFactory(“TestEntityManager”) ;
- //此处的名字要和persistence.xml中
- //定义的name一致
- EntityManager em = emf.createEntityManager();
- ...//使用
- em.close();
- ...
- emf.close();
- EntityManagerFactory emf =
- Peristence.createEntityManagerFactory(“TestEntityManager”) ;
- EntityManager em = emf.createEntityManager();
- ...//使用
- em.close();
- ...
- emf.close();