基于mvc模式的应用框架之Hibernate(三)

本文详细探讨了Hibernate框架中集合映射和关联映射的实现,包括set、list、map集合的映射配置,以及JavaBean设计、配置文件配置和JUnit测试代码的展示。在关联映射部分,解释了一对多、多对一和多对多的关系,提供了具体的数据库设计、javabean封装和映射策略,并强调了通过多的一方维护关系以提高执行效率的重要性。

一. 集合映射

一个用户对应多个地址

1.JaveBean设计
public class User
 {
    private int userId;
    private String userName;
    private Set<String> address;
    private List<String> addressList = new ArrayList<String>(); 
    private Map<String,String> addressMap = new HashMap<String, String>();
    public Map<String, String> getAddressMap()  
    {
        return addressMap;
    }
    public void setAddressMap(Map<String, String> addressMap)  
    {
        this.addressMap = addressMap;
    }
    public List<String> getAddressList()  
    {
        return addressList;
    }
    public void setAddressList(List<String> addressList)  
    {
        this.addressList = addressList;
    }
    public int getUserId()  
    {
        return userId;
    }
    public void setUserId(int userId)  
    {
        this.userId = userId;
    }
    public String getUserName()  
    {
        return userName;
    }
    public void setUserName(String userName)  
    {
        this.userName = userName;
    }
    public Set<String> getAddress()   
    {
        return address;
    }
    public void setAddress(Set<String> address)   
    {
        this.address = address;
    }
}
2.配置文件配置详情
1.set集合属性的映射

1).name 指定要映射的set集合的属性
2).table 集合属性要映射到的表
3).key指定集合表(t_address)的外键字段
4).element 指定集合表的其他字段
5).type元素类型,一定要指定

2.list集合映射

list-index: 指定的是排序列的名称 (因为要保证list集合的有序)

3. map集合的映射

1).key 指定外键字段
2).map-key 指定map的key
3).element 指定map的value

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC 
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="cn.itcast.a_collection">
    <class name="User" table="t_user">
        <id name="userId" column="id">
            <generator class="native"></generator>
        </id>   
        <property name="userName"></property>
         <set name="address" table="t_address">
            <key column="uid"></key>
            <element column="address" type="string"></element>
         </set>
          <list name="addressList" table="t_addressList">
              <key column="uid"></key>
              <list-index column="idx"></list-index>
              <element column="address" type="string"></element>
          </list>
          <map name="addressMap" table="t_addressMap">
            <key column="uid"></key>
            <map-key column="shortName" type="string" ></map-key>
            <element column="address" type="string" ></element>
          </map>
    </class>
</hibernate-mapping>
3.Juint测试代码
public class App
{
    private static SessionFactory sf;
    static  
    {
        sf = new Configuration()
            .configure()
            .addClass(User.class)   
            .buildSessionFactory();
    }

    @Test
    public void testSaveSet() throws Exception  
    {
        Session session = sf.openSession();
        session.beginTransaction();
        Set<String> addressSet = new HashSet<String>();
        addressSet.add("广州");
        addressSet.add("深圳");
        User user = new User();
        user.setUserName("Jack");
        user.setAddress(addressSet);
        session.save(user);
        session.getTransaction().commit();
        session.close();
    }

    @Test
    public void testSaveList() throws Exception  
    {
        Session session = sf.openSession();
        session.beginTransaction();
        User user = new User();
        user.setUserName("Tom");
        user.getAddressMap().put("A0001", "广州");
        user.getAddressMap().put("A0002", "深圳");
        session.save(user);
        session.getTransaction().commit();
        session.close();
    }

    @Test
    public void testGet() throws Exception  
    {
        Session session = sf.openSession();
        session.beginTransaction();
        User user = (User) session.get(User.class, 3); 
        System.out.println(user.getUserId());
        System.out.println(user.getUserName());
        System.out.println(user.getAddressList());
        session.getTransaction().commit();
        session.close();
    }
}

二.关联映射

需求1:
部门与员工
一个部门有多个员工; 【一对多】
多个员工,属于一个部门 【多对一】
需求2:
项目与开发员工
一个项目,有多个开发人员!
一个开发人员,参与多个项目! 【多对多】

多对一映射与一对多
代码
需求:员工与部门
数据库:
设计javabean封装:
映射:

1.javaBean设计
public class Dept 
{
    private int deptId;
    private String deptName;
    //【一对多】 部门对应的多个员工
    private Set<Employee> emps = new HashSet<Employee>();   
}   

