• (十二)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")
           来对获得的“多”方信息进行排序   

  • 相关阅读:
    Linux makefile
    java泛型
    Java中Split函数的用法技巧
    mysql基础笔记
    Linux学习路线浅谈
    泛型的用法
    数据流图的画法
    oracle学习路线图
    c++学习建议
    C#学习建议
  • 原文地址:https://www.cnblogs.com/shyroke/p/6853033.html
Copyright © 2020-2023  润新知