关于spring+hibernate JPA的一个例子
通过spring配置来实现对数据库的访问和对事务的管理
简单的对一张表(table)的操作
实体类:
User.java
package domain;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.Table;
/**
* User generated by MyEclipse Persistence Tools
*/
@Entity
@Table(name = "user", catalog = "shopping")
@NamedQueries(value = {@NamedQuery(name = "User.findAllUsers", query = "from User")})
public class User implements java.io.Serializable {
// Fields
/**
*
*/
private static final long serialVersionUID = 2172281412405163597L;
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private Integer id;
private String name;
private String pswd;
private String email;
// Constructors
/** default constructor */
public User() {
}
/** full constructor */
public User(Integer id, String name, String pswd, String email) {
this.id = id;
this.name = name;
this.pswd = pswd;
this.email = email;
}
// Property accessors
@Id
@Column(name = "ID", unique = true, nullable = false, insertable = true, updatable = true)
public Integer getId() {
return this.id;
}
public void setId(Integer id) {
this.id = id;
}
@Column(name = "NAME", unique = false, nullable = false, insertable = true, updatable = true, length = 30)
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
@Column(name = "PSWD", unique = false, nullable = false, insertable = true, updatable = true, length = 45)
public String getPswd() {
return this.pswd;
}
public void setPswd(String pswd) {
this.pswd = pswd;
}
@Column(name = "EMAIL", unique = false, nullable = false, insertable = true, updatable = true, length = 60)
public String getEmail() {
return this.email;
}
public void setEmail(String email) {
this.email = email;
}
}
Userdao.java (对表user的操作)
package com;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.PersistenceException;
import javax.persistence.Query;
import org.springframework.orm.jpa.JpaCallback;
import org.springframework.orm.jpa.JpaTemplate;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
import domain.User;
@Repository
public class Userdao {
private EntityManagerFactory entityManagerFactory;
public Userdao() {
}
protected JpaTemplate getJpaTemplate() {
return new JpaTemplate(this.entityManagerFactory);
}
@Transactional
// 声明为事务
public void createUser(User user) {
final JpaTemplate jpaTemplate = getJpaTemplate();
jpaTemplate.persist(user);
}
@Transactional
// 声明为事务
public void updateAndsaveUser(User user) {
final JpaTemplate jpaTemplate = getJpaTemplate();
user = jpaTemplate.merge(user);
System.out.println("修改完成");
}
@Transactional
public void deleteUser(User user) {// 注意与deleteUserById()方法的比较
final JpaTemplate jpaTemplate = getJpaTemplate();// 下面为什么没有用user
// =jpaTemplate.merge(user);
// 是因为下面的查找和删除都在一个事务中,user一直处于managed状态
user = jpaTemplate.merge(user); // change bean from detacthed to
// managed;
jpaTemplate.remove(user);
}
public User findUserById(Integer id) {
final JpaTemplate jpaTemplate = getJpaTemplate();
return jpaTemplate.find(User.class, id);
}
@Transactional
// 声明事务
public boolean deleteAllUsers() {
final JpaTemplate jpaTemplate = getJpaTemplate();
return (Boolean) jpaTemplate.execute(new JpaCallback() {
public Object doInJpa(EntityManager em) throws PersistenceException {
Query q = em.createNativeQuery("Delete from User");
if (q.executeUpdate() == 0)
return Boolean.TRUE;
else
return Boolean.FALSE;
}
});
}
public List findAllUsers() {
final JpaTemplate jpaTemplate = getJpaTemplate();
return jpaTemplate.findByNamedQuery("User.findAllUsers");
}
@Transactional
// 事务声明 删除操作必须在事务中才能完成
public boolean deleteUserById(Integer id) {
User user = null;
final JpaTemplate jpaTemplate = getJpaTemplate();
user = jpaTemplate.find(User.class, id);
if (user != null) {
jpaTemplate.remove(user);
System.out.println("删除用户:" + user.getName() + "(id=" + user.getId()
+ ")");
return true;
} else {
System.out.println("无法删除用户(id=" + id + ")");
return false;
}
}
public void setEntityManagerFactory(
EntityManagerFactory entityManagerFactory) {
this.entityManagerFactory = entityManagerFactory;
}
}
persistence.xml (持久化单元)
<?xml version="1.0" encoding="UTF-8"?>
<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/persistence
http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd" version="1.0">
<persistence-unit name="entityManagerFactory"
transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<class>domain.User</class>
<properties>
<property name="hibernate.connection.driver_class"
value="com.mysql.jdbc.Driver" />
<property name="hibernate.connection.url"
value="jdbc:mysql://localhost:3306/shopping?useUnicode=true&characterEncoding=GB2312" />
<property name="hibernate.connection.username" value="root" />
<property name="hibernate.connection.password" value="1024" />
<property name="show_sql" value="true" />
<property name="hibernate.Dialect"
value="org.hibernate.dialect.MySQLDialect" />
</properties>
</persistence-unit>
</persistence>
ApplicationContext.xml(Spring的一些配置)
<?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: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.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-2.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.0.xsd">
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">
<property name="persistenceUnitName"
value="entityManagerFactory" />
</bean>
<bean
class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />
<!-- 事务管理配置 -->
<bean id="myTxManager"
class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory"
ref="entityManagerFactory" />
</bean>
<tx:annotation-driven transaction-manager="myTxManager"></tx:annotation-driven>
<bean id="userdao" class="com.Userdao">
<property name="entityManagerFactory"
ref="entityManagerFactory" />
</bean>
</beans>
测试类
package com;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import domain.User;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test {
/**
* @param args
*/
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext(
"ApplicationContext.xml");
Userdao dao = (Userdao) ctx.getBean("userdao");
// System.out.println("姓名:"+dao.getUser().getName());
// System.out.println("年龄:"+dao.getUser().getAge());
/*
* dao.deleteUserById(1); dao.deleteUserById(2); dao.deleteUserById(3);
*/
// System.out.println(dao.deleteAllUsers());
// User user1 = new User(4,"lb","1235","lb@163.com");
// User user2 = new User(5,"hjp","1236","hjp@163.com");
// User user3 = new User(6,"zrq","1237","zrq@163.com");
// dao.createUser(user1);
// dao.createUser(user2);
// dao.createUser(user3);
User user11 = dao.findUserById(8);
if (user11 != null)
{System.out.println("姓名: " + user11.getName() + "(id="
+ user11.getId() + ");");
dao.deleteUser(user11);}
System.out.println("<----------------------------------->");
User user = dao.findUserById(1);
user.setName("yyq");
user.setEmail("yyq2007aa@163.com");
dao.updateAndsaveUser(user);
List<User> userlist = new ArrayList<User>();
userlist = dao.findAllUsers();
Iterator item = userlist.iterator();
int i = 0;
while (item.hasNext()) {
i++;
System.out.println(i + ". 姓名:" + ((User) item.next()).getName());
}
}
}
要注意的就是在Userdao.java中对User的cud等操作的事务性处理,事务通过@Transactional来声明,那么在ApplicationContext.xml中配置的事务管理器会自动把这个操作当作事务来处理。
JPA是持久化的标准,需要provider。现在支持JPA的ORM包有多种。Netbeans自带Toplink,如果想使用ORM框架的一些高级的功能,可以使用Hibernate作为JPA的实现。
使用Hibernate作为JPA的实现,需要在官网下载core、annotation、entityManager包。一般支持Hibernate的IDE都会带有core包,那么只需一下这些jar就可以:
ejb3-persistence.jar //创建实体时可以使用jdk1.6带的注释功能
hibernate-annotations.jar
hibernate-commons-annotations.jar
hibernate-entitymanager.jar //创建持久性单元需要这个jar
javassist.jar
jboss-archive-browsing.jar
将这些jar放到类路径就可以创建持久性单元persisitence.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="JavaApplication14PU" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<class>model.JH</class>
<properties>
<property name="hibernate.connection.username" value="root"/>
<property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver"/>
<property name="hibernate.connection.password" value=" 123"/>
<property name="hibernate.connection.url" value="jdbc:mysql://localhost:3306/news"/>
<property name="hibernate.hbm2ddl.auto" value="update"/>
<property name="show_sql" value="true"/>
</properties>
</persistence-unit>
</persistence>
其实这个就和hibernate.cfg.xml一样,用于管理持久层的配置。
不过写法和hibernate.cfg.xml有一些区别。
在hibernate.cfg.xml我们可以这样写:
<property name="show_sql">true</true>
但是在persistence.xml里面,我们得在value里面写:
<property name="show_sql" value="true"/>
之后建立实体就可以使用我们的Annotation了,不用再使用mapping文件了。
如果要使用到hibernate的高级功能,只需要在这个persistence.xml里面添加就可以了,例如我想添加二级缓存还有查询缓存,可以添加:
<!-- 配置缓存插件 -->
<property name="hibernate.cache.provider_class" value="org.hibernate.cache.EhCacheProvider"/>
<!-- 开启二级缓存 -->
<property name="hibernate.cache.use_second_level_cache" value="true"/>
而且当实体需要使用缓存的时候,我们只需要加上这个Annotation:
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class MyModel{}
这相当于在mapping文件里面添加:
<cache usage="read-only"/>