07年7月26日
关于hibenrate,两年前的开发中用到过,没想到再用hibernate开发是两年后的今天,这阵子用hibernate开发
把以前没有用到的地方全用了,认识也深入了。
那么,这阵子的开发应该做个总结了,从一些基础的知识开始总结,比看书快。
来说一个基础全面的表关系
student表
stuId(主键)
classId
fileId
class表
classId(主键)
lesson表
lesId(主键)
file表(档案表)
fileId(主键)
stu2les表(学生和课程的关联表)
id(主键)
stuId
lesId
恩。。。这些就足够了,来说说表之间的关系:
学生表和档案表是一对一的关系(每个学生只能有一个档案,一个档案只能对应一个学生)
学生表和班级表是多对一的关系(一个班级可以有多个学生,每个学生只属于一个班级)
所以,班级表和学生表就是一对多的关系了,哈哈哈哈(为了把多对一关系记录下来,学生和班级做个双向关联)
学生表和课程表是多对多的关系(每个学生有多门功课,一门功课可以属于多个学生)
学生表和课程表是多对多,所以做了一张stu2les表(学生和课程的关联表),因为多对多配置
和在程序里的实现不是太可取,用的不是很多,所以这样来搞吧,多对多我也会做总结
学生表和关联表之间一对多
课程和关联表之间是一对多
关于O/R映射:
(1)一对一映射(学生表和档案表)
有两种情况:
一种是这两张表共享一个主键,即stuId,但是上面这个例子中显然不是共享主键这种情况
另有一种是这两张表外键关联的,上面的例子是外键关联的这种情况
看看PO和配置文件
Student.java
public class Student implements java.io.Serializable
{
private Integer stuId; //学生主键
private Class class; //班级对象
private File file; //档案对象
private Set stu2lesSet = new HashSet();
生成getter/setter方法
}
看映射关系通过这个类就可以看出来,学生和档案是一对一,所以档案在学生类里只定义对象
学生和班级是多对一关系,这个“一”对应的就是班级对象了
学生和关联表的关系是一对多,这个“多”对应的就是关联表的Set集合了
再看看Student.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.hibernate.po.Student" table="Student" schema="dbo" catalog="Mytest">
<id name="stuId" type="integer">
<column name="stuId" />
<generator class="native" />
</id>
<property name="stuName" type="string">
<column name="stuName" length="50" />
</property>
<one-to-one
name="file"
class="com.hibernate.po.File" />
<many-to-one
name="class"
class="com.hibernate.po.Class"
column="classId"/> <!--这里体现出学生和班级的关系是多对一,通过学生表里的classId字段关联的-->
<set name="stu2lesSet" table="Stu2les" cascade="save-update" inverse="true" lazy="true">
<key column="stuId" />
<one-to-many class="com.hibernate.po.Stu2les" />
</set>
</class>
</hibernate-mapping>
上面这个配置文件中蓝色的代码很有必要说一下了,当我开发的时候,服务器上有两个数据库,这两个库的内容完全一样,一个叫Mytest,另一个叫Mytestpub这样两个库,当我的数据库连接从Mytest变成Mytestpub库的时候,发现连的还是Mytest数据库,查了一下,原来就是上面配置文件中蓝色代码搞的鬼,当把上面的蓝色代码去掉,就好了.蓝色的代码指定了配置文件必须和蓝色代码里规定的数据库连接,无论连接怎么变,它都会去找你指定的数据库里相应的表.
Class.java
public class Class implements java.io.Serializable
{
private Integer classId;
private String className;
private Set studentSet = new HashSet(); //学生集合
生成getter/setter方法
}
因为班级和学生是一对多,这个“多”就是学生的集合了
再看看配置文件
Class.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.hibernate.po.Class" table="Class" >
<id name="classId" type="integer">
<column name="classId" />
<generator class="native" />
</id>
<property name="className" type="string">
<column name="className" length="50" />
</property>
<set name="studentSet" table="Student" cascade="save-update" inverse="true" lazy="true">
<key column="classId" />
<one-to-many class="com.hibernate.po.Student" />
</set>
</class>
</hibernate-mapping>
<key column="" />总是和本身类的主键id对应
<column="" />总是和关联类的主键id对应
说说inverse="true" 这个属性,一般出现在双向关联里
出现位置是在Set标签里,以它所在的配置文件为主表,而不是以它所在的Set标签里对应的那个表为主表
File.java
public class Class implements java.io.Serializable
{
private Integer fileId; //档案Id
private String fileName; //档案名称
private Student student; //学生对象
生成getter/setter方法
}
再来看看配置文件
File.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.hibernate.po.File" table="File" >
<id name="fileId" type="integer">
<column name="fileId" />
<generator class="native" />
</id>
<property name="fileName" type="string">
<column name="fileName" length="50" />
</property>
<many-to-one
name="class"
class="com.hibernate.po.Student"
unique="true" <!-- 唯一的多对一,实际上也就变成了一对一了-->
column="stuId"/>
</class>
</hibernate-mapping>
unique="true"这个属性说明它是多对一关联的特例("多"这一方只有一个对象).
Lesson.java
public class Lesson implements java.io.Serializable
{
private lesId;
private lesName;
private Set stu2lesSet = new HashSet();
生成getter/setter方法
}
课程和关联表是一对多,这个“多”对应着关联表的集合,所以用Set集合
再来看看配置文件
Lesson.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.hibernate.po.Lesson" table="Lesson" >
<id name="lesId" type="integer">
<column name="lesId" />
<generator class="native" />
</id>
<property name="lesName" type="string">
<column name="lesName" length="50" />
</property>
<set name="stu2lesSet" table="Stu2les" cascade="save-update" inverse="true" lazy="true">
<key column="lesId" />
<one-to-many class="com.hibernate.po.Stu2les" />
</set>
</class>
</hibernate-mapping>
学生表和课程表的关联表
Stu2les.java
public class Stu2les implements java.io.Serializable
{
private Integer id; 此表的主键
private Integer stuId;
private Integer lesId;
生成getter/setter方法
}
再看看配置文件
Stu2les.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.hibernate.po.Stu2les" table="Stu2les" >
<id name="id" type="integer">
<column name="id" />
<generator class="native" />
</id>
<property name="stuId" type="integer">
<column name="stuId" />
</property>
<property name="lesId" type="integer">
<column name="lesId" />
</property>
</class>
</hibernate-mapping>