zoukankan      html  css  js  c++  java
  • Hibernate学习笔记

    一、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检索方式等等,以后有时间在写学习笔记。

  • 相关阅读:
    证明最大公约数Stein算法(高精度算法)
    链表常用内容和易犯错误
    斐波那契数列——各种公式证明
    用矩阵和待定系数法求数列的分析(复杂度log(n))
    盒模型(外边距)
    盒子模型(内边距)
    盒子模型(边框)
    jupyterhub
    1分钟k线图能反映什么?(转)
    python的self
  • 原文地址:https://www.cnblogs.com/aston/p/4888585.html
Copyright © 2011-2022 走看看