Hibernate学习笔记

时间:2022-08-22 21:43:32

一、Hibernate基础

  1.Hibernate简介

    Hibernate是一种对象关系映射(ORM)框架,是实现持久化存储的一种解决方案。Java包括Java类到数据库表的映射和数据查询及获取的方法,能够大大减少开发人员使用JDK和SQL处理数据的时间。

  2.Hibernate获取

    Hibernate的官网是http://www.hibernate.org,需要的时候可以去官网上下载相关的版本。

  3.Hibernate配置

    在一个项目中有时候不需要Hibernate中的全部jar包,所以当项目用到Hibernate的时候可以将相关jar包复制到项目的classpath/WebContent/WEB-INF/lib下面;或者在项目中建立一个Library加载Hibernate的jar包。

  4.Hibernate配置文件

    Hibernate的配置文件一般命名为hibernate.cfg.xml,这个配置文件默认存储在项目的classpath根目录下。下面以一个具体的配置文件说明hibernate配置文件的相关知识

    <?xml version='1.0' encoding='utf-8'?>   <!-- 这是一个xml文件头,定义版本和编码 -->

    <!DOCTYPE hibernate-configuration PUBLIC

      "_//Hibernate/Hibernate Configuration DTD 3.0//EN"

      "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">   <!-- hibernate独有的,建议写上 -->

    <hibernate-configuration>

      <session-factory>

        <property name="driver_class">com.mysql.jdbc.Driver</property>  <!-- 数据库驱动,这个是MySQL的驱动  请加载你相应数据库的驱动 -->

        <property name="url">jdbc:mysql://localhost:3306/test</property>  <!-- 数据库连接的URL -->

        <property name="username">root</property>  <!-- 数据库连接用户名 -->

        <property name="password">passwd</property>  <!-- 数据库连接密码 -->

        <property name="dialect">org.hibernate.dialect.MySQLDialect</property>  <!-- hibernate方言 -->

        <property name="show_sql">true</property>  <!-- 打印SQL语句 -->

        <mapping resource="com/lyq/User.hbm.xml" />  <!-- 映射文件,可以用这个属性改变映射文件的位置和名称 -->

      </session-factory>

    </hibernate-configuration>

    关于配置文件作如下解释:

      <hibernate-configuration>是配置文件的根元素;

      <session-factory>元素通常只有一个,其包含有多个<property>和<mapping>子元素用来配置Hibernate属性信息;

        <mapping>元素用来配置持久化类映射文件的相对路径;

        <property>元素的常用属性及说明如下:

          connectio.driver_class:设置数据库驱动;

          connection.url:设置数据库连接的URL;

          connection.username:设置连接数据库所使用的用户名;

          connection.password:设置连接数据库所使用的密码;

          dialect:设置连接数据库所使用的Hibernate方言;

          show_sql:是否打印SQL语句;

          format_sql:设置是否对SQL语句进行格式化;

          hbm2ddl.auto:设置自动建表。

  5.Hibernate的核心接口

    Hibernate的核心接口主要有五个:

    (1)Session接口:负责执行被持久化对象的CRUD操作,需要注意的是Session对象是非线程安全的;

    (2)SessionFactory接口:负责初始化Hibernate,他充当数据存储源的代理,并负责创建Session对象;

    (3)Configuration接口:负责配置并启动Hibernate,创建SessionFactory对象;

    (4)Transaction接口:负责事务相关的操作(可选);

    (5)Query接口:负责执行各种数据库查询。

