(十二)Hibernate中的多表操作(2):单向多对一

  • 由“多”方可知“一”方的信息,比如多个员工使用同一栋公寓,员工可以知道公寓的信息,而公寓无法知道员工的信息。

案例一:使用xml配置

  • pojo类 Group.java
package bean;

// default package

/**
 * Group entity. @author MyEclipse Persistence Tools
 */

public class Group implements java.io.Serializable {

    // Fields

    private Integer groupid;
    private String groupname;

    //省略get和set方法
    //省略空的和满的构造方法    
      
}

  GroupUser.java

package bean;

// default package

/**
 * GroupUser entity. @author MyEclipse Persistence Tools
 */

public class GroupUser implements java.io.Serializable {

    // Fields

    private Integer userid;
    private String username;

    private Group group;

    //省略get和set方法
     //省略构造方法


}    
  • 实体映射文件  Group.hbm.xml
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

<hibernate-mapping>
    <class name="bean.Group" table="t_group" catalog="test">
        <id name="groupid" type="java.lang.Integer">
            <column name="groupid" />
            <generator class="assigned"></generator>
        </id>
        <property name="groupname" type="java.lang.String">
            <column name="groupname" />
        </property>
    </class>
</hibernate-mapping>

 GroupUser.hbm.xml

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<!-- 
    Mapping file autogenerated by MyEclipse Persistence Tools
-->
<hibernate-mapping>
    <class name="bean.GroupUser" table="t_groupuser" catalog="test">
        <id name="userid" type="java.lang.Integer">
            <column name="userid" />
            <generator class="assigned"></generator>
        </id>
        <property name="username" type="java.lang.String">
            <column name="username" />
        </property>
          <!-- name的值要与本类的属性名一致,这里指定这个bean映射的表的外键为group_id属性且该属性是自动生成的,所以必须与数据库中的外键字段一致
                            //所以该bean就不需要设置表中外键的映射了。                          // hibernate默认该外键关联group映射的表的主键,
--> <many-to-one name="group" class="bean.Group" column="group_id" cascade="all"></many-to-one> <!-- class值指定了“一”方的类 --> </class> </hibernate-mapping>
  • <many-to-one >元素建立了department属性和employee表的外键depart_id之间的映射.

 <many-to-one name="group" class="bean.Group" column="group_id" cascade="all">

  • <many-to-one name="group" class="bean.Group" column="group_id" cascade="all">这种情况,hibernate会默认去group对象中查找主键值,因为hibernate默认的是外键对应另一个表中的主键的,如果想对应group中的其它属性,如”name”,则可以使用<many-to-one name=”group” column=”group_id” property-ref=”name”/>
  • name: 设定待映射的持久化类的属性名,此外为employee类的department属性.

    column: 设定和持久化类的属性对应的表的外键,此外为employee表的外键depart_id.

    class(可选):设定持久化类的属性的类型,此处设定department的类型是Department类.

    not-null(可选):如果为true,表示department属性不能为null,该属性的默认值为false.当为true时,生成的employee表中depart_id外键会设置not-null约束,所以当Hibernate保存Employee对象时,会先检查它的department属性是否为null,如果为null,则会抛出异常.


案例二:使用注解配置

  • 多个用户对应一个组,一个组有多个用户。且多个用户可以知道组的信息,但是组不能知道用户的信息。
  • 数据库中表结构:

  •  建议pojo持久化类: Group.java
package bean;

import java.io.Serializable;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;

import org.hibernate.annotations.GenericGenerator;

@Entity
@Table(name = "t_group")
public class Group implements Serializable {
    
    @Id
    @GeneratedValue(generator="a")
    @GenericGenerator(name="a",strategy="assigned")
    private Integer groupid;
@Column(name
="groupname") private String groupName; //省略get和set方法 //省略空的构造方法和满构造方法 }
  • GroupUser.java
package bean;

import java.io.Serializable;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;

import org.hibernate.annotations.GenericGenerator;

@Entity
@Table(name = "t_groupuser")
public class GroupUser implements Serializable {

    @Id
    @GeneratedValue(generator = "designed")
    @GenericGenerator(name = "designed", strategy = "assigned")
    private Integer userid;

    private String username;


