hibernate关系映射
一对多映射
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="com.jie.domain.TAddressProvince" table="t_address_province" schema="region">
<id name="id" column="id">
<generator class="native"></generator>
</id>
<property name="code" column="code"/>
<property name="name" column="name"/>
<!--一对多set
name:当前类的属性名
column:从表中的外键名
foreign-key:主表中的被参照字段
property-ref:主表中被参照字段的属性名
class:从表的类
-->
<set name="citys" cascade="all">
<key column="provinceCode" foreign-key="code" property-ref="code"></key>
<one-to-many class="com.jie.domain.TAddressCity"></one-to-many>
</set>
</class>
</hibernate-mapping>
domain类
package com.jie.domain;
import java.util.HashSet;
import java.util.Set;
public class TAddressProvince {
private int id;
private String code;
private String name;
private Set<TAddressCity>citys=new HashSet<>();
public Set<TAddressCity> getCitys() {
return citys;
}
public void setCitys(Set<TAddressCity> citys) {
this.citys = citys;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
TAddressProvince that = (TAddressProvince) o;
if (id != that.id) return false;
if (code != null ? !code.equals(that.code) : that.code != null) return false;
if (name != null ? !name.equals(that.name) : that.name != null) return false;
return true;
}
@Override
public int hashCode() {
int result = id;
result = 31 * result + (code != null ? code.hashCode() : 0);
result = 31 * result + (name != null ? name.hashCode() : 0);
return result;
}
}
这个其实就是在hibernate生成类的基础上添加属性 private Set
citys=new HashSet<>();和其get、set方法。
util工具类
package com.jie.util;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
public class HibernateUtil {
static SessionFactory factory=null;
static {
//创建配置文件
Configuration config=new Configuration();
//读取配置文件
config.configure("/hibernate.cfg.xml");
//创建sessionFactory
factory=config.buildSessionFactory();
}
//获取session
public static Session getCurrentSession(){
Session session=factory.openSession();
return session;
}
//关闭session
public static void closeSession(Session session){
if (session!=null){
session.close();
}
}
}
test测试类
package com.jie;
import com.jie.domain.TAddressCity;
import com.jie.domain.TAddressProvince;
import com.jie.util.HibernateUtil;
import org.hibernate.Session;
import org.junit.Test;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
//一对多
public class Test2 {
//查询
@Test
public void getCityInfo(){
Session session= HibernateUtil.getCurrentSession();
List<TAddressProvince>provinces=session.createQuery("from TAddressProvince").list();
HibernateUtil.closeSession(session);
}
//级联增加
@Test
public void sava(){
Session session= HibernateUtil.getCurrentSession();
session.beginTransaction();
TAddressProvince province=new TAddressProvince();
province.setName("JXQY");
province.setCode("830000");
Set<TAddressCity>cities=new HashSet<>();
TAddressCity city1=new TAddressCity();
city1.setName("QQ");
city1.setCode("831000");
TAddressCity city2=new TAddressCity();
city2.setName("ZJSZ");
city2.setCode("832000");
cities.add(city1);
cities.add(city2);
province.setCitys(cities);
session.save(province);
session.getTransaction().commit();
HibernateUtil.closeSession(session);
}
//级联修改
@Test
public void updata(){
Session session= HibernateUtil.getCurrentSession();
session.beginTransaction();
TAddressProvince province=session.get(TAddressProvince.class,48);
province.setName("JXQY123");
Set cities=province.getCitys();
Iterator iterator=cities.iterator();
int i=100;
while (iterator.hasNext()){
TAddressCity city=(TAddressCity) iterator.next();
city.setName("qq"+i++);
}
session.update(province);
session.getTransaction().commit();
HibernateUtil.closeSession(session);
}
//级联删除
@Test
public void delete(){
Session session=HibernateUtil.getCurrentSession();
session.beginTransaction();
TAddressProvince province=session.get(TAddressProvince.class,48);
session.delete(province);
session.getTransaction().commit();
HibernateUtil.closeSession(session);
}
}
一对多映射总结:
分析SQL:
get方法:
1:通过one方获取many方,使用了延迟加载.
2:one方的many方的属性是一个集合,必须使用接口来声明.
3:不能通过if-null来判断one方是否有many方,只能通过size方法来判断.
4:必须在session关闭之前使用集合对象,否则报错:no session.
save方法:
由One方来维护外键关系,所以得发额外的两条SQL:
在保存对象的时候,因为对象的关系由one方维护,所以,在保存many方的时候,不会去修改外键的值;
只能在one方保存完成之后,由one方发送额外的update语句去修改many方的外键的值;
多对一映射
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="com.jie.domain.TAddressCity" table="t_address_city" schema="region">
<id name="id" column="id">
<generator class="native"></generator>
</id>
<property name="code" column="code"/>
<property name="name" column="name"/>
<!--<property name="provinceCode" column="provinceCode"/>-->
<!-- 多对一映射,关系有多方维护 name many方通过哪一个属性找到one方 column 生成外键的列名 -->
<many-to-one name="province" class="com.jie.domain.TAddressProvince" property-ref="code" cascade="all">
<column name="provinceCode"></column>
</many-to-one>
</class>
</hibernate-mapping>
domain类
package com.jie.domain;
public class TAddressCity {
private int id;
private String code;
private String name;
// private String provinceCode;
private TAddressProvince province;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public TAddressProvince getProvince() {
return province;
}
public void setProvince(TAddressProvince province) {
this.province = province;
}
// public String getProvinceCode() {
// return provinceCode;
// }
//
// public void setProvinceCode(String provinceCode) {
// this.provinceCode = provinceCode;
// }
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
TAddressCity that = (TAddressCity) o;
if (id != that.id) return false;
if (code != null ? !code.equals(that.code) : that.code != null) return false;
if (name != null ? !name.equals(that.name) : that.name != null) return false;
//if (provinceCode != null ? !provinceCode.equals(that.provinceCode) : that.provinceCode != null) return false;
return true;
}
@Override
public int hashCode() {
int result = id;
result = 31 * result + (code != null ? code.hashCode() : 0);
result = 31 * result + (name != null ? name.hashCode() : 0);
//result = 31 * result + (provinceCode != null ? provinceCode.hashCode() : 0);
return result;
}
@Override
public String toString() {
return "TAddressCity{" +
"id=" + id +
", code='" + code + '\'' +
", name='" + name + '\'' +
", province=" + province +
'}';
}
}
注释掉与上级有关联的属性,添加上级对象属性,数据库对象的字段修改为允许null
总结:
分析get方法:
1:many方获取one方的时候,使用了延迟加载,生成了代理对象
2:可以使用if-null方式来判断,是否存在one方.
3:得到的one方,必须在session关闭之前实例化(获取非OID属性),否则报错:no session.
分析save方法:
先保存many方再保存one方,会产生额外的SQL,这些SQL是由于持久化对象(many)的脏数据造成的;
查询个别字段
package com.jie;
import com.jie.domain.TAddressProvince;
import com.jie.util.HibernateUtil;
import org.hibernate.Session;
import org.junit.Test;
import java.util.List;
public class Test3 {
@Test
public void toTest(){
Session session= HibernateUtil.getCurrentSession();
//List<Object[]>lists=session.createSQLQuery("select id,name,code from TAddressProvince").list();
List<Object[]>lists=session.createQuery("select id,name,code from TAddressProvince").list();
for (int i=0;i<lists.size();i++){
Object[]obj=lists.get(i);
System.out.println(obj[0]+" : "+obj[1]+" : "+obj[2]);
}
List<TAddressProvince>plists=session.createQuery("select new TAddressProvince( id,name,code) from TAddressProvince").list();
for (int i=0;i<plists.size();i++){
System.out.println(plists.get(i).getId()+" : "+plists.get(i).getName()+" : "+plists.get(i).getCode());
}
HibernateUtil.closeSession(session);
}
}
还没有评论,来说两句吧...