Hibernate双主键,多表关联操作相关知识
对于web项目一般避免用双主键或者多表关联的操作,但是对于编码人员来说,只要数据库设计师设计了数据库,必须按照数据库的方式进行编码,否则对于数据库维护方面就不太方便。
当然加入了双主键和多表关联的操作后,对于编码人员来说是个痛苦的事情。因为不管在PO的配置文件中还是在VO的action中都不会有一个完美的解决。
现在将我在项目开发中所遇到的关于双主键以及多表关联的操作总结下,希望大家能够一起给出意见:
1. 首先是PO文件的映射,
我想大家都会了吧,但是需要注意的是对于双主键来说,Hibernate会生成一个专门的主键Bean来存放主Bean所对应的主键。例如我的连个表是:
PetInfor(pid(number),itemid(varchar2),petname(varchar2),cateid(number),price(double)……)
Primary Key (pid,itemid)双主键,foreignkey(cateid)外键 关联。
Cate(cateid(number),catename(varchar2),…..)
则由此在po里映射的Bean有三个:Petinfor.java; PetinforId.java; Cate.java;
其中的某些属性:
/*************************petinfor.java*********************/
private PetinforId id;
private Cate cate;
private String name;
private Double norprice;
private Double vipprice;
// Constructors
/** default constructor */
public Petinfor() {
}
/** minimal constructor */
public Petinfor(PetinforId id, String name) {
this.id = id;
this.name = name;
}
/** full constructor */
public Petinfor(PetinforId id, Cate cate, String name, Double norprice,
Double vipprice) {
this.id = id;
this.cate = cate;
this.name = name;
this.norprice = norprice;
this.vipprice = vipprice;
}
/*************************petinforId.java*********************/
private String itemid;
private Long pid;
// Constructors
/** default constructor */
public PetinforId() {
}
/** full constructor */
public PetinforId(String itemid, Long pid) {
this.itemid = itemid;
this.pid = pid;
}
/*************************Cate.java*********************/
这个文件就不啰嗦了在这里。
我们没必要仔细追究Bean文件是怎样生成或使用的,很多人的习惯是将Bean里不符合要求的属性修改,这个习惯非常好,因为对于Hibernate操作而言,数据库设计和文件映射上的属性是不一样的。
有了双主键,是不是多了一个pojo文件呢?不会,主键bean只是作为主键标志而存在,并没有多一个pojo文件,而在配置文件中就关联了复合主键的属性。如下:
<composite-id name="id" class="com.hb.po.PetinforId">
<key-property name="itemid" type="java.lang.String">
<column name="ITEMID" length="10" />
</key-property>
<key-property name="pid" type="java.lang.Long">
<column name="PID" precision="22" scale="0" />
</key-property>
</composite-id>
<many-to-one name="cate" class="com.hb.po.Cate" fetch="select" lazy="false">
<column name="CATEID" precision="22" scale="0" />
</many-to-one>
从配置文件可以看出复合主键的配置方法和多对一映射的配置方法。
在这里要非常注意Hibernate lazy的设置。
Hibernate Lazy 问题, Spring 中引入了 OpenSessionInViewInterceptor, 这样虽然解决了页面上的 Lazy Load 问题,却增加了各层之间的偶合性,
如果一个 Lazy 的 Collection 在页面上可以被正确的 load, 但是如果请求不是来自于 HttpServletRequest (比如在 TestCase 或 Service 中希望获取 lazy 的属性),
一般会导致两种错误:
代码
1. 设置了 lazy = "true"
会导致 org.hibernate.LazyInitializationException: failed to lazily initialize a collection of xxx: xxx - no session or session was closed
2. 设置里 lazy = "false"
会导致 org.hibernate.LazyInitializationException: could not initialize proxy - the owning Session was closed
我这里设置的是lazy=“false”方便将Cate Bean中的相关属性用到工程中。
这个就是PO的相关东西,我会继续将po的相关细化并贴出来共享。下面是其他的操作。
<B style="mso-bidi-font-weight: normal">