hibernate的运用表之间的级联关系
hibernate的应用表之间的级联关系
1.联合主键映射
pojo类实现,要有equals()和hashCode()方法
PsersonKey类
2.外键,多对一/一对多
测试类,具体实现在后面依次添加
DeptDao代码
3.理解延迟加载,区分load和get方法
首先,配置hibernate.cfg.xml不过一般用于测试使用,项目开发可以使用第三方的管理配置
hibernateUtil的配置
pojo类Dept
1.联合主键映射
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <!--指定映射文件所在的包路径--> <hibernate-mapping package="tarena.domain"> <class name="Person" table="person"> <!--联合主键的配置--> <composite-id name="key" class="PersonKey"> <key-property name="first" type="string"> <column name="first"></column> </key-property> <key-property name="last" type="string"> <column name="last"></column> </key-property> </composite-id> <property name="sex" type="string"> <column name="sex"></column> </property> </class> </hibernate-mapping>
pojo类实现,要有equals()和hashCode()方法
package tarena.domain; public class Person { private PersonKey key; private String sex; public PersonKey getKey() { return key; } public void setKey(PersonKey key) { this.key = key; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } @Override public int hashCode() { final int PRIME = 31; int result = 1; result = PRIME * result + ((key == null) ? 0 : key.hashCode()); result = PRIME * result + ((sex == null) ? 0 : sex.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; final Person other = (Person) obj; if (key == null) { if (other.key != null) return false; } else if (!key.equals(other.key)) return false; if (sex == null) { if (other.sex != null) return false; } else if (!sex.equals(other.sex)) return false; return true; } }
PsersonKey类
package tarena.domain; public class PersonKey implements java.io.Serializable{ private String first; private String last; public PersonKey(){} public PersonKey(String first, String last) { super(); this.first = first; this.last = last; } public String getFirst() { return first; } public void setFirst(String first) { this.first = first; } public String getLast() { return last; } public void setLast(String last) { this.last = last; } }
2.外键,多对一/一对多
<!--Dept.hbm.xml--> <hibernate-mapping package="tarena.domain"> <class name="Dept" table="dept" lazy="true"> <id name="id" type="integer"> <column name="id"></column> <!--id标识的生成策略,依赖于底层数据库的支持--> <generator class="native"></generator> </id> <property name="dname" type="string"> <column name="dname"></column> </property> <!--cascade="all"表示表示对象表之间的级联关系;one-to-many中级联的对象应由多(many)的一方来提供支持,many-to-many中可以是任意方--> <set name="emps" cascade="all" inverse="true"> <key column="dept_id"></key> <one-to-many class="Emp"/> </set> </class> <!--Emp.hbm.xml--> <class name="Emp" table="emp"> <id name="id" type="integer"> <column name="id"></column> <generator class="native"></generator> </id> <property name="ename" type="string"> <column name="ename"></column> </property> <!--class对应的级联表对象,fetch="join"表示表与表之间的抓取策略--> <many-to-one name="dept" column="dept_id" class="Dept" fetch="join"> </many-to-one> </class> </hibernate-mapping>
测试类,具体实现在后面依次添加
public class DeptDAOTest { DeptDAO deptDao; @Before public void init(){ deptDao = new DeptDAO(); } // @Test public void testAdd1(){ Dept dept = new Dept(); dept.setDname("testing"); deptDao.add(dept); } // @Test //测试级联添加 public void testAdd2(){ Dept dept = new Dept(); dept.setDname("design"); //添加新员工designer1 Set<Emp> emps = new HashSet<Emp>(); Emp emp1 = new Emp(); emp1.setEname("designer1"); emp1.setDept(dept); emps.add(emp1); // 添加新员工designer2 Emp emp2 = new Emp(); emp2.setEname("designer2"); emp2.setDept(dept); emps.add(emp2); //将员工集合emps指定给dept对象 dept.setEmps(emps); deptDao.add(dept); } @Test //测试级联删除 public void testDelete(){ Dept dept = deptDao.findById(4); deptDao.delete(dept); } // @Test public void testFindById(){ Dept dept = deptDao.findById(1); System.out.println(dept.getId()+":"+dept.getDname()); Set<Emp> emps = dept.getEmps(); for(Emp emp:emps){ System.out.println(emp.getId()+":"+emp.getEname()); } System.out.println("一共有"+emps.size()+"个员工"); } }
DeptDao代码
package tarena.dao; import org.hibernate.Session; import org.hibernate.Transaction; import tarena.domain.Dept; import tarena.util.HibernateUtil; public class DeptDAO { public Dept findById(int id){ Session session = HibernateUtil.getSession(); Dept dept = (Dept)session.load(Dept.class, id); return dept; } public void add(Dept dept){ Session session = HibernateUtil.getSession(); Transaction txt = session.beginTransaction(); session.save(dept); txt.commit(); HibernateUtil.closeSession(); } public void delete(Dept dept){ Session session = HibernateUtil.getSession(); Transaction txt = session.beginTransaction(); session.delete(dept); txt.commit(); HibernateUtil.closeSession(); } }
3.理解延迟加载,区分load和get方法
//load方法启用延迟加载,返回的对象是一个代理对象 //Dept dept = (Dept)session.load(Dept.class, 1); //get方法不启用延迟加载,立刻检索数据表,返回对象实例 Dept dept = (Dept)session.get(Dept.class, 1); //HibernateUtil.closeSession(); // 如使用延迟加载,不要将session关闭,否则会影响后续取值操作 //可以在业务操作都完成后,再将session关闭。 //比如JavaWeb程序可以使用Filter控制session关闭 //hibernate的默认配置是启用延迟,所以在使用get方法时, //可以Hibernate.initialize(obj),来对对象进行初始化加载,不过要在session.colse()之前 //或者可以把该对象的pojo类的映射文件的lazy="false",就可以了。
首先,配置hibernate.cfg.xml不过一般用于测试使用,项目开发可以使用第三方的管理配置
<?xml version='1.0' encoding='UTF-8'?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"> <!-- Generated by MyEclipse Hibernate Tools. --> <hibernate-configuration> <session-factory> <property name="myeclipse.connection.profile">mysql</property> <property name="connection.username">root</property> <property name="connection.password">1234</property> <property name="connection.url"> jdbc:mysql://localhost:3306/hibernate </property> <!-- 是否使用数据库本地话方言 --> <property name="dialect"> org.hibernate.dialect.MySQLDialect </property> <property name="connection.driver_class"> com.mysql.jdbc.Driver </property> <!-- 是否打印hql语句 --> <property name="show_sql">true</property> <!-- 对象的关系映射 --> <mapping resource="tarena/mapping/Person.hbm.xml" /> <mapping resource="tarena/mapping/Dept.hbm.xml" /> <mapping resource="tarena/mapping/Emp.hbm.xml" /> </session-factory> </hibernate-configuration>
hibernateUtil的配置
package tarena.util; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.cfg.Configuration; public class HibernateUtil { public static Configuration conf; public static SessionFactory sf; public static ThreadLocal<Session> sessionLocal = new ThreadLocal<Session>(); static{ conf = new Configuration(); conf.configure();//默认加载src下面的hibernate.cfg.xml配置文件 sf = conf.buildSessionFactory(); } public static Session getSession() { Session session = sessionLocal.get(); if(session == null){ session = sf.openSession(); sessionLocal.set(session); } return session; } public static void closeSession(){ Session session = sessionLocal.get(); sessionLocal.set(null); if(session != null){ session.close(); } } }
pojo类Dept
package tarena.domain; import java.io.Serializable; import java.util.Set; public class Dept implements Serializable{ private int id; private String dname; private Set<Emp> emps; public String getDname() { return dname; } public void setDname(String dname) { this.dname = dname; } public int getId() { return id; } public void setId(int id) { this.id = id; } public Set<Emp> getEmps() { return emps; } public void setEmps(Set<Emp> emps) { this.emps = emps; } }