工作中遇到的问题及解决办法18(hibernate)

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>
 

你可能感兴趣的:(工作,.net,Hibernate,xml)