Hibernate知识宝库

来源:互联网 发布:人大 网络教育二学位 编辑:程序博客网 时间:2024/05/20 19:32

 

Hibernate知识宝库

 

hibernate3

参考书

javaweb程序设计与项目实践》古乐声

版本说明

hibernate3.3.2为例

下载地址

http://sourceforge.net/projects/hibernate/files/hibernate3/hibernate4的下载把3换成4

项目配置步骤

以下以纯手工方式描述(可脱离MyEclipseEclipseIDE),使用数据库管理系统是mySQL

一.引入jar

1Hibernate的必备jar包;(application则用classpath引入,web程序则放入\WEB-INF\lib

1)核心包:Hibernate3.jar

2lib\required下的6jar包:

antlr-2.7.6.jar

commons-collections-3.1.jar

dom4j-1.6.1.jar

javassist-3.9.0.GA.jar

jta-1.1.jar

slf4j-api-1.5.8.jar (slf4j的包来配合才能起作用)

3slf4j-nop-1.5.8.jar(来自http://www.slf4j.org/,版本要和lib\required下的slf4j-api-1.5.8.jar数字匹配);

2、数据库驱动jar包;(application则用classpath引入,web程序则放入\WEB-INF\lib

mySQL驱动包mysql-connector-java-5.0.8-bin.jar

 

二.创建Hibernate配置文件(application则放入src目录,web程序则放入\WEB-INF\classes

    (这里主要举XML文件的方式,其它方式见后文。)

XML文件:hibernate.cfg.xml;(这是习惯文件名。DTD为:hibernate-configuration-3.0.dtd。)

主要是在根节点<hibernate-configuration>下的唯一一个子节点<session-factory>下配置数据库。

 

三.创建会话工厂类(该工厂类用于获得一个Session对象。每个线程对应唯一的Session对象。线程安全),使用者可以不关心会话工厂类内部细节,只管使用。

 

插件Myeclipse可以辅助生成会话工厂类文件HibernateSessionFactory

如果用注释@配置实体-关系映射,则会话工厂类为AnnotationSessionFactory,内部代码细微区别。

如果脱离MyEclipse等插件,则需手工拷贝一份会话工厂类文件来用。

 

四、创建持久化类。(POJO类,成员变量都是private的,具有publicgetterXXX/setterXXX方法)

 

五、创建“对象-关系”映射文件。

1)对象-关系映射文件名:持久化类名.hbm.xml

(与持久化类同目录。DTD文件为:hibernate-mapping-3.0.dtd。)

根节点<hibernate-mapping><class>节点指定了持久化类。

2)在hibernate.cfg.xml添加<mapping resource=”映射文件路径” />(注:必须在property后)

 

 (如果是用注释Annotation的方案,则不需要映射文件,且在hibernate.cfg.xml中添加的形式为<mapping class=”持久化类路径” />

 

至此时,已形成了4者关联:数据库—hibernate.cfg.xml—映射文件持久化类。

 

六、操作数据库

调用会话工厂类来先得到Session,再用该Sessionorg.hibernate.Session)来操作数据。写数据时需要用到Transactionorg.hibernate.Transaction)。

备注

1.hibernate.cfg.xml文件中<property name=”show_sql”>false</property>设置了在进行持久化操作时,是否会将相应的SQL语句输出到控制台。

2. hibernate的数据库输出日志为log4j,可以设置是否在控制台输出,与log4j.property文件有关。最好将logforj配置上。这样方便调试。

3.

有的工具能:自动根据映射文件(持久化类)生成表的功能,

有的工具能:根据表自动生成“持久化类”和“映射文件”。如MyEclipseDBBrowser视图

配置文件相关说明

配置hibernate的方案

法一:使用文件hibernate.cfg.xml:一个文件只能配置一个数据库连接信息

      若使用其它文件名,则在HibernateSessionFactory类中相应设置。

法二:使用资源文件“*.property”。已过时。

法三:动态配置,用一个类的configuration对象来配置,调用多个setProperty(“”,””)方法。

配置“对象-关系”映射(文件)

法一:使用文件“持久化类名.hbm.xml

法二:使用JDK5.0后推出的注释技术Annotations

注释实体类:@Entity@Table

