一. 集合映射
一个用户对应多个地址
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的执行效率!
配置一对多与多对一,这种叫“双向关联”
只配置一对多, 叫“单项一对多”
只配置多对一, 叫“单项多对一”
注意:
配置了哪一方,哪一方才有维护关联关系的权限!
本文详细探讨了Hibernate框架中集合映射和关联映射的实现,包括set、list、map集合的映射配置,以及JavaBean设计、配置文件配置和JUnit测试代码的展示。在关联映射部分,解释了一对多、多对一和多对多的关系,提供了具体的数据库设计、javabean封装和映射策略,并强调了通过多的一方维护关系以提高执行效率的重要性。
1309

被折叠的 条评论
为什么被折叠?