public class Employee 
{

    private int empId;
    private String empName;
    private double salary;
    // 【多对一】员工与部门
    private Dept dept;
}
2.配置文件配置
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC 
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="cn.itcast.b_one2Many">
    <class name="Dept" table="t_dept">
        <id name="deptId">
            <generator class="native"></generator>
        </id>   
        <property name="deptName" length="20"></property>
    <!-- 
     一对多关联映射配置  (通过部门管理到员工)
     Dept 映射关键点:
            1.  指定 映射的集合属性: "emps"
            2.  集合属性对应的集合表: "t_employee"
            3.  集合表的外键字段   "t_employee. dept_id"
            4.  集合元素的类型
         -->
         <set name="emps">   <!-- table="t_employee" -->
             <key column="dept_id"></key>
             <one-to-many class="Employee"/>
         </set>
    </class>
</hibernate-mapping>


<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC 
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

<hibernate-mapping package="cn.itcast.b_one2Many">
    <class name="Employee" table="t_employee">
        <id name="empId">
            <generator class="native"></generator>
        </id>   
        <property name="empName" length="20"></property>
        <property name="salary" type="double"></property>
        <!-- 
            多对一映射配置
            Employee 映射关键点:
            1.  映射的部门属性  :  dept
            2.  映射的部门属性,对应的外键字段: dept_id
            3.  部门的类型
         -->
         <many-to-one name="dept" column="dept_id" class="Dept"></many-to-one>
    </class>
</hibernate-mapping>
3.测试代码
public class App 
{
    private static SessionFactory sf;
    static {
        sf = new Configuration()
            .configure()
            .addClass(Dept.class)   
            .addClass(Employee.class)   // 测试时候使用
            .buildSessionFactory();
    }

    // 保存, 部门方 【一的一方法操作】
    @Test
    public void save() {

        Session session = sf.openSession();
        session.beginTransaction();

        // 部门对象
        Dept dept = new Dept();
        dept.setDeptName("应用开发部");
        // 员工对象
        Employee emp_zs = new Employee();
        emp_zs.setEmpName("张三");
        Employee emp_ls = new Employee();
        emp_ls.setEmpName("李四");
        // 关系
        dept.getEmps().add(emp_zs);
        dept.getEmps().add(emp_ls);

        // 保存
        session.save(emp_zs);
        session.save(emp_ls);
        session.save(dept); // 保存部门,部门下所有的员工  

        session.getTransaction().commit();
        session.close();
        /*
         *  结果
         *  Hibernate: insert into t_employee (empName, salary, dept_id) values (?, ?, ?)
            Hibernate: insert into t_employee (empName, salary, dept_id) values (?, ?, ?)
            Hibernate: insert into t_dept (deptName) values (?)
            Hibernate: update t_employee set deptId=? where empId=?    维护员工引用的部门的id
            Hibernate: update t_employee set deptId=? where empId=?
         */
    }

    // 【推荐】 保存, 部员方 【多的一方法操作】
    @Test
    public void save2() {

        Session session = sf.openSession();
        session.beginTransaction();

        // 部门对象
        Dept dept = new Dept();
        dept.setDeptName("综合部");
        // 员工对象
        Employee emp_zs = new Employee();
        emp_zs.setEmpName("张三");
        Employee emp_ls = new Employee();
        emp_ls.setEmpName("李四");
        // 关系
        emp_zs.setDept(dept);
        emp_ls.setDept(dept);


        // 保存
        session.save(dept); // 先保存一的方法
        session.save(emp_zs);
        session.save(emp_ls);// 再保存多的一方,关系回自动维护(映射配置完)

        session.getTransaction().commit();
        session.close();
        /*
         *  结果
         *  Hibernate: insert into t_dept (deptName) values (?)
            Hibernate: insert into t_employee (empName, salary, dept_id) values (?, ?, ?)
            Hibernate: insert into t_employee (empName, salary, dept_id) values (?, ?, ?)
            少生成2条update  sql
         */
    }
}

总结:
在一对多与多对一的关联关系中,保存数据最好的通过多的一方来维护关系,这样可以减少update语句的生成,从而提高hibernate的执行效率!
配置一对多与多对一,这种叫“双向关联”
只配置一对多, 叫“单项一对多”
只配置多对一, 叫“单项多对一”
注意:
配置了哪一方,哪一方才有维护关联关系的权限!

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

The_Web3_社区

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值