分享
 
 
 

我的 O/R Mapping 之旅(三)

王朝java/jsp·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

在本部分中,才真正开始对 AUTO_INFO 和 PEOPLE 表进行操作。

要让 Hibernate 跑起来,还要了解其中几个关键对象:

net.sf.hibernate.cfg.Configuration 的实例负责管理 Hibernate 配置信息,比如数据库连接、数据库 dialect,还有最重要的映射文件初始化工作。

程序为了得到 Session 实例,必须先要得到它的工厂 net.sf.hibernate.SessionFactory,SessionFactory 的实例由 Configuration 构造。

net.sf.hibernate.Session 是一切数据库操作的基础,和 JDBC 的 Connection 意义一样,Session 实例由 SessionFactory 获得。

net.sf.hibernate.Transaction 的实例由 Session 获得。Hibernate 不具备事务管理能力,Hibernate 将其委托给底层的 JDBC 或者 JTA,以实现事务管理和调度功能。在本文中使用 JDBC 事务管理。

把以上的知识串起来吧:

Configuration cfg = new Configuration().configure();

SessionFactory sessions = cfg.buildSessionFactory();

Session session = sessions.openSession();

Transaction tx = session.beginTransaction();

程序第一幕马上出场。

有位叫张三的人,他买了辆车。由于是第一次买车,进入车辆管理系统后要对AUTO_INFO 和 PEOPLE 表都进行 insert 操作。

形成的一对多(one-to-many)关系保存如下:

package com.dao;

import java.util.*;

import net.sf.hibernate.*;

import net.sf.hibernate.cfg.*;

import bo.*;

public class Test {

List list;

AutoInfo ai=new AutoInfo();

People people=new People();

public void DoTest() {

try {

Configuration cfg = new Configuration().configure();

SessionFactory sessions = cfg.buildSessionFactory();

Session session = sessions.openSession();

Transaction tx = session.beginTransaction();

people.setAddress("中国");

people.setName("张三");

people.addToAutoInfoSet(ai);

ai.setLicensePlate("A00001");

ai.setOwnerNo(people);

session.save(people);

tx.commit();

session.close();

} catch (Exception e) {

System.out.println(e);

}

}

}

分别设置好 AutoInfo、People 对象属性后,调用 Session.save() 方法保存,然后事务提交,最后关闭 Session。好了,看看数据库吧,一切都已保存好了。

程序第二幕出场。

张三后来做生意,自己经营得很好,打算再买辆车跑运输。对于第二次买车,车辆管理系统的 PEOPLE 表原本已经记录了他的基本信息,遂不对 PEOPLE 表操作。只向 AUTO_INFO表 insert 一条车辆记录即可。

形成的一对多(one-to-many)关系保存如下:

package com.dao;

import java.util.*;

import net.sf.hibernate.*;

import net.sf.hibernate.cfg.*;

import bo.*;

public class Test {

List list;

AutoInfo ai = new AutoInfo();

People people = new People();

public void DoTest() {

try {

Configuration cfg = new Configuration().configure();

SessionFactory sessions = cfg.buildSessionFactory();

Session session = sessions.openSession();

Transaction tx = session.beginTransaction();

people =

(People) session

.find(

"from People where OWNER_ID=1")

.get(0);

ai.setLicensePlate("A00002");

ai.setOwnerNo(people);

people.getAutoInfoSet().add(ai);

session.save(people);

tx.commit();

session.close();

} catch (Exception e) {

System.out.println(e);

}

}

}

session.find() 方法返回一个 List 接口的实例,里面封装着 PO,其中的 “from People where OWNER_ID=1” 就是大名鼎鼎的 HQL(Hibernate Query Language) 了,是不是很像 SQL 呢?PEOPLE 表和 AUTO_INFO 表存在一对多关系,也就需要 People 对象来持有多个 AutoInfo 对象(以 Set 接口的实例封装,参看People类源代码),再通过 people.getAutoInfoSet().add(ai) 为 AUTO_INFO 表添加一条新纪录。好了,执行完以后,再检查数据库吧。

这段代码

people = (People) session.find("from People where OWNER_ID=1").get(0);

可以和

people =(People) session.load(People.class,new Integer(1));

