一、开发环境
l MyEclipse 8.5。因为JPA只能应用在Hibernate3.2及以上的版本,而MyEclipse 8.5的核心库是Hibernate3.2的版本,在通过MyEclipse生成Hibernate的配置文件的时候会看到。
l Jdk 5.0。
l Tomcat5.5.28。
l Sql server 2000。
l Jar包:
ejb3-persistence.jar
hibernate3.jar
hibernate-annotations.jar
hibernate-entitymanager.jar
hibernate-validator.jar
jtds.jar
junit.jar
dom4j-1.6.1.jar
hibernate-commons-annotations.jar
commons-collections.jar
cglib-2.1.3.jar
jta.jar
antlr-2.7.6.jar
asm.jar
commons-logging-1.0.4.jar
二、开发实例
1. 首先创建一个Web工程,New->Web Project
2. 将开发需要用到的十五个jar包放到项目的WebRoot->WEB-INF->lib下面,并引用进来。
3. 接下来需要配置一个DB Browser,Window->Show View->other会出现如下画面
点OK之后会出现DB Browser的页面,在DB Browser页面的空白处点击右键,点击New之后,出现一个配置画面,配置如下(以sql server为例):
然后点下一步,然后finish,中间不需要任何操作。
在DB Browser页面上右键点击刚才配置的jpaDb项目,选择open connection,成功之后会出现数据库的一个连接,里面可以看到数据库的所有表,效果如下:
这样一个DB连接就配置完成了。
4. 回到Web工程项目,开始生成hibernate配置文件,右键点击jpa项目工程,Myeclipse->Add Hibernate Capabilities
点击Next
点击Next
点击Next
然后点击finish自动生成hibernate配置文件了。
5. 在数据库中创建两个表
CREATE TABLE classes (
id int identity (1,1) NOT NULL PRIMARY KEY ,
name varchar (100) NOT NULL DEFAULT ('')
)
CREATE TABLE users(
id int IDENTITY (1, 1) NOT NULL PRIMARY KEY,
name varchar (100) NOT NULL DEFAULT (''),
age int NULL
)
6. 然后在Web工程项目中,创建两个与数据库中的users和classes两个表对应的实体Entity:User.java和Classes.java
User.java代码如下:
import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToMany;
import javax.persistence.Table;
@Entity
@Table(name="users")//对应数据库中的表名
public class User implements Serializable{
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy=GenerationType.AUTO)//表示自增主键
private Integer id;
@Column(name="name")//对应数据库表中的列名
private String name;
@Column(name="age")
private Integer age;
//多对多配置,一个User对应多个Classes,mappedBy="users"中的//users是映射到Classes类中private Set<User> users = new
//HashSet< User >();的变量名
@ManyToMany(mappedBy="users",fetch=FetchType.EAGER)
private Set<Classes> cla = new HashSet<Classes>();
public Set<Classes> getClasses() {
return cla;
}
public void setClasses(Set<Classes> classes) {
cla = classes;
}
public User() {
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}
Classes.java代码如下:
import java.util.HashSet;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Column;
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.OrderBy;
import javax.persistence.Table;
@Entity
@Table(name="classes")//对应数据库的表名
public class Classes implements java.io.Serializable {
private static final long serialVersionUID = 1L;
// Fields
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private Integer id;
@Column(name="name",length=100)//对应数据库中表的列,最大长度是100
private String name;
@ManyToMany(cascade = CascadeType.ALL)// 级联合并方式一
//多对多,级联合并方式一,往数据库中插入Classes值时,如果属性users的Set集合有新的User实体,则会将User实体的信息插入到User表中,并创建关联;删除该类的实体时也会将所有与之关联的User一起删掉。也就是说这个设置可以使Classes实体连带操作User表和关联表course。
//@ManyToMany(cascade = CascadeType.PERSIST)// 级联合并方式二
//多对多,级联合并方式二,使Classes实体的任何增删改查操作都不能影响User表,但可以操作关联表,比如删除某一个Classes,如果这个实体在关联表中和User有关联,则会将关联也删除,而不删除User。也就是说这个设置可以使Classes实体连带操作关联表course,而不能操作User表。
@JoinTable(name="course",inverseJoinColumns=@JoinColumn(name="uid"),joinColumns=@JoinColumn(name="cid"))
//上面的注释的作用是,在执行多对多的关联操作时,会自动创建关联表course,uid列对应User表的主键Id,cid列对应Classes的主键Id
@OrderBy("id desc")//查询时,users是按照user表的id降序排列的
private Set<User> users = new HashSet<User>();
/** default constructor */
public Classes() {
}
public Set<User> getUsers() {
return users;
}
public void setUsers(Set<User> users) {
this.users = users;
}
public Classes(String name) {
this.name = name;
}
public Integer getId() {
return this.id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
}
7. 修改hibernate的配置文件hibernate.cfg.xml,将新建的两个实体类在hibernate.cfg.xml中添加映射,具体实现如下
8. 创建hibernate拦截器HibernateInterceptor.java,具体代码如下:
import java.io.Serializable;
import org.hibernate.CallbackException;
import org.hibernate.EmptyInterceptor;
import org.hibernate.type.Type;
import com.ajax.dao.Classes;
import com.ajax.dao.User;
public class HibernateInterceptor extends EmptyInterceptor { //只要继承这个类就OK了
private static final long serialVersionUID = 1L;
@Override
public boolean onSave(Object entity, Serializable id, Object[] state, String[] propertyNames, Type[] types)
{ //entity就是当前的实体对象
//保存
System.out.println("执行保存操作:");
if(entity instanceof User)
{
User user=(User)entity;
// if(user.getId()==null)
// {
// //返回true则拦截本次操作
// return true;
// }
System.out.println(user.getName());
System.out.println(user.getAge());
}
if(entity instanceof Classes)
{
Classes clas=(Classes)entity;
System.out.println(clas.getName());
}
return super.onSave(entity, id, state, propertyNames, types);
}
@Override
public boolean onFlushDirty(Object entity, Serializable id,
Object[] currentState, Object[] previousState,
String[] propertyNames, Type[] types)
{ //entity就是当前的实体对象
//更新
System.out.println("执行更新操作:");
if(entity instanceof User)
{
User user=(User)entity;
System.out.println(user.getName());
System.out.println(user.getAge());
}
if(entity instanceof Classes)
{
Classes clas=(Classes)entity;
System.out.println(clas.getName());
}
return super.onFlushDirty(entity, id, currentState,previousState,propertyNames, types);
}
@Override
public void onDelete(Object arg0, Serializable arg1, Object[] arg2,
String[] arg3, Type[] arg4) throws CallbackException
{
//删除
System.out.println("执行删除操作:");
if(arg2!=null&&arg2.length>0)
for(Object ob:arg2)
{
System.out.println(ob.toString());
}
// super.onDelete(arg0,arg1,arg2,arg3,arg4);
}
}
该类实现的功能就是在对表执行添加、更新、删除操作时,在执行操作之前将操作对象的属性值显示出来。如果在方法中返回true则拦截本次操作,不予执行。
9. 编写service方法totalService.java,代码如下:
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import org.hibernate.Interceptor;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.AnnotationConfiguration;
import org.hibernate.cfg.Configuration;
import com.ajax.dao.Classes;
import com.ajax.dao.User;
import com.ajax.interceptor.HibernateInterceptor;
public class totalService {
private Session session;
private Transaction tx;
SessionFactory sessionFactory;
//获得session
public void before()
{
Configuration config = new AnnotationConfiguration().configure();
//添加拦截器
Interceptor intercept=new HibernateInterceptor();
config.setInterceptor(intercept);
sessionFactory = config.buildSessionFactory();
session = sessionFactory.openSession();
tx= session.beginTransaction();
}
//关闭session
public void after()
{
tx.commit();
session.close();
sessionFactory.close();
}
//插入一个新用户
public void insertRecord1(User user)
{
before();
session.save(user);
after();
}
//插入一个新班级
public void insertRecord2(Classes cla)
{
before();
session.save(cla);
after();
}
//插入一个新班级和一个新用户,并添加关联;
public void insertRecord3(Classes cla,User user)
{
before();
cla.getUsers().add(user);
session.save(cla);
after();
}
//根据已有的班级id和用户id,添加关联
public void createRelate(String cid,String uid)
{
before();
Classes cla=new Classes();
cla=(Classes)session.get(Classes.class, new Integer(cid));
User user=(User)session.get(User.class, new Integer(uid));
cla.getUsers().add(user);
session.save(cla);
after();
}
//根据已有的班级id和用户id,删除它们的关联
public void deleteRelate(String cid,String uid)
{
before();
Classes cla=new Classes();
cla=(Classes)session.get(Classes.class, new Integer(cid));
User user=(User)session.get(User.class, new Integer(uid));
if(cla.getUsers().contains(user))
{
cla.getUsers().remove(user);
session.save(cla);
}
after();
}
//根据用户id查询出所有与之关联的班级
public List selectClassesByUserId(String id)
{
List list=new ArrayList();
before();
User us=(User)session.get(User.class, new Integer(id));
Set classes=us.getClasses();
for(Object ob:classes)
{
list.add(ob);
}
after();
return list;
}
//根据班级id查询出所有与之关联的用户
public List selectUsersByClassId(String id)
{
List list=new ArrayList();
before();
Classes cla=(Classes)session.get(Classes.class, new Integer(id));
Set users=cla.getUsers();
for(Object ob:users)
{
list.add(ob);
}
after();
return list;
}
//查询出所有用户
public List selectAllUser()
{
before();
List list = session.createCriteria(User.class).list();
after();
return list;
}
//查询出所有班级
public List selectAllClass()
{
before();
List list = session.createCriteria(Classes.class).list();
after();
return list;
}
//根据用户id删除该用户的所有关联
public void deleteRelateOfUser(String id)
{
List classes=selectAllClass();
for(Object ob:classes)
{
Classes cla=(Classes)ob;
deleteRelate(cla.getId().toString(),id);
}
}
//根据用户id删除用户
public void deleteRecordU(String id)
{
deleteRelateOfUser (id);
before();
User us=(User)session.get(User.class, new Integer(id));
session.delete(us);
after();
}
//根据班级id删除班级
public void deleteRecordC(String id)
{
before();
Classes us=(Classes)session.get(Classes.class, new Integer(id));
session.delete(us);
after();
}
//根据用户id更新用户
public void updateRecordU(User user)
{
before();
User us=(User)session.get(User.class, new Integer(user.getId()));
us.setName(user.getName());
us.setAge(user.getAge());
session.update(us);
after();
}
//根据班级id更新班级
public void updateRecordC(Classes cla)
{
before();
Classes classes=(Classes)session.get(Classes.class, new Integer(cla.getId()));
classes.setName(cla.getName());
session.update(classes);
after();
}
}
10. 编写单元测试程序 Test.java,代码如下:
import java.util.List;
import junit.framework.TestCase;
public class Test extends TestCase{
public void test() {
totalService aa=new totalService();
List list=aa.selectAllUser();
for(Object ob:list)
{
User u=(User)ob;
System.out.println(u.getName());
}
}
}