<?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:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd"> <!-- 数据库连接池 --> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close" scope="singleton"> <property name="driverClassName"> <value>com.mysql.jdbc.Driver</value> </property> <property name="url"> <value>jdbc:mysql://127.0.0.1:3306/test</value> </property> <property name="username"> <value>root</value> </property> <property name="password"> <value>123456</value> </property> <!-- 以下为可选参数 <property name="initialSize"> <value>10</value> </property>--> <property name="minIdle"> <value>10</value> </property> <property name="maxActive"> <value>15</value> </property> <property name="maxIdle"> <value>15</value> </property> <property name="validationQuery"> <value>select count(*) from dual</value> </property> <property name="testOnBorrow"> <value>true</value> </property> <property name="testOnReturn"> <value>true</value> </property> <property name="testWhileIdle"> <value>true</value> </property> <!--大于0 ,进行连接空闲时间判断,或为0,对空闲的连接不进行验证 --> <property name="minEvictableIdleTimeMillis"> <value>60000</value> </property> <!--失效检查线程运行时间间隔,如果小于等于0,不会启动检查线程 --> <property name="timeBetweenEvictionRunsMillis"> <value>300000</value> </property> </bean> <context:annotation-config /> <!-- 配置实体管理对象 p:persistenceUnitManager-ref="persistenceUnitManager"--> <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" > <property name="persistenceXmlLocation" value="classpath:/META-INF/persistence.xml" /> <property name="dataSource" ref="dataSource" /> <!-- 选配属性 --> <property name="jpaVendorAdapter"> <bean class="org.springframework.orm.jpa.vendor.OpenJpaVendorAdapter"> <property name="showSql" value="false"/> <property name="generateDdl" value="false"/> <property name="databasePlatform" value="org.apache.openjpa.jdbc.sql.MySQLDictionary"/> </bean> </property> </bean> <!--可屏蔽 <bean id="persistenceUnitManager" class="org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManager" p:default-data-source-ref="dataSource" p:persistence-xml-locations="classpath*:META-INF/persistence.xml"> <property name="loadTimeWeaver"> <bean class="org.springframework.instrument.classloading.ReflectiveLoadTimeWeaver"/> </property> </bean> --> <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager" lazy-init="true"> <property name="entityManagerFactory" ref="entityManagerFactory"/> </bean> <tx:advice id="transactionAdvice" transaction-manager="transactionManager"> <tx:attributes> <tx:method name="*" rollback-for="Exception" /> <!--<tx:method name="add*" propagation="REQUIRED" rollback-for="Exception" /> <tx:method name="save*" propagation="REQUIRED" /> <tx:method name="someOtherBusinessMethod" propagation="REQUIRES_NEW" /> <tx:method name="*" propagation="SUPPORTS" read-only="true" />--> </tx:attributes> </tx:advice> <aop:config> <aop:pointcut id="businessService" expression="execution(* service.*.*(..))" /> <aop:advisor advice-ref="transactionAdvice" pointcut-ref="businessService" /> </aop:config> <bean id="orderDao" class="dao.OrderDao"> <property name="entityManagerFactory" ref="entityManagerFactory" /> </bean> <bean id="orderService" class="service.OrderService"> <property name="orderDao" ref="orderDao"/> </bean> <context:load-time-weaver /> <context:annotation-config /> </beans>
persistence.xml
<?xml version="1.0" encoding="UTF-8"?> <persistence version="1.0" 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/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"> <persistence-unit name="default" transaction-type="RESOURCE_LOCAL"> <properties> <property name="openjpa.InverseManager" value="false"/> <property name="openjpa.Log" value="log4j"/> <property name="openjpa.DataCache" value="false"/> <property name="openjpa.QueryCache" value="false"/> <property name="openjpa.Compatibility" value="QuotedNumbersInQueries=true"/> </properties> </persistence-unit> <!--<persistence-unit name="MyJPA" transaction-type="RESOURCE_LOCAL"> <!– 描述信息.(可选) –> <description>MySQL5.1数据库的映射文件</description> <!– 要注意的是我们使用的JPA事务采用RESOURCE_LOCAL(本地资源), 不能够使用JTA(全局资源,容器管理事务)。 而且使用本地资源的话, 只能够在web容器部署,而不能够部署到EJB容器里面(Glassfish等), 在GlassfishV2里面部署就提示只可以使用JTA事务 –> <!– 定义jpa的Provider –> <provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider> <class>entity.Animal</class> <!– J2EE中,不建议在此配置,建议在Spring中的entityManagerFactory处配制 <properties> <property name="openjpa.Log" value="none" /> <property name="openjpa.Log" value="SQL=TRACE" /> <property name="openjpa.ConnectionFactoryProperties" value="PrettyPrint=true,PrettyPrintLineLength=72" /> </properties> –> <exclude-unlisted-classes/> </persistence-unit>--> </persistence>
Order.java
/** * one端 * * 碰到many为末端的加载就是延迟加载,若one为末端则为立即加载,除了one-to-one。 * * @author jiqinlin * */ @SuppressWarnings({"ALL"}) @Entity(name="tb_order") public class Order implements java.io.Serializable { @Id @Column(name="id") @GeneratedValue(strategy = GenerationType.IDENTITY) private int id; @Column(name="name") private String name; /* one端 @OneToMany(cascade={CascadeType.PERSIST,CascadeType.MERGE,CascadeType.REMOVE}) mappedBy="order": 指明Order类为双向关系维护端,负责外键的更新 */ @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "order") private List<OrderItem> orderItemList;
OrderItem.java
/** * many端 * * 在one-to-many双向关联中,多的一方为关系维护端,关系维护端负责外键记录的更新 * 关系被维护端是没有权力更新外键记录的 * * * */ @SuppressWarnings({"ALL"}) @Entity(name="tb_orderitem") public class OrderItem implements java.io.Serializable { @Id @Column(name="id") @GeneratedValue(strategy = GenerationType.IDENTITY) private int id; //@Column(name="order_id") // private int orderId; @Column(name="name") private String name; // optional=true:可选,表示此对象可以没有,可以为null;false表示必须存在 @ManyToOne(cascade = { CascadeType.REFRESH,CascadeType.PERSIST , CascadeType.MERGE }, optional = true) @JoinColumn(name = "order_id") private Order order;
Dao.java
public class OrderDao extends JpaDaoSupport { public void addOrder(final Object order){ getJpaTemplate().persist(order); /* getJpaTemplate().execute(new JpaCallback() { public Object doInJpa(EntityManager entityManager) throws PersistenceException { entityManager.getTransaction().begin(); entityManager.persist(order); entityManager.getTransaction().commit(); entityManager.close(); return null; } });*/ } public void updateOrder(final Object order){ getJpaTemplate().merge(order); } }
service
public void addOrder(Object order) throws Exception { orderDao.addOrder(order); //throw new Exception(); } public void updateOrder(Object order) throws Exception { orderDao.updateOrder(order); //throw new Exception(); } public static void main(String[]args){ List orderItems = new ArrayList(); Order order = new Order(); order.setName("name333"); // order.setId(1); OrderItem orderItem = new OrderItem(); orderItem.setOrder(order); //order.getId(); orderItem.setName("nameNew"); ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("classpath*:applicationContext-common.xml"); OrderService orderService = (OrderService) ctx.getBean("orderService"); try { //orderService.addOrder(order); orderService.updateOrder(orderItem); } catch (Exception e) { e.printStackTrace(); }