互换。在本例中 List 接口实例 size() 为 1,即其中只有一个 PO;而 session.load() 是根据持久对象和主键来返回相应 PO,也只是单个。所以这两种方式返回的都是相同 PO。采用哪种方式由你决定。

到这里,也许你会有这样的想法:“应该可以直接向 AUTO_INFO 表插入记录,不通过 People 对象中转,像写 SQL 一样 Easy。” 错了!以前直接写 SQL 是可以办到的,不过现在我们用的可是 Hibernate ,一切都要以对象行事,看见 ai.setOwnerNo(people) 了吗?传入参数是个 People 对象实例,不是简单的字段喔。

程序第三幕出场。

呵呵,这个第三幕是最简单的了,第一种一对多(one-to-many)的查询:

package com.dao;

import java.util.*;

import net.sf.hibernate.*;

import net.sf.hibernate.cfg.*;

import bo.*;

public class Test {

List list;

AutoInfo ai = new AutoInfo();

People people = new People();

public void DoTest() {

try {

Configuration cfg = new Configuration().configure();

SessionFactory sessions = cfg.buildSessionFactory();

Session session = sessions.openSession();

List list =

session.find(

"select ai from AutoInfo as ai where ai.OwnerNo.Id=1");

for (int i = 0; i < list.size(); i++) {

ai=(AutoInfo)list.get(i);

System.out.println(ai.getLicensePlate());

people=ai.getOwnerNo();

System.out.println(people.getName());

System.out.println(people.getAddress());

}

session.close();

} catch (Exception e) {

System.out.println(e);

}

}

}

到了年底,查查张三一共有多少辆车。”select ai from AutoInfo as ai where ai.OwnerNo.Id=1”,这句 HQL 要找的是 AutoInfo 对象,而传统 SQL 这么写:“select p.name,p.address,ai.license_plate from people p,auto_info ai where p.owner_id=1”。由于 AUTO_INFO 表是“many”表,而 PEOPLE 表是“one”表,我的做法是以“many”表为基础返回它的多个 PO,其中再持有“one”表的信息。“ai.OwnerNo.Id=1”就是说通过主键参数为“1”的 PEOPLE 表记录来取出相应 AUTO_INFO 表记录。

对于一对多(one-to-many)关系,还有第二种查询方式:

package com.dao;

import java.util.*;

import net.sf.hibernate.*;

import net.sf.hibernate.cfg.*;

import bo.*;

public class Test {

AutoInfo ai = new AutoInfo();

People people = new People();

public void DoTest() {

try {

Configuration cfg = new Configuration().configure();

SessionFactory sessions = cfg.buildSessionFactory();

Session session = sessions.openSession();

people = (People) session.load(People.class, new Integer(1));

Iterator iterator = people.getAutoInfoSet().iterator();

System.out.println(people.getName());

System.out.println(people.getAddress());

while (iterator.hasNext()) {

ai = (AutoInfo) iterator.next();

System.out.println(ai.getLicensePlate());

}

session.close();

} catch (Exception e) {

System.out.println(e);

}

}

}

people = (People) session.load(People.class, new Integer(1)) 取出单个 People 对象,其中持有以 Set 封装的若干 AutoInfo 对象实例,Iterator iterator = people.getAutoInfoSet().iterator() 把 Set 立即转化为 Iterator ,最后用 while (iterator.hasNext()) 循环取出其中的车牌号码。

第一种一对多(one-to-many)的查询实际上我把它转换成了多对一(many -to- one)的查询。这种转换后有两个缺点:一、由 HQL 转为 SQL 输出时,打印的 SQL 条数多于直接一对多(one-to-many)关系查询;二、其中的 People 对象存在着大量冗余(只需要一个实例,结果取出了 List.size() 个相同的实例)。我们知道,数据库的性能是有限的,构造对象的代价是高昂的,所以应尽量减少不必要的性能开销。

虽然我个人不建议把一对多(one-to-many)查询转换成多对一(many -to- one)查询,但事实上有些开发团队却乐意采用,即使他们知道性能有略微的降低。在还没有更深入研究之前,各位看官有何看法呢?

(请注意!引用、转贴本文应注明原作者:Rosen Jiang 以及出处:http://blog.csdn.net/rosen

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有