注释实体类标识:@Id@GeneratedValue@GenericdValue@GenericGenerator

注释实体类非标识:@Column

关联关系下的映射配置

一、

 

 

 

 

多、

示例

“学生”实体与“班级”实体的关系。“学生”为“多”方,“班级”为“一”方。一个“班级”实体对应了多个“学生”实体。一个“学生”实体最多能对应一个“班级”实体。

具体测试结果见http://ryxxlong.iteye.com/category/98071中相关文章

数据表定义

建表方式:将“一”方的主键做为“多”方表定义的外键。

create table student (

       studentID int(11) not null auto_increment ,

       studentName  varchar(10) default NULL,

       classID int(11) default NULL,

       PRIMARY KEY(studentID),

       FOREIGN KEY(classID) references classes(classID)

);

 

create table classes(

       classID  int(11) not null auto_increment ,

       className  varchar(30) default NULL,

       PRIMARY KEY(classID)

);

以“多”方为主控方

实体类定义

public class Student {                  //学生类

       private int studentID;            //学生编号

       private String studentName;   //学生姓名

       private Classes myClass;              //学生班级

}

映射文件定义

<hibernate-mapping>

<class name="com.sanqing.po.Student" table="student">

       <id name="studentID">

              <generator class="identity"></generator>

       </id>

       <property name="studentName"></property>

 

      <many-to-one name="myClass" column="classID"

             class="com.sanqing.po.Classes" cascade="all" outer-join="true"/>

</class> 

</hibernate-mapping>

以“一”方为主控方

实体类定义

public class Classes {                  //班级类

       private int classID;               //班级编号

       private String className;      //班级名称

       private Set<Student> students;//班级中的所有学生

}

映射文件定义

<hibernate-mapping>

       <class name="com.sanqing.po.Classes" table="classes">

              <id name="classID">

                     <generator class="identity"></generator>

              </id>

              <property name="className"></property>

              <set name="students" cascade="all" lazy="true">

                    <key column="classID"></key>          <!-- 配置外键 -->

                    <one-to-many class="com.sanqing.po.Student"/><!-- 配置关联类 -->

             </set>

       </class> 

</hibernate-mapping>

示例

“人”实体与“身份证”实体的关系。一个“人”只有一个“身份证”,一个“身份证”只能对应一个“人”。

具体测试结果见http://ryxxlong.iteye.com/category/98071中相关文章

数据表定义

建表方式:将其中一方表的主键做为另一方表定义的外键,并将该外键也设置为具有“唯一”的特性。

两方均可做主控方。

 

create table person (

       id int(11) not null auto_increment ,

       personName  varchar(20) default NULL,

       cardID int(11) default NULL,

       PRIMARY KEY(id),

      unique cardID(cardID),

      FOREIGN KEY(cardID) references card(id)

);

 

create table card(

       id  int(11) not null auto_increment ,

       cardNO  varchar(18) default NULL,

       PRIMARY KEY(id)

);

实体类定义

public class Person {                   //

       private int id;          //编号(自动编号)

       private String personName;   //姓名

       private Card card;                 //身份证号码

}

 

public class Card {        //身份证

       private int id;          //编号

       private String cardNO;//身份证号码

       private String place;//身份证发放地

       private Person person;//所属人

}

映射文件定义

<hibernate-mapping>

       <class name="com.sanqing.po.Person" table="person">

              <id name="id">

                     <generator class="identity"></generator>

              </id>

              <property name="personName"></property>

               <!--配置一对一映射关系,一个人对应一个身份证信息-->

              <one-to-one name="card"

                    class="com.sanqing.po.Card" cascade="all" unique="true"/>     

       </class>

</hibernate-mapping>

 

<hibernate-mapping>

       <class name="com.sanqing.po.Card" table="card">

              <id name="id">

                     <generator class="identity"></generator>

              </id>

              <property name="place"></property>          <!--配置place属性 -->

              <property name="cardNO"></property>      <!--配置cardNO属性 -->

              <one-to-one name="person" property-ref="card"></one-to-one>

       </class> 

</hibernate-mapping>

在被控方可以不用配置<one-to-one>标签。

多对多