    @ManyToOne(cascade = { CascadeType.REMOVE, CascadeType.MERGE })     // 设置关联关系和级联类型
    @JoinColumn(name = "group_id")    // 该注解表示指定外键,这里指定这个bean映射的表的外键为group_id属性且该属性是自动生成的,所以必须与数据库中的外键字段一致,所以该bean就不需要设置表中外键的映射了。
                         // hibernate默认该外键关联group映射的表的主键,
private Group group; public GroupUser() { } public GroupUser(Integer userid, String username) { super(); this.userid = userid; this.username = username; } public Integer getUserid() { return userid; } public void setUserid(Integer userid) { this.userid = userid; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public Group getGroup() { return group; } public void setGroup(Group group) { this.group = group; } }
  •   测试类  Test_ManytoOne.java
package action;

import org.hibernate.Session;
import org.hibernate.Transaction;

import bean.Group;
import bean.GroupUser;
import util.HibernateUtil;


/**
 * 本类测试多对一的操作
 * @author 半颗柠檬、
 *
 */
public class Test_ManytoOne {
    public static void main(String[] args) {
        Test_ManytoOne.save();
        
//        Test_ManytoOne.select();
        
//        Test_ManytoOne.delete();
    }

    public static void save(){
        Session session = null;
        Transaction tran = null;
        try {
            session = HibernateUtil.getSessionFactory().getCurrentSession();
            tran=session.beginTransaction();
            
            //添加一个组
            Group group=new Group();
            group.setGid(1);
            group.setGroupName("管理员组");
            
            //添加组成员
            GroupUser user=new GroupUser();
            user.setUserid(1);
            user.setUsername("admin1");
            user.setGroup(group);
            
            GroupUser user1=new GroupUser();
            user1.setUserid(2);
            user1.setUsername("admin2");
            user1.setGroup(group);
            
            session.save(group);
            session.save(user);
            session.save(user1);
            
            tran.commit();
        } catch (Exception e) {
            e.printStackTrace();
            tran.rollback();
        }
    }
    
    /**
     * 测试单向对一是否只能多方读取一方,而一方不能读取多方
     */
    private static void select() {
        Session session = null;
        Transaction tran = null;
        try {
            session = HibernateUtil.getSessionFactory().getCurrentSession();
            tran=session.beginTransaction();
            
        
            GroupUser user=    (GroupUser)session.get(GroupUser.class, new Integer(2));
            System.out.println(user.getUserid()+"	"+user.getUsername());
            
            //单向获取“一”方的信息
            
            Group group=user.getGroup();
            System.out.println("groupid="+group.getGid()+"	"+group.getGroupName());
            
            tran.commit();
        } catch (Exception e) {
            e.printStackTrace();
            tran.rollback();
        }
    }

    /**
     * 删除Many一方时,默认不会级联删除One的一方。
     * 
     * 如果要级联删除:,一般使用代码手动级联更新
     * 
     * A:使用代码来控制级联删除。[使用这种方式]
     * 
     * B:配置级联关系,让Hibernate自动执行。
     * 
     * 在关联关系中配置cascade属性。
     * 
     * @ManyToOne(cascade = { CascadeType.REMOVE, CascadeType.MERGE })
     * 
     */
    private static void delete() {
        Session session = null;
        Transaction tx = null;
        try {
            session = HibernateUtil.getSession();
            tx = session.beginTransaction();
            /**
             * A:使用代码控制级联
             */
//             GroupUser user = (GroupUser) session.get(GroupUser.class,
//             new Integer(1));
//            
//             session.delete(user);
//            
//             Group group = user.getGroup();
//             session.delete(group);
            /**
             * B  在关联关系中配置cascade属性之后
             */
            GroupUser user = (GroupUser) session.get(GroupUser.class,
                    new Integer(1));
            session.delete(user);

            tx.commit();
        } catch (Exception e) {
            e.printStackTrace();
            tx.rollback();
        } finally {
            HibernateUtil.closeSession();
        }
    }
    
    
}


  • 一对多可以从“一”方得到“多”方的信息,那么可以用

          OneToMany
            @JoinColumn(name = " ")
            @OrderBy(value=" studentID desc")
       来对获得的“多”方信息进行排序   

原文地址:https://www.cnblogs.com/shyroke/p/6853033.html