美文网首页
hibernate学习(三)

hibernate学习(三)

作者: 咻咻咻i | 来源:发表于2017-09-06 07:32 被阅读0次

突然感觉接触到了流币的知识,完全不懂。数据库方面的很多东西以前都没接触过。等今年开课在认真学一遍吧,暂时按照教程把我学到的东西整理下。

第一节 一对多映射列表(XML)

对于没有系统学习过数据库的我而言一开始并不明白这是什么意思。教程给的例子使用的联系人,感觉还是很好理解的。一个客户可以拥有多个用户,客户就是一联系人就是多,即一对多。

  • 创建用户实体类 Customer.java
package cn.lkangle.entity;

import java.util.HashSet;
import java.util.Set;

public class Customer {
    private Integer cid;
    private String name;
    private String attr;
    
    // 将联系人保存于set集合中
    private Set<LinkMan> linkMans = new HashSet<LinkMan>();
    ...
}
  • 创建联系人实体类 LinkMan.java
package cn.lkangle.entity;

public class LinkMan {
    private Integer lid;
    private String name;
    private String tel;

    // 用于保存所属客户
    private Customer customer;
    ...
}
  • XML映射配置文件
<?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>
     <!-- 一对多的客户映射配置 -->
    <class name="cn.lkangle.entity.Customer" table="t_customer">
        <id name="cid" column="cid">
            <generator class="native"></generator>
        </id>
        <property name="name" column="cname"></property>
        <property name="attr" column="cattr"></property>
        
        <set name="linkMans" cascade="save-update,delete">
            <key column="clid"></key>
            <one-to-many class="cn.lkangle.entity.LinkMan"></one-to-many>
        </set>
    </class>
    
    <!-- 一对多的联系人映射配置 -->
    <class name="cn.lkangle.entity.LinkMan" table="t_linkman">
        <id name="lid" column="lid">
            <generator class="native"></generator>
        </id>
        <property name="name" column="lname"></property>
        <property name="tel" column="ltel"></property>
        
        <many-to-one name="customer" class="cn.lkangle.entity.Customer" column="clid" cascade="save-update"></many-to-one>
    </class>
</hibernate-mapping>

客户的set标签与联系人的many-to-one标签是配置一对多的关键,其中的cascade属性设置级联操作。
级联具有方向性,在客户中添加只有在对客户进行操作时才会产生级联,在联系人中添加只有对联系人进行操作时才产生级联

cascade属性取值:

  • update-save 在更新和保存时进行级联
  • delete 在删除时进行级联
  • all 任何操作都进行级联
  • 一对多级联的CRUD操作
package cn.lkangle.threeday;

import java.util.Set;

import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test;

import cn.lkangle.entity.Customer;
import cn.lkangle.entity.LinkMan;
import cn.lkangle.util.HbmUtil;