二、持久化对象(数据库对象映射)

  1.持久类的编写

    持久类是Hibernate操作的对象,它与数据库中的数据表相对应,描述数据表的结构信息。下面是一个学生类student.java

    public class Student{

      private String id;  //id编号

      private String name;  //姓名

      private boolean sex;  //性别

      //参数的setter和getter方法

    }

    编写Hibernate的持久类时候需要注意以下几点:声明一个默认的、无参的构造方法;类的声明是非final类型的;拥有一个标识属性;为属性声明getter和setter方法。

  2.映射文件的编写

    Hibernate的映射文件与持久类相互对应,映射文件指定持久类与数据表之间的映射关系。Hibernate的映射文件的命名规则是*.hbm.xml。上面student类的映射文件如下:

    <?xml version="1.0" encoding="UTF-8"?>

    <!DOCTYPE hibernate-mapping PUBLIC

      "_//Hibernate/Hibernate Mapping DTD 3.0//EN"

      "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

    <hibernate-mapping>

      <class name="持久类的全名"  table="数据表名">

        <id name="id" column="id" type="String">

          <generator class="native"></generator>

        </id>

        <property name="name" type="String" not-null="true" length="50">

          <column name="name"></column>

        </property>

        <property name="sex" type="boolean">

          <column name="sex" />

        </property>

      </class>

    </hibernate-mapping>

    关于持久类的映射文件作如下解释:

      <hibernate-mapping>元素是映射文件的根元素,其常用的属性主要是package属性,用来指定包名;

      <class>元素用于指定持久化类和数据表的映射,其属性中的table属性用于指定数据表的名称,name属性指定持久化类的完整类名(包含包名),但是当<hibernate-mapping>中指定package属性时可以不指定包名;上述<class>中包含<id>和<property>,下面分别介绍

        <id>元素对应数据表中的标识,指定持久化类的OID和表主键的映射;<id>通过name属性指定持久化类中的属性,column属性指定数据表中的字段名称,type属性用于指定字段的类型。<id>的子元素<generator>用于配置数据表主键的成长策略,主键生成策略标识如下:

        increment:适用于代理主键,由Hibernate以自增的方式生产,增量为1;

        identity:适用于代理主键,由底层数据库生成,前提是底层数据库支持自增字段类型;

        sequence:适用于代理主键,Hibernate根据底层数据库的序列生成,前提条件是底层数据库支持序列;

        hilo:适用于代理主键;

        native:适用于代理主键,根据底层数据库对自动生成标识符的支持能力,选择identity、sequence和hilo;

        uuid:适用于代理主键,不推荐使用,因为字符串型要比整形占用更多的数据库空间;

        assigned:适用于自然主键,由Java应用程序负责生成;

        <id>的子元素<property>元素描述数据表中字段的属性,用于配置数据表中字段的属性信息,通过此元素能够详细地对数据表的字段进行描述。<property>元素的常用配置属性及说明如下:

        name:指定持久化类中的属性名称;

        column:指定数据表中的字段名称;

        type:指定数据表中的字段类型;

        not-null:指定数据表字段的非空属性,它是一个布尔值;

        length:指定数据表中的字段长度;

        unique:指定数据表字段值是否唯一,它是一个布尔值;

        lazy:设置延迟加载。

  3.映射关系的使用

    持久化对象使用最频繁的操作是增删改查的操作,所以在下文中介绍对映射关系的使用。

三、关联关系映射

  映射在Hibernate中发挥着重大的作用,它将实体对象映射成数据表,实体对象的属性映射成数据表中的字段,另外,实体之间的关联关系也是通过映射实现的。其实关联类型分两种:

  单向关联:具有关联关系的实体对象之间的加载关系是单向的;

  双向关系:具有关联关系的实体对象之间的加载关系是双向的。

  1.一对多的关联关系

    再建一个类class.Java,包含id,classname和student三个变量。如下:

    public class Class {

      private int id;

      private String classname;

      private Ser<Student> studentes;

      //相应的getter和setter方法

    }

    这时,映射文件class.hbm.xml的内容主要部分如下:

    <set name="students">  <!-- Set为我们在class.java中定义的集合 -->

      <key column="id"></key>  <!-- 外键名称 -->

      <one-to-many class="....../student.java" />  <!-- 一对多关系的对应的类,类名的全称 -->

    </set>

    除了Set集合,还有List、Map等集合。映射文件的写法大同小异,如下:

      <!-- 映射集合属性studentes,指定存放集合属性的表明 -->

      <list name="studentes" table="student">

        <!-- 集合属性和持久化类的关联外键 -->

        <key column="id" not-null="true"/>

        <!-- 集合属性的次序列 -->

        <list-index column="list-order"/>

        <!-- 集合属性的元素 -->

        <element type="String" column="name" />

      </list>

      <!-- 映射Map  集合属性 -->

      <map name="student" table="student">

        <key  column="id" not-null="true"/>

        <map-key column="name" type="String"/>

      </map>

  2.多对一的关联关系

    将上面的一对多的关系颠倒过来就是多对一的关联关系了。假设在学生类中加一个班级属性,两个类如下:

      public class student {

        private int id;

        private String name;

        private Stirng sex;

        private Great great;

        //相应的getter和setter方法

      }

      public class Great{

        private int id;

        private String name;

        //相应的getter和setter方法

      }

    在student.hbm.xml里面的主要语句如下:

      <!-- 多对一的映射关系 -->

      <many-to-one name="great" column="great_id"></many-ro-one>

  3.多对多的关联关系

    学生和课程之间就是一个常见的多对多的关系,一个学生可以选多门课、一门课也可以被多个学生选择。假设课程类Course.java如下:

      public class Course{

        private String name;

        private int core;

        private Set<Student> students;

        //相应的getter和setter方法

      }

    这时,应该在student.java中增加一个属性private Set<Course> course;

    student.hbm.xml中的主要配置如下:

      <!-- cascade="save-update"表示在保存和更新当前对象时,级联保存和更新附属对象 -->

      <!-- inverse="true"表示该对象不维护关系(一般由一边来维护,下面会介绍让course维护) -->

      <!-- table="sc_table"表示中间表 -->

      <set name="courses" cascade="save-update" inverse="true" table="sc_table">

        <!-- column为中间表  参照student_table的外键 -->

        <key column="stu_id"  not-null="true"></key>

        <!-- 多对多的关系映射 -->

        <map-to-many  class="Course"  column="cor_id"></map-to-many>

      </set>

    course.hbm.xml中的主要配置如下:

      <!-- 主要这里没有inverse属性,由course这边维护映射关系 -->

      <set name="student" cascade="save-update" table="sc_table">

        <key column="cou_id"  not-null="true"></key>

        <map-to-many class="student" column="stu_id"></map-to-many>

      </set>

