暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Hibernate入门篇

Java笔记录 2019-03-03
392
Hibernate入门篇


ORM简述


今天开始学习Hibernate框架,在学习之前先了解下什么是ORM?

ORM,全称为Object Relational Mapping,利用面向对象编程思想都是为了把对象的信息存进关系型数据库中,所以要写很多底层SQL语句,但是不同的数据库SQL语句又有不同,所以为了解决面向对象与关系数据库不匹配的问题提出了ORM技术,使用ORM技术可以完全摒弃SQL语句,充分利用面向对象进行编程。


什么是Hibernate?


Hibernate是一个关系型映射框架,对JDBC进行了非常轻量级的封装,其实底层还是使用JDBC来进行与数据库交互,Hibernate可以自动的生成SQL语句,并自动的执行,因此Hibernate是作为MVC模式中的数据持久层,并且Hibernate还开放源代码,把软件开发人员从数据持久层的工作中解放出来,避免了重复编写繁琐的SQL语句。


Hibernate语言特点


1、将对数据库的操作转换为对Java对象的操作,从而简化开发。通过修改一个“持久化”对象的属性从而修改数据库表中对应的记录数据。

2、提供线程和进程两个级别的缓存提升应用程序性能。

3、有丰富的映射方式将Java对象之间的关系转换为数据库表之间的关系。

4、屏蔽不同数据库实现之间的差异。在Hibernate中只需要通过“方言”的形式指定当前使用的数据库,就可以根据底层数据库的实际情况生成适合的SQL语句。

5、非侵入式:Hibernate不要求持久化类实现任何接口或继承任何类,POJO即可。


使用IDEA实现第一个Hibernate例子


1、引入jar包,或者在创建Hibernate工程的时候勾选下载,jar包可以去官网上下载,引入lib目录下required中的所有包,注意要引入数据库驱动包。



2、创建一个数据库,不用创建表


3、创建一个持久化的Student类


package com.demo.model;

public class Student {

    private int id;
    private String username;
    private String password;
    private int age;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}


4、创建Hibernate配置文件,在src目录下


<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD//EN"
        "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory>
        <property name="connection.url">jdbc:mysql://localhost:3306/hibernate1</property>
        <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="connection.username">root</property>
        <property name="connection.password">ForMe=520</property>

        <!-- 指定在控制台打印生成的Sql语句 -->
        <property name="show_sql">true</property>

        <!-- 指定使用mysql数据库中的SQL语句格式-->
        <property name="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</property>

        <!-- 指定是否自动生成数据库表 -->
        <property name="hbm2ddl.auto">update</property>

        <!-- 表示为每个线程生成一个session 必须要加上这一句否则会出错-->
        <property name="current_session_context_class">thread</property>
        <!-- 引入对象-关系映射文件 -->
        <mapping resource="com/demo/model/student.hbm.xml"/>
    </session-factory>
</hibernate-configuration>



注意:Hibernate配置文件的创建是由固定格式的,如上所示,每个property代表着不同的含义。


5、创建对象--关系映射文件,要和持久化的类在同一包下。


<?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 package="com.demo.model" >
    <!--类名、表名-->
    <class name="com.demo.model.Student" table="stu">
        <id name="id" type="int">
            <!--column表示列名-->
            <column name="id"/>
            <generator class="identity"/>
        </id>
        <property name="username" type="java.lang.String">
            <column name="username"/>
        </property>
        <property name="password" type="java.lang.String">
            <column name="password"/>
        </property>
        <property name="age" type="int">
            <column name="age"/>
        </property>
    </class>
</hibernate-mapping>


对映射文件的各个属性进行分析


id:定义了该属性到数据库表主键字段的映射。

type:指定该标识属性的数据类型,该类型可以是

Hibernate的内建类型,也可以是java类型,如果是java类型则需要使用全限定类名(带包名)。该属性可选,如果没有指定类型, 则hibernate自行判断该标识属性数据类型。通常建议设定。

name="userId":标识属性的名字;

column="userId":表主键字段的名字,如果不填写与

name一样;


对generator进行解释:


class的取值可以有下面几种

1、increment 

increment: 对 long , short 或 int 的数据列生成自动增长主键。 主键按数值顺序递增,存在并发问题


2、identity 

对如 SQL server , MySQL 等支持自动增长列的数据库。


3、seqhilo 

对如 Oracle , DB2 等支持 Sequence 的数据库,

oracle自增长是序列化的形式。


4、uuid: 

对字符串列的数据采用 128-位 uuid 算法生成唯一的字符串主键。


5、native  

自增长,会根据底层数据库自增长的方式选择identity或

sequence

如果是mysql数据库, 采用的自增长方式是identity

如果是oracle数据库, 使用sequence序列的方式实现自增长


6、assigned 

主键由外部程序负责生成,无需Hibernate参与


7、foreign 

使用外部表的字段作为主键。


<property>:为类定义一个持久化的javaBean风格的属性。

            name="name":标识属性的名字,以小写字母开头;

            column="name":表主键字段的名字,如果不填写与name一样;

            update="true"/insert="true":默认为true,表示可以被更新或插入;

            access="property/field":指定Hibernate访问持久化类属性的方式。默认property。property表示使用setter/getter方式。field表示运用java反射机制直接访问类的属性。