public class OnetoManyTest {
    /**
     * 双重级联效果 配置文件中客户和联系人都要设置级联属性 只是试试
     */
    @Test
    public void testSave2() {
        Session session = null;
        Transaction tx = null;
        try {
            session = HbmUtil.getSession();
            System.out.println(session);
            tx = session.beginTransaction();
            
            Customer customer = new Customer();
            customer.setName("客户一");
            customer.setAttr("北京");
            
            LinkMan linkMan = new LinkMan();
            linkMan.setName("联系人一");
            linkMan.setTel("3333333333");
            LinkMan linkMan2= new LinkMan();
            linkMan2.setName("联系人二");
            linkMan2.setTel("865432222");
            
            customer.getLinkMans().add(linkMan);
            customer.getLinkMans().add(linkMan2);
            linkMan.setCustomer(customer);
            linkMan2.setCustomer(customer);
            
            session.save(linkMan);
            
            tx.commit();
        } catch (Exception e) {
            tx.rollback();
        } finally {
            session.close();
        }
    }
    /**
     * 级联查询操作
     */
    @Test
    public void testSelect() {
        Session session = null;
        Transaction tx = null;
        try {
            session = HbmUtil.getSession();
            System.out.println(session);
            tx = session.beginTransaction();
            
//          Customer customer = session.get(Customer.class, 9);
//          System.out.println(customer);
//          Set<LinkMan> linkMans = customer.getLinkMans();
//          for (LinkMan linkMan : linkMans) {
//              System.err.println(linkMan);
//          }
            LinkMan linkMan = session.get(LinkMan.class, 2);
            System.out.println(linkMan);
            System.out.println(linkMan.getCustomer());

            tx.commit();
        } catch (Exception e) {
            tx.rollback();
        } finally {
            session.close();
        }
    }
    /**
     * 级联删除
     */
    @Test
    public void testDelete() {
        Session session = null;
        Transaction tx = null;
        try {
            session = HbmUtil.getSession();
            System.out.println(session);
            tx = session.beginTransaction();
                        
//          LinkMan linkMan = session.get(LinkMan.class, 6);
//          session.delete(linkMan);

            Customer customer = session.get(Customer.class, 6);
            session.delete(customer);
            
            tx.commit();
        } catch (Exception e) {
            tx.rollback();
        } finally {
            session.close();
        }
    }
    /**
     * 级联修改 直接操作实体类就可以
     */
    @Test
    public void testUpdate() {
        Session session = null;
        Transaction tx = null;
        try {
            session = HbmUtil.getSession();
            System.out.println(session);
            tx = session.beginTransaction();
            /**
             * 在这里如果设置了双向级联修改时会出现对外键进行两次修改,这是双向维护外键导致的,这样的效率就不高 
             * 推荐在客户中设置inverse="true"让其放弃对外键的维护,解决修改时会修改两次外键 
             */
            Customer customer = session.get(Customer.class, 9);
            
            LinkMan linkMan = session.get(LinkMan.class, 2);
            LinkMan linkMan2 = session.get(LinkMan.class, 7);
            // 因为放弃了客户对外键的维护 这里要更新联系人
            linkMan.setCustomer(customer);          
            linkMan2.setCustomer(customer);
            
            tx.commit();
        } catch (Exception e) {
            tx.rollback();
        } finally {
            session.close();
        }
    }
    /**
     * 级联保存
     */
    @Test
    public void testSave() {
        Session session = null;
        Transaction tx = null;
        try {
            session = HbmUtil.getSession();
            System.out.println(session);
            tx = session.beginTransaction();
            
            Customer customer = new Customer();
            customer.setName("客户一");
            customer.setAttr("地址");
            
            LinkMan linkMan = new LinkMan();
            linkMan.setName("联系人一");
            linkMan.setTel("55555555");
            LinkMan linkMan2= new LinkMan();
            linkMan2.setName("联系人二");
            linkMan2.setTel("9999999999");
            
            customer.getLinkMans().add(linkMan);
            customer.getLinkMans().add(linkMan2);
            
            session.save(customer); // 客户要设置级联属性为save-update才能成功保存
            
            tx.commit();
        } catch (Exception e) {
            tx.rollback();
        } finally {
            session.close();
        }
    }
}

XMl配置中set标签的inverse属性值
   inverse="false" 默认 不放弃级联
   inverse="true" 放弃级联
好处在进行update操作时可以提高效率减少一次数据库操作

第二节 多对多映射列表(XML)

多对多使用的人和角色的关系举例,即一个人可以同时有多个角色,一个角色同时可以是多个人的。

  • 创建人实体类 Man.java
package cn.lkangle.entity;

import java.util.HashSet;
import java.util.Set;

public class Man {
    private Integer man_id;
    private String man_name;
    private String man_attr;
    
    private Set<Role> roles = new HashSet<>();
    ...
}
  • 创建角色实体类 Role.java
package cn.lkangle.entity;

import java.util.HashSet;
import java.util.Set;

public class Role {
    private Integer role_id;
    private String role_name;
    
    private Set<Man> mans = new HashSet<>();
    ...
}
  • XML映射配置文件
<?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>
    <!-- 多对多用户映射配置 -->
    <class name="cn.lkangle.entity.Man" table="t_man">
        <id name="man_id" column="man_id">
            <generator class="native"></generator>
        </id>
        <property name="man_name" column="man_name"></property>
        <property name="man_attr" column="man_attr"></property>
        
        <set name="roles" table="mans_role" cascade="save-update,delete">
            <key column="man_id_3"></key>
            <many-to-many class="cn.lkangle.entity.Role" column="role_id_3"></many-to-many>
        </set>
    </class>
    
    <!-- 多对多角色映射配置 -->
    <class name="cn.lkangle.entity.Role" table="t_role">
        <id name="role_id" column="role_id">
            <generator class="native"></generator>
        </id>
        <property name="role_name"></property>
        
        <set name="mans" table="mans_role">
            <key column="role_id_3"></key>
            <many-to-many class="cn.lkangle.entity.Man" column="man_id_3"></many-to-many>
        </set>
    </class>
