|
小弟从美河提供的免费视频上学到了不少东西,但是有一些技术细节,可能因为篇幅原因不能详细描述,我根据自己实际经验所得,进行了一些补充,适合像我这样的菜鸟互相学习,高手就不要看了, 呵呵
1)
springDAO更新指定字段:
在DAO层,更新的对象不要用new,而使用hibernateTemplate().load();
例如,传进来一个对象,该对象保存了N个字段,但不是持久化对象的所有字段
如果直接用HibernateTemplate().savaorUpdate(instanse)的话,会将其他未set的字段设置为null
如何使用数据库的默认值呢?
例:加入一个Student对象,有name,age,sex三个属性,从高层传过来的student对象只设置了name和age两个属性
如果直接在dao层update的话,显然sex属性会被null覆盖
public void reStudent(Student student){
HibernateTemplate ht = this.getHibernateTemplate();
Student stu = ht.load(Student.Class,student.getID());//ht.load(p1,p2)参数p2是student表的主属性
stu.setName(student.getName());
stu.setAge(student.getAge());//未设置sex属性
ht.flush();//changes to studnet are automatically detected and persisted
ht.savaOrUpdate(stu);
}
这时update了stu对象后,未设置的属性保持DB原来的值
2)
使用hibernate的延迟加载策略
hibernate3以后,默认使用延迟加载策略
如果多对一查询的时候,设置不使用延迟加载,可以直接读子属性的属性
例如,student---〉drom,学生对宿舍是典型的一对多
lazy=“false”以后,查询学生信息,可以直接读取宿舍的信息
但是如果遇到多对一查询,设置不使用延迟加载,也不能读取到子属性
如宿舍--〉学生就是一对多的关系,不使用延迟加载也不能读取学生的信息(主属性除外)
如果想根据宿舍查找学生信息,可以用以下方式:
public LIst getStudentWithDrom(){
List studentList = this.getHibernateTemplate().find("from Drom");
Iterator it = list.iterator();//使用跌带器
while(it.hasNext()){
Drom drom = (Drom)it.next();
if(!Hibernate.isInitialized(drom.getStudents())){
session.refresh(drom);//一定要刷新drom的session
Hibernate.initialize(drom.getStudend());//强制加载
}
}
return studentList();
}
注意:如果你使用的是微软的SQLserver2000,而且使用微软提供的驱动(就是那三个包),仍然会抛出session关闭的异常,这是由于该驱动不支持二次查找所
致,不妨试试由sourceforge提供的jtds,需要如下配置:
<bean id="dataSource"
class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName"
value="net.sourceforge.jtds.jdbc.Driver">
</property>
<property name="url"
value="jdbc:jtds:sqlserver://localhost:1433/数据库名字">
</property>
<property name="username" value="用户名"></property>
<property name="password" value="密码"></property>
</bean>
3)
分散式DAO
有这样一种需求,业务层有一个类,封装了有关学生的一切操作,例如学生基本信息操作,学生宿舍信息操作
实现具体操作使用的是dao的数据访问接口IStudentDAO,该接口描述了学生相关的所有操作
而在DAO层实现该接口的是两个不同的DAO,studentDAO和dromDAO,连个DAO分别实现了该接口IStudentDAO
我自己管这种模式叫做“分散式DAO”
在studentDAO实现了学生相关的数据操作,而在dromDAO实现了宿舍的相关数据操作,假设在业务层,需要一个功能“为学
生安排宿舍”,该功能要求:
1.为学生安排宿舍以后,该学生的宿舍属性为目标宿舍。
2.每安排一名学生进入宿舍,该宿舍的入住人数+1。(解决这一问题还有一种方法就是将studentsSet.size()插入“现在居住人数”,但是此方法需要对学
生二次查询,为了这样一个小需求进行二次查询显然不划算)
3.为学生选择的宿舍必须和学生性别一致,不能将男生安排到女生宿舍,反之相同
4.为学生选择的宿舍必须是未住满的宿舍,例如drom有8个床位,现有8个人居住,就不能将第九个人安排到该宿舍
这个功能需要对两个实体都进行操作,而两个DAO又实现了同一个接口,需要在两个DAO里面都分别实现所有的描述,这时,业务层怎么知道调用的是学生DAO
的方法还是宿舍DAO的方法?
这时就需要用的java一“得以技”--“upcasting”
在业务层这样使用接口:
private IStudentDAO studentDAO = new StudentDAO();
private IStudentDAO studentDromDAO = new DromDAO();
这时需要对宿舍的操作就使用studentDromDAO,对学生的操作就使用studentDAO,例如:
public getOkDrom(Student student){ //获取合适的宿舍,操作对象:Drom
studentDAO.getOkDrom(Studnet studnet);
}
public studentIntoDrom(Student student,Drom drom){ //安排学生宿舍,操作对象Student,Drom
Student stu = new Student();
Drom dro = new Drom();
dro.setId(drom.getId());
dro.setNowPerson(drom.getNowPerson()-1);
stu.setId(student.getId());
stu.setDrom(dro);
studentDAO.reStudent(stu);//DAO具体实现注意1)
studentDromDAO.reDrom(dro);//DAO具体实现注意1)
}
[ 本帖最后由 djhyoo 于 2007-8-29 00:36 编辑 ] |
评分
-
1
查看全部评分
-
|