hibernate核心,一对多,多对多映射讲解,看了就完全搞明白了
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
inverse是“反转”的意思,表示关联关系的控制权。 为true,表示由对方负责关联关系的添加和删除; 执行了delete语句, 为false,表示由自己负责维护关联关系。 删除成功
• 在many一方删除数据的正确做法:
Baidu Nhomakorabea
在many一方删除数据2
– 给配置文件中set属性增加inverse属性,设为 只执行super.del即可将数据 false 从数据库中删除 但为了保持对象模型和数据库 (由many一方负责维护关联) 数据一致,还要调用 // 在对象模型中删除关系 qx.getJds().remove(jd);先从 Jd jd = (Jd)super.get(Jd.class,366); – 程序代码: 对象模型中删除 Qx qx = (Qx)super.get(Qx.class,19);
双向一对多关联
• 现希望通过qx.getJds()即可获得该区县下所 有街道的信息。如何配置映射信息?
<!-- Qx类映射文件 - -> <class name="Qx" table="TBL_QX"> <id name="qxid" column="qxid" type="long"> <generator class="native" /> </id> <property name="qxname" column="qx" public class Qx { type="string" /> private Integer qxid; <set name="jds" > 在Qx实体类中, private String <key column="qxid" /> 增加jds属性 qxname; <one-to-many class="Jd" /> private Set jds = </set> new HashSet(); </class> 在Qx映射文件中增加 // Getters & Setters ... set/one-to-many配置 }
• 增加山南区下属的三个街道:“和平路” 、“八一路”和“五四大道”
在many一方删除数据1
• 删除“五四大道”
inverse设为true,由many一方删除 从one一方去“删除”, Hibernate只是执行了 问题出在配置文件上 update语句。还是未删 没有配置set节点的inverse属性 除成功! 根本没有执行 Delete语句,数据 没有被删除!
qx.getJds().remove(jd); // 在数据库中删除数据 super.del(Jd.class,366); //BaseHibernateDAO中del方法代码 Transaction tx = null; try { tx = session.beginTransaction(); session.delete(this.get(clazz,id)); tx.commit(); } catch (RuntimeException re) { tx.rollback(); throw re; }
• 代码
自动执行了级联删除
小结
• 在租房系统中,房屋信息(Fwxx)与用户( User)是多对一关系;房屋信息(Fwxx)与 街道(Jd)是多对一关系。
请完成下面的方法,完成添加“房屋信息” 记录到数据库的功能。
/** * 新建房屋信息记录 * @param title 房屋信息标题 * @param fwxx 房屋信息内容 * @param userId 用户ID * @param jdId 街道ID */ public void post(String title,String fwxx,int userId,int jdId){ //TODO:完成这个方法。 }
双向一对多关联
• 测试程序
Qx qx = (Qx)super.get(Qx.class,1); System.out.println(qx.getQxname()); Iterator it = qx.getJds().iterator(); while (it.hasNext()) { Jd jd = (Jd)it.next(); System.out.print(jd.getJdname() + " "); 现在我们在“区县”(一)和“街道” } (多)两方面都添加了关联,获得了 双向一对多的配置 可以只在一的一方配置,从而得到单 向一对多关联
修改关联关系
• 划“和平路”到海淀区
首先对对象模型编码 然后个更新hepinglu(通过 inverse属性设定的控制方)
执行了update语句
在one一方删除数据
• 删除山南区
• 删除山南区应级联删除下属的区县
super.del(365,Jd.class); super.del(19,Qx.class); 先删除对应子表数据, 删除成功!
第六章
Hibernate的关联映射
回顾
下面这个异常是怎么回事?该怎么解决?
org.hibernate.MappingException: Unknown entity: com.aptech.jb.entity.TblUser at org.hibernate.impl.SessionFactoryImpl.getEntityPersister (SessionFactoryImpl.java:514) at org.hibernate.event.def.DefaultLoadEventListener.onLoad (DefaultLoadEventListener.java:66) at org.hibernate.impl.SessionImpl.fireLoad(SessionImpl.java:862) at org.hibernate.impl.SessionImpl.get(SessionImpl.java:799) at com.aptech.jb.dao.hibimpl.TblUserDAO.findById(TblUserDAO.java:52) at com.aptech.jb.Test.main(Test.java:13) 没有在Hibernate.cfg.xml加 <mapping resource="com/aptech/jb/entity/TblUser.hbm.xml" />
如果many一方数据过多,代码繁琐 通过配置set节点cascade属性可 实现自动级联删除 执行了delete语句,但违反 外键约束,删除失败
在one一方删除数据
• set节点之cascade属性
– all : 对所有操作都进行级联 – none : 对所有操作都不进行级联 – save-update : 执行更新操作时级联 – delete : 执行删除操作时级联
单向多对一关联
• 建立测试类,继承自BaseHibernateDAO
public class ManyToOneTest extends BaseHibernateDAO { public static void main(String[] args) { new ManyToOneTest().testManyToOne(); } 通过配置many-toone节点,加载街public void testManyToOne() { Jd jd = (Jd)super.get(Jd.class,1); 道(多)信息时, String qxname = jd.getQx().getQxname(); Hibernate自动加 System.out.println(qxname + "," + 载了对应的区县 jd.getJdname()); (一)信息 } } 通过映射关系的配置即 获得了在代码中面向对 象编程的便利性!
回顾
• 下面代码有哪些错误?
Transaction tx = null; Session session = HibernateSessionFactory.getSession(); try { tx = session.beginTransaction(); 没有session.open()方法 session.open(); 应该是session.save(item); session.save(item); session.insert(item); session.close(); 关闭session应在finally块中 tx.commit(); 进行 } catch (Exception e) { tx.rollback(); e.printStackTrace(); 应该先提交事务,再关闭 session }
小结
• 在租房系统中,房屋信息(Fwxx)与用户 (User)间也是多对一关系。如何配置映 射文件,使之可以通过下面的代码输出房 屋信息和发布该信息的用户名称? Fwxx fwxx = (Fwxx)super.get(Fwxx.class,1);
System.out.println( fwxx.getTitle() + "," + fwxx.getUser.getUname());
预习检查
1、举一个一对多关联的例子 2、举一个多对一关联的例子 3、举一个多对多关联的例子 4、使用Hibernate配置关联有什 么好处?
本章任务
使用Hibernate实现:
配置Hibernate关联自动加载区县对应的街道 配置Hibernate关联并实现:
1、增加一个区县:“山南区” 2、增加山南区下属的三个街道 3、删除“五四大道” 4、划“和平路”到海淀区 5、删除山南区
双向一对多关联
在配置好双向一对多后,如何实现下列 功能?
1、增加一个区县:“山南区” 2、增加山南区下属的三个街道:“和平路” 、“八一路”和“五四大道” 3、删除“五四大道” 4、划“和平路”到海淀区 5、删除山南区
在one一方添加数据
• 增加一个区县:山南区
添加成功!
在many一方添加数据
– 配置Hibernate多对多关联,实现某OA系统项 目和人员对照关系的管理
本章目标
• 掌握单向many-to-one关联 • 掌握双向one-to-many关联 • 掌握many-to-many关联
实体间的关联
• 单向多对一
tblJd.getQx().getQxname();
• 单向一对多
TblJd jd = (TblJd)tblQx.getJds().get(0); jd.getJdname(); tblQx.getJds.add(jd);
实体间的关联
• 双向一对多
怎样将实体一对多关系映射到数据库?
• 关系模型
单向多对一关联
多对一关系 • 定义“区县” 、“街道”实体如下:
映射文件:
public class Jd { public class Qx { private Integer jdid; private Integer qxid; private String jdname; private String qxname; private Qx qx; // Getters & Setters ... // Getters & Setters ... } <!-- Jd映射文件 - -> } <class name="Jd" table="TBL_JD"> <id name="jdid" column="jdid" type="long"> <generator class="identity" /> <!-- Qx类映射文件 - -> </id> <class name="Qx" table="TBL_QX"> <property name="jdname" column="jd" type="s <id name="qxid" column="qxid" type="long"> class="Qx" column=" <many-to-one name="qx" <generator class="native" /> </class> 只在many一方 </id> 配置了关联 <property name="qxname" column="qx" type="string" /> </class>