</hibernate-mapping>
 set集合属性 
         table: 第三个表的表名
         
         key属性
         column: 本表外键在第三张表中的字段名
         
         many-to-many属性
         class: 另一个实体类的路径
         column: 另一个表外键在第三张表中的字段名

两个实体类的配置对应关系如图:

  • 多对多的CRUD操作
package cn.lkangle.threeday;

import java.util.Set;

import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test;

import cn.lkangle.entity.Man;
import cn.lkangle.entity.Role;
import cn.lkangle.util.HbmUtil;

public class ManyToMany {
    /**
     * 查询
     */
    @Test
    public void testManySelect() {
        Session session = null;
        Transaction tx = null;
        try {
            session = HbmUtil.getSession();
            tx = session.beginTransaction();
            
            Man man = session.get(Man.class, 2);
            System.out.println(man);
            
            Set<Role> roles = man.getRoles();
            for (Role role : roles) {
                System.out.println(role);
            }
            tx.commit();
        } catch (Exception e) {
            tx.rollback();
        } finally {
            session.close();
        }
    }
    /**
     * 修改 通过维护第三张表实现
     */
    @Test
    public void testManyUpdate() {
        Session session = null;
        Transaction tx = null;
        try {
            session = HbmUtil.getSession();
            tx = session.beginTransaction();
            
            Man man = session.get(Man.class, 2);
            
            Role role = session.get(Role.class, 3);
            man.getRoles().add(role);
            
            tx.commit();
        } catch (Exception e) {
            tx.rollback();
        } finally {
            session.close();
        }
    }
    /**
     * 直接性级联删除 不推荐
     */
    @Test
    public void testManyDelete0() {
        Session session = null;
        Transaction tx = null;
        try {
            session = HbmUtil.getSession();
            tx = session.beginTransaction();
            
            Man man = session.get(Man.class, 1);
            
            session.delete(man);
            
            tx.commit();
        } catch (Exception e) {
            tx.rollback();
        } finally {
            session.close();
        }
    }
    /**
     * 删除 通过维护第三张表实现
     */
    @Test
    public void testManyDelete() {
        Session session = null;
        Transaction tx = null;
        try {
            session = HbmUtil.getSession();
            tx = session.beginTransaction();
            
            Man man = session.get(Man.class, 1);
            Role role = session.get(Role.class, 1);
            
            man.getRoles().remove(role);
            
            tx.commit();
        } catch (Exception e) {
            tx.rollback();
        } finally {
            session.close();
        }
    }
    /**
     * 多对多级联保存
     */
    @Test
    public void testMany() {
        Session session = null;
        Transaction tx = null;
        try {
            session = HbmUtil.getSession();
            tx = session.beginTransaction();
            
            Man man = new Man();
            man.setMan_name("严老");
            man.setMan_attr("兔斯基");
            Man man2 = new Man();
            man2.setMan_name("叶老");
            man2.setMan_attr("土耳其");
            
            Role role = new Role();
            role.setRole_name("老板");
            Role role2 = new Role();
            role2.setRole_name("秘书");
            Role role3 = new Role();
            role3.setRole_name("保安");
            
            man.getRoles().add(role);
            man.getRoles().add(role2);
            man2.getRoles().add(role);
            man2.getRoles().add(role3);
            
            session.save(man);
            session.save(man2);
            
            tx.commit();
        } catch (Exception e) {
            tx.rollback();
        } finally {
            session.close();
        }
    }
}

实话我还没写过用到相关操作的项目、、、数据库也没系统学习过对此感觉很是生疏,看过教程也就会这一些基础的知识,更细节深入的知识还需要以后继续学习~~

相关文章

网友评论

      本文标题:hibernate学习(三)

      本文链接:https://www.haomeiwen.com/subject/ttsejxtx.html