Hibernate自关联关系
业务逻辑:
书籍的种类,本身是自关联的关系,如下图所示:
所有书籍:
历史书籍
音乐书籍
钢琴书籍
烹饪书籍
美食书籍
1. Books类的源程序
Books.java
package mypack;
import java.util.Set;
import java.io.Serializable;
public class Books
implements Serializable {
/**
* 默认构造函数
*/
public Books() {
}
/** 主健id */
private Long id;
/** 书籍名称 */
private String name;
/** 父书籍 */
private mypack.Books parentCategory;
/** 子集合 */
private Set childCategories;
/** 完整构造函数 */
public Books(String name, mypack.Books parentCategory, Set childCategories) {
this.name = name;
this.parentCategory = parentCategory;
this.childCategories = childCategories;
}
/** 最小构造函数 */
public Books(Set childCategories) {
this.childCategories = childCategories;
}
public Long getId() {
return this.id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
public mypack.Books getParentCategory() {
return this.parentCategory;
}
public void setParentCategory(mypack.Books parentCategory) {
this.parentCategory = parentCategory;
}
public Set getChildCategories() {
return this.childCategories;
}
public void setChildCategories(Set childCategories) {
this.childCategories = childCategories;
}
}
2. 映射文件,放在classes/mypack下
Books.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping
PUBLIC "-//Hibernate/Hibernate Mapping DTD 2.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">
<hibernate-mapping >
<class name="mypack.Books" table="books" >
<id name="id" type="long" column="ID">
<generator class="increment"/>
</id>
<property name="name" type="string" >
<column name="NAME" length="15" />
</property>
<set
name="childCategories"
cascade="save-update"
inverse="true"
>
<key column="CATEGORY_ID" />
<one-to-many class="mypack.Books" />
</set>
<many-to-one
name="parentCategory"
column="CATEGORY_ID"
class="mypack.Books"
cascade="save-update"
/>
</class>
</hibernate-mapping>
3. 数据库Schema
数据库Schema
Create table books(
Id number(10) not null,
Name varchar2(64),
Category_id number(10),
Primary key(id)
);
1. hibernate.property
hibernate.property
hibernate.dialect net.sf.hibernate.dialect.Oracle9Dialect
hibernate.dialect net.sf.hibernate.dialect.OracleDialect
hibernate.connection.driver_class oracle.jdbc.driver.OracleDriver
hibernate.connection.username testpm
hibernate.connection.password testpm
hibernate.connection.url jdbc:oracle:thin:@localhost:1521:wsy
4. 业务操作类BusinessService.java
package mypack;
import net.sf.hibernate.SessionFactory;
import net.sf.hibernate.cfg.Configuration;
import net.sf.hibernate.*;
import java.util.HashSet;
import java.util.List;
public class BusinessService {
public static SessionFactory sessionFactory;
static{
try{
// Create a configuration based on the properties file we've put
Configuration config = new Configuration();
config.addClass(Books.class);
// Get the session factory we can use for persistence
sessionFactory = config.buildSessionFactory();
}catch(Exception e){e.printStackTrace();}
}
public BusinessService() {
}
/**
* 级联保存
* @throws Exception
*/
public void saveCategoryWithCascade() throws Exception{
Session session = sessionFactory.openSession();
Transaction tx = null;
try {
tx = session.beginTransaction();
Books allBooks = new Books("allbooks",null,new HashSet());
Books historyBooks = new Books("history",null,new HashSet());
Books musicBooks =new Books("music",null,new HashSet());
Books cookBooks=new Books("cook",null,new HashSet());
Books pianoBooks=new Books("piano",null,new HashSet());
Books foodBooks=new Books("food",null,new HashSet());
//建立所有书与历史书的关系
allBooks.getChildCategories().add(historyBooks);
historyBooks.setParentCategory(allBooks);
//建立所有书与音乐书的关系
allBooks.getChildCategories().add(musicBooks);
musicBooks.setParentCategory(allBooks);
//建立所有书与烹饪书的关系
allBooks.getChildCategories().add(cookBooks);
cookBooks.setParentCategory(allBooks);
//建立音乐书与钢琴书的关系
musicBooks.getChildCategories().add(pianoBooks);
pianoBooks.setParentCategory(musicBooks);
//建立烹饪书与美食书的关系
foodBooks.setParentCategory(cookBooks);
cookBooks.getChildCategories().add(foodBooks);
session.save(allBooks);
tx.commit();
}catch (Exception e) {
if (tx != null) {
// Something went wrong; discard all partial changes
tx.rollback();
}
throw e;
} finally {
// No matter what, close the session
session.close();
}
}
/**
* 修改关系
* @throws Exception
*/
public void modifyCategoryAssociation() throws Exception{
Session session = sessionFactory.openSession();
Transaction tx = null;
try {
tx = session.beginTransaction();
Books cookBooks =findCategoryByName(session,"cook");
Books foodBooks=findCategoryByName(session,"food");
Books musicBooks=findCategoryByName(session,"music");
//建立西红柿类和蔬菜类之间的关联关系
foodBooks.setParentCategory(musicBooks);
musicBooks.getChildCategories().add(foodBooks);
//删除西红柿类和水果类之间的关联关系
cookBooks.getChildCategories().remove(foodBooks);
tx.commit();
}catch (Exception e) {
if (tx != null) {
// Something went wrong; discard all partial changes
tx.rollback();
}
throw e;
} finally {
// No matter what, close the session
session.close();
}
}
/**
* 根据名称,得到bean
* @param session Session
* @param name String
* @throws Exception
* @return Books
*/
private Books findCategoryByName(Session session,String name)throws Exception{
List results=session.find("from Books as c where c.name='"+name+"'");
return (Books)results.iterator().next();
}
/**
* 主方法,运行
* @param args String[]
* @throws Exception
*/
public static void main(String[] args)throws Exception{
new BusinessService().test();
sessionFactory.close();
}
/**
* 测试方法
* @throws Exception
*/
private void test()throws Exception {
saveCategoryWithCascade();
modifyCategoryAssociation();
}
}
目录结构示意:
Classes
Hibernate.property
/mypack
Books.java
BusinessService.java
Books.hbm.xml
参考资料:精通Hibernate:Java对象持久化技术详解 孙卫琴