6、创建HibernateUtils工具类


package com.demo.utils;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.Nullable;

public class HibernateUtils {

    private static SessionFactory sessionFactory = null;

    static{
        Configuration configuration = new Configuration().configure();
        sessionFactory = configuration.buildSessionFactory();
    }

    @Nullable
    public static Session getSession(){
        return (sessionFactory != null)?sessionFactory.openSession():null;
    }

    @Contract(pure = true)
    public static SessionFactory getSessionFactory(){
        return sessionFactory;
    }

    public static void closeSession(Session sess){
        if(sess != null)
            if(sess.isOpen())
                sess.close();
    }

}


7、利用HibernateUtils工具类进行CRUD


package com.demo.tests;

import com.demo.model.Student;
import com.demo.utils.HibernateUtils;
import org.hibernate.Session;

public class HibernateTest1 {

    public static void main(String[] args) {
        //   createTest();
        //       updateTest();
        //       retrieveTest();
       //        deleteTest();
    }

    public static void createTest(){

        Session session = HibernateUtils.getSession();
        session.beginTransaction();
        Student student = new Student();
        student.setId(11);
        student.setUsername("李四");
        student.setPassword("798233");
        student.setAge(17);

        session.save(student);
        session.getTransaction().commit();
        HibernateUtils.closeSession(session);
    }

    public static void updateTest(){
        Session session = HibernateUtils.getSession();
        session.beginTransaction();
        Student student = session.load(Student.class,2);
        student.setAge(19);
        student.setPassword("412435");
        session.getTransaction().commit();
        HibernateUtils.closeSession(session);
    }

    public static void retrieveTest(){
        Session session = HibernateUtils.getSession();
        session.beginTransaction();
        Student student = session.load(Student.class,new Integer(1));
        System.out.println("年龄:" + student.getAge() + " 姓名:" + student.getUsername()
         + " 密码:" + student.getPassword());
        session.getTransaction().commit();
    }

    public static void deleteTest(){
        Session session = HibernateUtils.getSession();
        session.beginTransaction();
        Student student = session.load(Student.class,new Integer(4));
        session.delete(student);
        session.getTransaction().commit();
    }
}


用到的类和方法详解


1、先看下HibernateUtils中的类Configuration类,是Hibernate的入口,操作的是主配置文件(hibernate.cfg.xml或者是hibernate.properties)。


2、Configuration类的configure()方法


configure()方法用于加载配置文件

加载主配置文件的方法有两种

如果指定参数,那么加载参数的路径配置文件

如果不指定参数,默认加载src/目录下的

hibernate.cfg.xml 


3、SessionFactory


SessionFactory用到了工厂模式,用户程序从工厂类SessionFactory中取得Session的实例,是重量级的,在一个项目中最好只存在一个SessionFactory,可以在整个应用程序中共享,SessionFactory在Hibernate中实际上起到了一个缓冲区的作用 他缓冲了HIbernate自动生成SQL语句和其他的映射数据 还缓冲了一些将来有可能重复利用的数据。


4、buildSessionFactory()方法


用于创建session工厂


5、SessionFactory.openSession()方法


用于创建session对象


6、Session


上面介绍了这么多关于session的类和方法,那么什么是

session呢?它的功能又是什么呢?

Session的主要功能是为映射的实体类的实例提供增删改查操作。


● 保存对象到数据库 session.save(Object obj);


● 保存对象到数据库 session.persist(Object obj); 


● 数据更新,session.update(Object obj);


● 更新或者保存,session.saveOrUpdate(Object  user);

本方法当有主键的时候,执行更新,没有设置主键的时候执行的是保存。


● 主键查询


//两者都可用于主键查询
//Student student = session.get(Student.class,2);
Student student = session.load(Student.class,2);



beginTransaction()方法,开启事务


最后总结一下Hibernate的执行流程如下图



Hibernate实体对象的三种状态

Hibernate是基于实体对象的操作,也就是说把实体对象与数据库表一一对应起来,通过操作实体对象来进行改变数据库中的数据。而是对对象在Hibernate中有三种存在状态,分别为:瞬时状态、持久化状态和游离状态。


瞬时状态(Tranisent)


通过new创建出来的对象,与Hibernate没有关系,不在Hibernate的缓存中,此时的状态为瞬时状态,此时如果对象不再被其他对象调用,将会被垃圾处理机制回收。


持久化状态(Persistent)


对象与session关联,此对象就处在持久化状态,处于持久化状态的对象拥有数据库标识(也就是主键)。对象与

session相互关联的方式有两种:

第一种就是调用get或者load方法从数据库加载对象;第二种就是瞬时状态的对象调用save方法或者

SaveOrUpdate方法时,对象处于持久化的状态Hibernate会选择时机将变更固化到数据库中。


游离状态(Detached)


当Session进行了close()、clear()、evict()或flush()后,实体对象从持久态变成游离态。


三种实体化状态的相互转换


画一个草图简单理解




总结:
Hibernate的入门就是这些,能理解创建Hibernate的步骤和流程,掌握配置文件的使用和Hibernate的执行流程。



文章转载自Java笔记录,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论