多对一映射
多对一:
这里举例:User类与Group类,
一个Group中是有多个User的。具体数据库表现为在Group类的主键作为User类的外键。
POJO:
package com.lwf.hibernate.pojo;public class User {private int id;private String name;private Group group = new Group();public int getId() {return id;}public void setId(int id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public Group getGroup() {return group;}public void setGroup(Group group) {this.group = group;}}
?
package com.lwf.hibernate.pojo;public class Group {private int id;private String name;public int getId() {return id;}public void setId(int id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}}
?
<?xml version="1.0"?><!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN""http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"><hibernate-mapping package="com.lwf.hibernate.pojo"><class name="User" table="t_user"><id name="id"><generator column="group_id" cascade="all" ></many-to-one></class><class name="Group" table="t_group"><id name="id"><generator name="code">package com.lwf.hibernate.test;import junit.framework.TestCase;import org.hibernate.Session;import com.lwf.hibernate.pojo.Group;import com.lwf.hibernate.pojo.User;import com.lwf.hibernate.util.HibernateUtil;public class Many2one_Test extends TestCase{public void testUser(){Session session = HibernateUtil.getSession();session.beginTransaction();try{Group g = new Group();g.setName("group1");//session.save(g);//如果不保存group那么<many-to-one name="group" column="group_id" cascade="all" />中的cascade="all" 必须设置.for (int i = 0; i < 5; i++) {User u = new User();u.setName("user");u.setGroup(g);session.save(u);}HibernateUtil.commit(session);}catch(Exception e){HibernateUtil.roolback(session);}finally{HibernateUtil.closeSession(session);}}public void testLoad(){Session session = null;try{session = HibernateUtil.getSession();session.beginTransaction();User user = (User)session.load(User.class, 1);System.out.println(user.getName());System.out.println(user.getGroup().getName());HibernateUtil.commit(session);}catch(Exception e){HibernateUtil.roolback(session);}finally{HibernateUtil.closeSession(session);}}}
?
注意点:
一、了解cascade="all"的使用.如果设置了级联,那么保存User的时候会自动先保存Group。否则如果不调用session.save(g);会报错。
二、观察testLoad方法,我们发现发出了如下SQL语句:
Hibernate: select user0_.id as id0_0_, user0_.name as name0_0_, user0_.group_id as group3_0_0_ from t_user user0_ where user0_.id=?userHibernate: select group0_.id as id1_0_, group0_.name as name1_0_ from t_group group0_ where group0_.id=?group1
?
即发出了两条SQL,先查出user的group_id,然后再通过group_id到group对象查询name
那么我们知道在数据库操作上是可以通过连接来查询出的:
mysql> select u.name,g.name from t_user u left outer join t_group g on u.group_id=g.id;
?那么其实我们在many-to-one上增加fetch属性即可实现这个查询
如下:
<many-to-one name="group" column="group_id" cascade="all" fetch="join" ></many-to-one>
?
再来测试一下,这时通过testLoad方法发出的SQL语句是:
Hibernate: select user0_.id as id0_1_, user0_.name as name0_1_, user0_.group_id as group3_0_1_, group1_.id as id1_0_, group1_.name as name1_0_ from t_user user0_ left outer join t_group group1_ on user0_.group_id=group1_.id where user0_.id=?usergroup1
?