四、Hibernate对数据库的操作——增删改查

  1.Hibernate的初始化

    使用Hibernate操作数据库时首先应该创建和初始化Hibernate。

  1.1创建Hibernate——使用SessionFactory

    默认情况下,Hibernate会加载classpath目录下的Hibernate.cfg.xml文件,格式如下:

     Configuration  cfg = new Configuration().configure();

    实例化SessionFactory的代码如下:

     SessionFactory  factory = cfg.buildSessionFactory(new ServiceRegistryBuilder().applySettings(cfg.getProperties()).buildServiceRegistry());

  2.获取session

    代码如下:

     Session  session = (Session)threadLocal.get();

     if( session == null || !session.isOpen() ){

       session = (sessionFactory != null)sessionFactory.openSession() : null;

     }

  3.开启事务

    session.beginTransaction();

    还有一个提交事务:session.getTransaction().commit();

  4.添加数据

    添加数据的语法格式如下:

     public  Serializable  save(Object obj) throws  HibernateException

    比如添加student的代码:session.save(student);

  5.删除数据

    删除数据的语法格式如下:

     public  void  delete(Object obj)  throws  HibernateException

    但是因为要删除的对象并不在Session的管理之中,通过Session并不能对其进行删除操作,所以需要将要删除的对象转换为持久状态,使其处于Session的管理之内,再用上述方法将数据删除。

    比如删除student的代码:

     Student  student = (Student)session.load(Student.class,new Integer(001));

     session.delete(student);

  6.查询数据

    Session接口提供了两个加载数据的方法,即get()和load()方法。这两个方法都可用于加载数据,但是两者之间存在一定的区别。get()方法返回实际对象;load()方法返回对象的代理,只有在被调用时,Hibernate才会发出SQL语句去查询对象。

   6.1 get()方法

     get()方法的语法格式如下:

       public  Object  get(Class  entityClass, Serializable  id)  throws  HibernateExcetion

        其中,entityClass:持久化对象的类;id:标识;返回值:持久化对象或null值。

     例如:Student  student = (Student)session.get(Student.class,new Integer(1));

   6.2 load()方法

     load()方法的语法格式如下:

       public  Object  load(Class  entityClass, Serializable  id)  throws  HibernateException

         各个参数的解释同上。

     例如:Student  student = (Student)session.load(Student.class,new Integer(1));

     当调用Session的load()方法时,Hibernate并不会立刻发出SQL语句进行查询,只有在引用对象时才会发出SQL语句。

  7.修改数据

    Hibernate对数据的修改主要有两种情况:1)当实例对象处于Persistent(持久)状态时,对于它所发生的任何更新操作,Hibernate在更新缓存时都会对其进行自动更新;2)Session接口提供了update()方法,调用此方法可对数据进行手动更新。

   7.1自动更新

     自动更新在操作之前需要加载数据,因为要修改的数据并没有处于Session的管理之内。

     Student  student = (Student)session.load(Student.class,new Integer(1));  //加载Student对象

     student.setName("test");  //修改名称

     session.getTransaction().commit();  //提交事务

   7.2手动更新

     手动更新语法格式如下:

       public  void  update(Object obj)  throws  HibernateException

       例如:

        //手动创建的Detached状态的药品对象

        Student  student = new  Student();

        student.setId(1);

        student.setName("test");

        student.setSex(true);

        //更新student信息

        session.update(student);

        //提交事务

        session.getTransaction().commit();

五、写在最后

  关于Hibernate的基础知识就这些了,或许不够全面,但是根据这些知识足够建立一个Hibernate项目了。

  Hibernate还有些高级应用,例如一级缓存、二级缓存、HQL检索方式等等,以后有时间在写学习笔记。