多对多实际上最终会转换成一对多、多对一关系。比如选课这件事情,与“学生”、“课程”相关。学生与课程本是多对多的关系,但处理方式是定义“选课”实体:(编号、学生、课程),“选课”与“学生”是“多对一”的关系,“选课”与“课程”也是“多对一”的关系。

操作数据库的常用代码常用格式。

 

主要区分用于“写”和“读”的代码的区别

写(增、删、改)数据的常用格式举例,写数据必须考虑事务性:

import org.hibernate.Session;

import org.hibernate.Transaction;

import com.sanqing.hibernate.HibernateSessionFactory;

…...

Session s=HibernateSessionFactory.getSession();//获得Session对象

Transaction  t = null;                  //声明一个事务对象

try{

       t=s.beginTransaction();  //开启事务

       s.save(持久化对象变量名);  //写入数据

       t.commit();            //提交事务

}

catch(Exception e){

       e.printStackTrace();

       t.rollback();           //事务回滚

}

 

HibernateSessionFactory.closeSession();//关闭Session对象

…...

读(查询)数据的常用格式举例(本例的持久化类是Student),读数据可以不考虑事务性:

import java.util.Iterator;

import java.util.List;

import org.hibernate.Query;

import org.hibernate.Session;

 

import com.sanqing.hibernate.HibernateSessionFactory;

import com.sanqing.po.Student;

 

public class QueryTest {

       public static void main(String[] args) {

              Session session =HibernateSessionFactory.getSession();// 获得Session对象

              Query query =session.createQuery

(“from Student as stu where stu.subject = ‘大学英语’ and stu.result >= 60”);//查询student

              List list =query.list();// 查询结果保存到list

              Iterator iter = list.iterator();//获得list的内部迭代器

              Student stu = null;

              System.out.println(“学号\t\t姓名\t科目\t成绩”);

              while (iter.hasNext()) { //遍历list

                     stu = (Student) iter.next();

                     System.out.println(stu.getId() + "\t" + stu.getName() + "\t"

                                   + stu.getSubject() + "\t" + stu.getResult());

              }

              HibernateSessionFactory.closeSession();// 关闭Session对象

       }

}

Session的一些方法(更多的方法见相关文档)

1.持久化(写入):save()saveOrUpdate()

将内存对象写入到数据库记录去。推荐saveOrUpdate()

2.刷新:refresh()

比对数据库记录和内存对象,以数据库记录为准来刷新内存对象。

3.更新:update():比对数据库记录和内存对象,以内存对象为准去修正数据库记录。

可能后续需要调用flash()以使更新生效,但不一定必须调用flash()。这与更新模式FlushMode有关。可以setFlushMode(FlushMode常量)FlushMode的常量有MANUALCOMMITAUTOALWAYS

比如一旦某内存对象是某session从数据库中装载得到的,如果此时FlushMode等于AUTO,此后,如果修改了内存对象,当提交事务时Transaction.commit()session会自动调用flash()。要注意区分FlushMode等于不同值所起到的效果。

4.装载:load()get()

从数据库记录读出,并创建内存对象。Serializable标识Id作为选择记录的依据。推荐get()

5.比较:isDirty()

比对数据库记录和内存对象是否一致,返回truefalse。涉与session有关的所有当前内存对象。

6.删除:delete()

将内存对象对应的数据库记录删除。

标准查询API

需利用org.hibernate.Criteria接口。

步骤是:

1Criteria c=session.creatCriteria(类类型)可创建Criteria接口对象。

2Criterialist()方法可以得到查询结果。

3、后续处理。

(注:session.creatCriteria(类类型)的参数是类,说明hibernate会自行找到对应的表)

Criteria支持的设置有:

1、设置最大记录数setMaxResults()

2、设置条件add(Criterion);条件甚至支持通配符或MatchMode模糊)

Criterion接口代表一些条件约束。具体可用如Restrictions类的静态方法得到实现了Criterion的对象)

3、设置Order类来定制排序规则。

HQL查询

需利用org.hibernate.Query接口。

步骤是:

1Query query = session.createQuery(字符串)可创建Query接口对象。

2Querylist()方法可以得到查询结果。

3、后续处理。

(注:字符串如果是“from名字”的形式,则名字是实体类名,list()返回值将是list<类名>;否则是sql语句,list()返回值将是list<Object[]>

 

原创粉丝点击