`
Clayz
  • 浏览: 293638 次
  • 性别: Icon_minigender_1
  • 来自: 东京
社区版块
存档分类
最新评论

Spring 2.0 中配置 JPA

阅读更多

翻译:SpringSide团队 转载请注明出处。

本文提供了一个简单的 Spring 框架 standalone 环境下,如何 step-by-step 去开发 JPA 的向导。 JPA 的规范最开始时是由 EJB 3.0 的持久性机制产生的, 它被公认为是把简单的 POJOs 持久化的机制。你只需少量 JAR 在 classpath 中,配置一点 Spring 的 bean, 就能在你喜爱的IDE中去开始感受 JPA 的强大威力了。我们在这里使用的是 Glassfish JPA - 一个基于 Oracle’s TopLink ORM framework 的开源项目

初始化设置
  1. 保证你使用的是Java 5 (EJB 3.0 中 JPA 的先决条件).
  2. 从 https://glassfish.dev.java.net/downloads/persistence/JavaPersistence.html 下载 glassfish JPA jar (注意: 我使用的是 “V2_build_02″ jar, 但该版本后的版本也应回往前兼容的.)
  3. 从“installer” jar 中解压,并运行: java -jar glassfish-persistence-installer-v2-b02.jar
  4. 把 toplink-essentials.jar 加入你的 classpath
  5. 把数据库的驱动 JAR 也加入( 我用的是 version 1.8.0.1 的 hsqldb.jar 作为例子,但实际上你只需很少的改变就能适配到另外的数据库 )
  6. 加入2.0 M5 以上版本的Spring JAR( http://sourceforge.net/project/showfiles.php?group_id=73357) - spring.jar - spring-jpa.jar - spring-mock.jar
  7. 最后,把这些 JAR 也加入到你的classpath 中: - commons-logging.jar - log4j.jar - junit.jar

领域模型 (domain model)

这个例子中我们只是有目的地列举了3个简单的domain model. 要注意的是这例子中我们使用了annotation。 使用 JPA 时,一般会选择用annotation 或 XML 文件,又或者两者一起配合用,去指定ORM(object-relational mapping)元数据。在这里,我们只是选择了单独用annotation, 因为只需要在domain model 的代码中加入简短的描述就能马上办到。 首先, 看看餐厅 Restaurant class:

package blog.jpa.domain;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.OneToOne;

@Entity
public class Restaurant {

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;

private String name;

@OneToOne(cascade = CascadeType.ALL)
private Address address;

@ManyToMany
@JoinTable(inverseJoinColumns = @JoinColumn(name = "ENTREE_ID"))
private Set<Entree> entrees;

public long getId() {
  return id;
}

public void setId(long id) {
  this.id = id;
}

public String getName() {
  return name;
}

public void setName(String name) {
  this.name = name;
}

public Address getAddress() {
  return address;
}

public void setAddress(Address address) {
  this.address = address;
}

public Set<Entree> getEntrees() {
  return entrees;
}

public void setEntrees(Set<Entree> entrees) {
  this.entrees = entrees;
}

}

Adderss class:

package blog.jpa.domain;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

@Entity
public class Address {

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;

@Column(name = "STREET_NUMBER")
private int streetNumber;

@Column(name = "STREET_NAME")
private String streetName;

public long getId() {
  return id;
}

public void setId(long id) {
  this.id = id;
}

public int getStreetNumber() {
  return streetNumber;
}

public void setStreetNumber(int streetNumber) {
  this.streetNumber = streetNumber;
}

public String getStreetName() {
  return streetName;
}

public void setStreetName(String streetName) {
  this.streetName = streetName;
}

}


然后, Entree class:

package blog.jpa.domain;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

@Entity
public class Entree {

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;

private String name;

private boolean vegetarian;

public long getId() {
  return id;
}

public void setId(long id) {
  this.id = id;
}

public String getName() {
  return name;
}

public void setName(String name) {
  this.name = name;
}

public boolean isVegetarian() {
  return vegetarian;
}

public void setVegetarian(boolean vegetarian) {
  this.vegetarian = vegetarian;
}

}


如你看到的那样,并不是所有的 field 都需要annotation。JAP 会使用默认值(例如用数据表中的列名来精确匹配属性名),所以在很多的情况下,你并不需要很明确的去指定元数据。需要注意的是,在 Entree 类中,我并没有为String 属性 “name” 或 boolean 属性 “vegetarian” 加入 annotation。

然而,在 Address 类中,我使用了annotation, 因为我不想用数据库表中的列名作为默认名(例如,我用 “STREET_NAME”而默认的是 “STREETNAME”)。在ORM机制中最重要的当然是指定Objects和database间的对应关系。在 Restaurant 类中,我们用 @OneToOne 去描述它与 Address 的关系,同时我们用 @ManyToMany 去描述它与 Entree 类中的成员关系。因为其它类的实例也是由 EntityManager 所管理的, 所以可以指定“cascade”规则,如当一个 Restaurant 被删除,所有相关联的 Address 也会同时被删除。在下面,你将会看到这个场景的测试用例。 最后,看看 @Id 和指定“strategy”给ID的 @GeneratedValue 。 这元数据是用来描述数据库中唯一键 primary key 的生成方式的。想知道更多关于JPA annotation 的资料,查看 JPA 的说明文档,JSR-220. 数据访问层 (Data Access Layer) 最好的方式是建立通用的接口去隐藏持久层所有的实现细节,这样就算由JPA换到其它的实现方式也不会影响到系统架构。

同时,这也为业务逻辑层提供了方便,可以更容易地实现 stub 或 mock 测试。 RestaurantDao 是一个接口,注意它没有对任何 JPA 或 Spring 的类有依赖。实际上,它只对自身的domain model 有依赖(在这个简单的例子中,只有一个,那就是 Restaurant):

package blog.jpa.dao;

import java.util.List;
import blog.jpa.domain.Restaurant;

public interface RestaurantDao {

public Restaurant findById(long id);

public List<Restaurant> findByName(String name);

public List<Restaurant> findByStreetName(String streetName);

public List<Restaurant> findByEntreeNameLike(String entreeName);

public List<Restaurant> findRestaurantsWithVegetarianEntrees();

public void save(Restaurant restaurant);

public Restaurant update(Restaurant restaurant);

public void delete(Restaurant restaurant);

}


对于接口的实现,我使用了 Spring 的 JpaDaoSupport 类,它提供了方便的方法去获取 JpaTemplate。如果你已经比较熟悉 Spring 的 JDBC 或者起其它 ORM 技术,则很容易上手。 JpaDaoSupport 是可选的,它只是提供了通过 EntityManagerFactory 更直接使用 JpaTemplate 的方法。JpaTemplate 也是可选的,如果你不希望 Spring 的自动处理 JPA exception 的事务方式,你完全可以避免使用 JpaTemplate 。即使这样,Spring 的 EntityManagerFactoryUtils 类还是会对你有比较大的帮助,它提供了方便的静态方法去获取共享的EntityManager。下面是具体实现代码:

package blog.jpa.dao;

import java.util.List;
import org.springframework.orm.jpa.support.JpaDaoSupport;
import blog.jpa.domain.Restaurant;

public class JpaRestaurantDao extends JpaDaoSupport implements RestaurantDao {

public Restaurant findById(long id) {
  return getJpaTemplate().find(Restaurant.class, id);
}

public List<Restaurant> findByName(String name) {
  return getJpaTemplate().find("select r from Restaurant r where r.name = ?1", name);
}

public List<Restaurant> findByStreetName(String streetName) {
  return getJpaTemplate().find("select r from Restaurant r where r.address.streetName = ?1", streetName);
}

public List<Restaurant> findByEntreeNameLike(String entreeName) {
  return getJpaTemplate().find("select r from Restaurant r where r.entrees.name like ?1", entreeName);
}

public List<Restaurant> findRestaurantsWithVegetarianEntrees() {
  return getJpaTemplate().find("select r from Restaurant r where r.entrees.vegetarian = 'true'");
}

public void save(Restaurant restaurant) {
  getJpaTemplate().persist(restaurant);
}

public Restaurant update(Restaurant restaurant) {
  return getJpaTemplate().merge(restaurant);
}

public void delete(Restaurant restaurant) {
  getJpaTemplate().remove(restaurant);
}

}


业务逻辑层 (Service Layer)

由于我们的主要目的是集中在数据访问层 JPA 的实现,所以业务逻辑层基本上忽略不讲。在实际项目中,业务逻辑层对于整个系统的架构至关重要。它是分离事务(transaction)的重点。一般情况下,我们都会通过 Spring 来配置事务。在下面的步骤中,当你看配置时,你会注意到我已提供了一个“transactionManager” 的 bean。 它可以为测试用例中的每个测试方法提供事务回滚,同时它也让使用同一个 “transactionManager”的业务逻辑层的方法提供事务处理。数据库访问层的代码与则不负责事务处理,事务传播的发生是自动的,最终由业务逻辑层来处理。Spring 框架中的所有持久层类的配置都是相同的,使用 Spring JpaTemplate 时要注意保证所有 DAO 都共享同一个EntityManager 。

配置

因为我选择了使用基于 annotation 的映射关系,你或许已经看过许多 JPA 的配置说明,如我上面说提到的,它同样可以通过 XML( 在‘orm.xml’文件里 )来配置映射关系。另一种则只要求配置‘META-INF/persistence.xml’。这样的话,就能更为容易,因为database相关的属性可以通过EntityManagerFactory 来获得。在‘persistence.xml’中需要的信息只是需要 local 的还是global(JTA) 的事务。下面是 ‘persistence.xml’ 的具体内容:

<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="1.0">

<persistence-unit name="SpringJpaGettingStarted" transaction-type="RESOURCE_LOCAL"/>

</persistence>

 


有4个bean在这 Spring 配置中是要注意的。

首先,看看“restaurantDao” (我没有在bean名前的"jpa"也加上去的原因是所有的业务逻辑层都必须只与接口相关),其唯一需要的 property 就是 “entityManagerFactory” ,用于产生JpaTemplate。 “entityManagerFactory” 需要“dataSource”, 这个在 JPA 说明文档里并没有提到。在这里,我们使用了DriverManagerDataSource,但是在实际操作中,你需要用你自己数据库的连接池,或者是用 JndiObjectFactoryBean来得到Jndi。最后的 “transactionManager” bean是测试和逻辑层处理事务需要到的。如果你已经熟悉 Spring 下 JDBC, Hibernate, JDO, TopLink, 或 iBATIS 的配置,这几个bean对于你来说是再简单不过了。然我们来看看完整的‘applicationContext.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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
  http://www.springframework.org/schema/beans/spring-beans.xsd">

<bean id="restaurantDao" class="blog.jpa.dao.JpaRestaurantDao">
  <property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>

<bean id="entityManagerFactory" class="org.springframework.orm.jpa.ContainerEntityManagerFactoryBean">
  <property name="dataSource" ref="dataSource"/>
  <property name="jpaVendorAdapter">
    <bean class="org.springframework.orm.jpa.vendor.TopLinkJpaVendorAdapter">
    <property name="showSql" value="true"/>
    <property name="generateDdl" value="true"/>
    <property name="databasePlatform" value="oracle.toplink.essentials.platform.database.HSQLPlatform"/>
    </bean>
  </property>
  <property name="loadTimeWeaver">
    <bean class="org.springframework.instrument.classloading.SimpleLoadTimeWeaver"/>
  </property>
</bean>

<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
  <property name="driverClassName" value="org.hsqldb.jdbcDriver"/>
  <property name="url" value="jdbc:hsqldb:hsql://localhost/"/>
  <property name="username" value="sa"/>
  <property name="password" value=""/>
</bean>

<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
  <property name="entityManagerFactory" ref="entityManagerFactory"/>
  <property name="dataSource" ref="dataSource"/>
</bean>

</beans>


“entityManagerFactory” bean需要 “jpaVendorAdapter” ,对于 “jpaVendorAdapter”有多种多样的JPA实现方式。在这个例子里,我用了 TopLinkJpaVendorAdapter 作为 inner bean,它也需要自己的一些property ,它有两个属性分别指明是否现实SQL和是否生成DDL.在这里我们都设为 “true” ,所以当测试的时候数据库表会每次都自动生成,这对于早期的开发带来不少方便。还有就是“databasePlatformClass” 提供了必要的数据库库使用的详细信息。“entityManagerFactory”还有一个“loadTimeWeaver” 属性,以配合某些特性,如延迟加载(lazy-loading)。

集成测试(Integration Testing)

JpaRestaurantDaoTests 提供了一些基础的测试。你可以自己尝试动手修改一下配置文件和测试代码,来掌握更多关于JPA的知识,如尝试不同的设置cascade 。值得注意的是 JpaRestaurantDaoTests 继承了 Spring 的 AbstractJpaTests。也许你已经比较熟悉 Spring 的 AbstractTransactionalDataSourceSpringContextTests, 这个类可以让在测试中的所有数据库改变都回滚。AbstractJpaTests 实际上的作用不仅于此,但已经超出了我们该讲的范围了。如果感兴趣,你可以深入看看AbstractJpaTests的源代码。这里是 JpaRestaurantDaoTests 的实现代码:

package blog.jpa.dao;

import java.util.List;
import org.springframework.test.jpa.AbstractJpaTests;
import blog.jpa.dao.RestaurantDao;
import blog.jpa.domain.Restaurant;

public class JpaRestaurantDaoTests extends AbstractJpaTests {

private RestaurantDao restaurantDao;

public void setRestaurantDao(RestaurantDao restaurantDao) {
  this.restaurantDao = restaurantDao;
}

protected String[] getConfigLocations() {
  return new String[] {"classpath:/blog/jpa/dao/applicationContext.xml"};
}

protected void onSetUpInTransaction() throws Exception {
  jdbcTemplate.execute("insert into address (id, street_number, street_name) values (1, 10, 'Main Street')");
  jdbcTemplate.execute("insert into address (id, street_number, street_name) values (2, 20, 'Main Street')");
  jdbcTemplate.execute("insert into address (id, street_number, street_name) values (3, 123, 'Dover Street')");

  jdbcTemplate.execute("insert into restaurant (id, name, address_id) values (1, 'Burger Barn', 1)");
  jdbcTemplate.execute("insert into restaurant (id, name, address_id) values (2, 'Veggie Village', 2)");
  jdbcTemplate.execute("insert into restaurant (id, name, address_id) values (3, 'Dover Diner', 3)");

  jdbcTemplate.execute("insert into entree (id, name, vegetarian) values (1, 'Hamburger', 0)");
  jdbcTemplate.execute("insert into entree (id, name, vegetarian) values (2, 'Cheeseburger', 0)");
  jdbcTemplate.execute("insert into entree (id, name, vegetarian) values (3, 'Tofu Stir Fry', 1)");
  jdbcTemplate.execute("insert into entree (id, name, vegetarian) values (4, 'Vegetable Soup', 1)");

  jdbcTemplate.execute("insert into restaurant_entree (restaurant_id, entree_id) values (1, 1)");
  jdbcTemplate.execute("insert into restaurant_entree (restaurant_id, entree_id) values (1, 2)");
  jdbcTemplate.execute("insert into restaurant_entree (restaurant_id, entree_id) values (2, 3)");
  jdbcTemplate.execute("insert into restaurant_entree (restaurant_id, entree_id) values (2, 4)");
  jdbcTemplate.execute("insert into restaurant_entree (restaurant_id, entree_id) values (3, 1)");
  jdbcTemplate.execute("insert into restaurant_entree (restaurant_id, entree_id) values (3, 2)");
  jdbcTemplate.execute("insert into restaurant_entree (restaurant_id, entree_id) values (3, 4)");
}

public void testFindByIdWhereRestaurantExists() {
  Restaurant restaurant = restaurantDao.findById(1);
  assertNotNull(restaurant);
  assertEquals("Burger Barn", restaurant.getName());
}

public void testFindByIdWhereRestaurantDoesNotExist() {
  Restaurant restaurant = restaurantDao.findById(99);
  assertNull(restaurant);
}

public void testFindByNameWhereRestaurantExists() {
  List<Restaurant> restaurants = restaurantDao.findByName("Veggie Village");
  assertEquals(1, restaurants.size());
  Restaurant restaurant = restaurants.get(0);
  assertEquals("Veggie Village", restaurant.getName());
  assertEquals("Main Street", restaurant.getAddress().getStreetName());
  assertEquals(2, restaurant.getEntrees().size());
}

public void testFindByNameWhereRestaurantDoesNotExist() {
  List<Restaurant> restaurants = restaurantDao.findByName("No Such Restaurant");
  assertEquals(0, restaurants.size());
}

public void testFindByStreetName() {
  List<Restaurant> restaurants = restaurantDao.findByStreetName("Main Street");
  assertEquals(2, restaurants.size());
  Restaurant r1 = restaurantDao.findByName("Burger Barn").get(0);
  Restaurant r2 = restaurantDao.findByName("Veggie Village").get(0);
  assertTrue(restaurants.contains(r1));
  assertTrue(restaurants.contains(r2));
}

public void testFindByEntreeNameLike() {
  List<Restaurant> restaurants = restaurantDao.findByEntreeNameLike("%burger");
  assertEquals(2, restaurants.size());
}

public void testFindRestaurantsWithVegetarianOptions() {
  List<Restaurant> restaurants = restaurantDao.findRestaurantsWithVegetarianEntrees();
  assertEquals(2, restaurants.size());
}

public void testModifyRestaurant() {
  String oldName = "Burger Barn";
  String newName = "Hamburger Hut";
  Restaurant restaurant = restaurantDao.findByName(oldName).get(0);
  restaurant.setName(newName);
  restaurantDao.update(restaurant);
  List<Restaurant> results = restaurantDao.findByName(oldName);
  assertEquals(0, results.size());
  results = restaurantDao.findByName(newName);
  assertEquals(1, results.size());
}

public void testDeleteRestaurantAlsoDeletesAddress() {
  String restaurantName = "Dover Diner";
  int preRestaurantCount = jdbcTemplate.queryForInt("select count(*) from restaurant");
  int preAddressCount = jdbcTemplate.queryForInt("select count(*) from address where street_name = 'Dover Street'");
  Restaurant restaurant = restaurantDao.findByName(restaurantName).get(0);
  restaurantDao.delete(restaurant);
  List<Restaurant> results = restaurantDao.findByName(restaurantName);
  assertEquals(0, results.size());
  int postRestaurantCount = jdbcTemplate.queryForInt("select count(*) from restaurant");
  assertEquals(preRestaurantCount - 1, postRestaurantCount);
  int postAddressCount = jdbcTemplate.queryForInt("select count(*) from address where street_name = 'Dover Street'");
  assertEquals(preAddressCount - 1, postAddressCount);
}

public void testDeleteRestaurantDoesNotDeleteEntrees() {
  String restaurantName = "Dover Diner";
  int preRestaurantCount = jdbcTemplate.queryForInt("select count(*) from restaurant");
  int preEntreeCount = jdbcTemplate.queryForInt("select count(*) from entree");
  Restaurant restaurant = restaurantDao.findByName(restaurantName).get(0);
  restaurantDao.delete(restaurant);
  List<Restaurant> results = restaurantDao.findByName(restaurantName);
  assertEquals(0, results.size());
  int postRestaurantCount = jdbcTemplate.queryForInt("select count(*) from restaurant");
  assertEquals(preRestaurantCount - 1, postRestaurantCount);
  int postEntreeCount = jdbcTemplate.queryForInt("select count(*) from entree");
  assertEquals(preEntreeCount, postEntreeCount);
}
}


进一步阅读

JPA是一个很大的话题,这篇日志只是讲述了如何在 Spring 框架中配置 JPA. 

只要你弄懂了配置如何运作,你就能很好的运用 JPA提供的ORM功能。我非常建议你去看看 JPA的官方文档还有 Spring reference 文档。在Spring 2.0 RC1 文档中就有加入了 JPA 的 ORM部分内容。以下是比较有用的一些连接:

JSR-220 (包含了 JPA 说明文档)
http://www.jcp.org/en/jsr/detail?id=220
Glassfish JPA (相关的实现说明)
https://glassfish.dev.java.net/javaee5/persistence/
Kodo 4.0 (BEA的基于Kodo的JPA实现)
http://commerce.bea.com/showproduct.jsp?family=KODO&major=4.0&minor=0
Hibernate JPA Migration Guide
http://www.hibernate.org/371.html
(自 http://blog.interface21.com/main/2006/05/30/getting-started-with-jpa-in-spring-20/ , cac 翻译)

注:因无法拷贝原的连接地址。因此,此处略有改动。

分享到:
评论

相关推荐

    spring 4.0.6 + jpa2.0配置

    采用hibernate 4.3.6,spring 4.0.6 ,实现jpa配置,简单易懂明了。压缩文件中包含jpa依赖的hibernate包,如果下载者希望运行,需要自己写实体类。压缩包中含有精简的配置。

    EJB3.0 + Struts1.3 + Spring2.0 + JPA

    软件架构: EJB3.0 + Struts1.3 + Spring2.0 + JPA 应用服务器: Jboss5.1 数据库用: Oracle9i 部署前将 demo-service.xml和oracle-ds.xml copy到jboss deploy目录下,配置到你的环境下即可 -- Create sequence ...

    Struts2+Spring2.0+JPA(Hibernate3.3)实例

    服务器:tomcat6.0 可运行,http://localhost:8080/spring/test.do 其中spring为tomcat配置path属性值 主要用于演示他们之间如何配置

    Spring 2.0 开发参考手册

    12.6.1. 在Spring环境中建立JPA 12.6.2. JpaTemplate 和 JpaDaoSupport 12.6.3. 基于原生的JPA实现DAO 12.6.4. 异常转化 12.6.5. 事务管理 12.6.6. JpaDialect III. Web 13. Web框架 13.1. 介绍 13.1.1. 与...

    spring-boot-jpa-hibernate-demo:Spring Boot中的JPA + Hibernate + MySQL

    具体方法不再赘述项目通过配置DBConfig这个类来配置JPA到Hibernate的结合,读者可自行将DBConfig中有关Hibernate的相关配置提取到application.properties文件中框架SpringBootSpringMVCSpring data JPAMySQL概述一个...

    spring-boot2.0全新教程实例20例.zip

    spring-boot2.0全新教程实例20例.zip - [spring-boot-helloWorld](https://github.com/ityouknow/spring-boot-examples/tree/master/spring-boot-helloWorld):Spring Boot 的 hello World 版本 - [spring-boot-...

    后台管理系统基于SpringBoot2.0 + Spring Data Jpa + Thymeleaf + Shiro

    - 菜单管理:用于配置系统菜单,同时也作为权限资源。 - 部门管理:通过不同的部门来管理和区分用户。 - 字典管理:对一些需要转换的数据进行统一管理,如:男、女等。 - 行为日志:用于记录用户对系统的操作,同时...

    springboot2.0多数据源集成hibernate配置hibernateDaoSupport示例

    springboot2.0多数据源集成hibernate配置hibernateDaoSupport, dao层继承hibernateDaoSupport, 不使用jpa方式。

    自己做的SSH2自动生成数据库表的实例

    因为数据库处理未实现,此实例只是说明动态生成数据库表,如果要实现数据操作 可以自行定义方法,希望大家能够理解spring和hibernate 本资例只是说明jpa和hibernate的配置关系及spring的关系 如果需要jar包请与我...

    Spring3.2_Hibernate4.2_JPA2全注解实例

    Spring3.2 Hibernate4.2 JPA2全注解实例.采用JTA事务管理,配置ehcache为二级缓存,在glassfish3.2.2和postgresql9测试通过。参考网上的资料整理。

    Spring3 MVC +HibernateJPA Eclipse Demo

    5、spring:3.1.1 hibernate:4.1.6 Hibernate-JPA:2.0 6、若更换数据库后代码有误,无法调通,请先运行com.web.test代码调试数据库配置,运行测试,数据库调通再运行com.web.mvc下的controller。 7、附带的另一...

    Guice2.0+Hibernate3.2+warp-persist-2.0+Struts2+JPA

    轻量级的Guice2.0代替了Spring,速度更快,项目体积更小,Hibernate3.2与JPA的结合使用代替了传统的配置文件,使Hibernate的开发更简单,本项目基本上是零配置开发,由于我只能上传小于15M的文件,故JAR被我删除了,...

    Spring-Reference_zh_CN(Spring中文参考手册)

    12.6.1. 在Spring环境中建立JPA 12.6.1.1. LocalEntityManagerFactoryBean 12.6.1.2. LocalContainerEntityManagerFactoryBean 12.6.1.3. 处理多个持久化单元 12.6.2. JpaTemplate 和 JpaDaoSupport 12.6.3. 基于...

    Spring3 MVC Hibernate-JPA Eclipse Demo

    5、spring:3.1.1 hibernate:4.1.6 Hibernate-JPA:2.0 6、若更换数据库后代码有误,无法调通,请先运行com.web.test代码调试数据库配置,运行测试,数据库调通再运行com.web.mvc下的controller。 7、附带的另一...

    2018年Java Activiti6.x 视频整合Spring Boot/JPA/WEB框架实战

    2018年Java Activiti6.x 视频整合Spring Boot/JPA/WEB框架实战 01 Activiti介绍与搭建开发环境 02 运行官方例子 03 编写第一个Activiti程序 04 流程引擎配置与服务组件 05 Activiti数据库介绍 06 API(1)...

    spring2.5.chm帮助文档(中文版)

    2. Spring 2.0和 2.5的新特性 2.1. 简介 2.2. 控制反转(IoC)容器 2.2.1. 新的bean作用域 2.2.2. 更简单的XML配置 2.2.3. 可扩展的XML编写 2.2.4. Annotation(注解)驱动配置 2.2.5. 在classpath中自动搜索组件...

    积分管理系统java源码-Timo:TIMO后台管理系统,基于SpringBoot2.0+SpringDataJpa+Thymeleaf+Sh

    TIMO后台管理系统,基于SpringBoot2.0 + Spring Data Jpa + Thymeleaf + Shiro 开发的后台管理系统,采用分模块的方式便于开发和维护,支持前后台模块分别部署,目前支持的功能有:权限管理、部门管理、字典管理、...

    Spring 2.5 jar 所有开发包及完整文档及项目开发实例

    13) spring-mock.jar需spring-core.jar,spring-beans.jar,spring-dao.jar,spring-context.jar,spring-jdbc.jarspring2.0和spring2.5及以上版本的jar包区别Spring 2.5的Jar打包 在Spring 2.5中, Spring Web MVC...

    spring chm文档

    12.6.1. 在Spring环境中建立JPA 12.6.2. JpaTemplate 和 JpaDaoSupport 12.6.3. 基于原生的JPA实现DAO 12.6.4. 异常转化 12.6.5. 事务管理 12.6.6. JpaDialect III. Web 13. Web框架 13.1. 介绍 13.1.1. 与...

    Spring MVC环境搭建:(Spring 2.5.6 + Hibernate 3.2.0)架包

     Hibernate 3.6.8:hibernate3.jar、hibernate-jpa-2.0-api-1.0.1.Final.jar、antlr-2.7.6.jar、commons-collections-3.1、dom4j-1.6.1.jar、javassist-3.12.0.GA.jar、jta-1.1.jar、slf4j-api-1.6.1.jar、slf4j-...

Global site tag (gtag.js) - Google Analytics