欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Hibernate框架之快速入门

程序员文章站 2024-03-23 13:07:52
...

Hibernate框架介绍

Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,它将POJO与数据库表建立映射关系,是一个全自动的orm框架,hibernate可以自动生成SQL语句,自动执行,使得Java程序员可以随心所欲的使用对象编程思维来操纵数据库。 Hibernate可以应用在任何使用JDBC的场合,既可以在Java的客户端程序使用,也可以在Servlet/JSP的Web应用中使用,最具革命意义的是,Hibernate可以在应用EJB的J2EE架构中取代CMP,完成数据持久化的重任。

从度娘的介绍,我们可以看出:Hibernate是对JDBC进行封装的一个轻量级的框架,底层是使用JDBC来对数据库表进行交互操作。也就是说,我们可以使用Hibernate来完成原来JDBC与数据库表的交互操作。Hibernate是在Dao层使用的框架。

Hibernate的核心接口一共有6个,分别为:Session、SessionFactory、Transaction、Query、Criteria和Configuration。 

ORM介绍

对象关系映射(Object-Relational Mapping)提供了概念性的、易于理解的模型化数据的方法。ORM方法论基于三个核心原则: 简单:以最基本的形式建模数据。 传达性:数据库结构被任何人都能理解的语言文档化。 精确性:基于数据模型创建正确标准化的结构。 典型地,建模者通过收集来自那些熟悉应用程序但不熟练的数据建模者的人的信息开发信息模型。建模者必须能够用非技术企业专家可以理解的术语在概念层次上与数据结构进行通讯。建模者也必须能以简单的单元分析信息,对样本数据进行处理。ORM专门被设计为改进这种联系。

简单说:ORM是对象与数据库表的映射,是对象的属性与数据表的字段的映射。

 

Hibernate简单了解

1、持久化对象和标识符

(1)持久化类:配置完关系后,操作的实体对应的类,成为持久化类 (Customer)
(2)持久化类标识符(oid:object id)
(3)持久化类主键的生成策略

<id name="cust_id">
            <generator class="native"></generator>        
        </id>

      generator的class属性的取值:
           数据库底层生成主键:
               identity:底层以自增的方式生成主键 例如mysql
               sequence:底层以序列方式生成主键 例如oracle
               native:根据数据库底层的主键生成策略自动选用identity还是sequence (使用最多)
           hibernate生成主键:
               increment:自增
               uuid:生成不重复的字符串        
           手动指定主键:
               assigned
           代理主键:没有实际业务意义的字段
           自然主键:可以具备主键的要求(唯一不空) 与此同时还具备业务意义(身份证、手机号、学号....)

2、hibernate持久化对象的三种状态和一级缓存

(1)持久化对象的三种状态(了解)
        瞬时态:实体没有oid 也与session没有关联
        持久态:实体有oid 与session有关联 (重点),持久态对象具备自动发送sql的能力
        脱管态:实体有oid 与session失去关联
        
        代码演示:

Session session = HibernateUtils.openSession();
Transaction transaction = session.beginTransaction();
Customer customer = new Customer(); //瞬时态
customer.setCust_name("jd"); //瞬时态
System.out.println(customer); //瞬时态
session.save(customer); //执行完毕后 持久态
System.out.println(customer); //持久态
transaction.commit(); //持久态
session.close(); //脱管态
System.out.println(customer);  //脱管态

   (2)hibernate的一级缓存(重点)
        hibernate存在两级缓存:
            一级缓存:hibernate的内置缓存,session级别的缓存
            二级缓存:hibernate的外置缓存,sessionFactory级别缓存(不学)  redis
            
        验证一级缓存是存在的?        

Session session = HibernateUtils.openSession();
Transaction transaction = session.beginTransaction();
//查询对象
Customer customer = session.get(Customer.class, 4L);//发送sql查询数据 封装Customer 将customer缓存在session中
Customer customer2 = session.get(Customer.class, 4L);//从session获取4号customer
System.out.println(customer);
System.out.println(customer2);
transaction.commit(); 
session.close();

3、事务

(1)事务的特性ACID
        原子性:事务是数据库操作最小单位 不可再分割
        一致性:同时成功或同时失败
        隔离性:多个事务互不影响的
        持久性:当事务提交 数据就会被持久化到磁盘上
    
(2)并发操作出现的问题
        脏读:A事务读取到B事务尚未提交的数据(最不安全的 开发中必须要避免的)
        不可重复读:一个事务中多次读取数据的内容不一致
        虚读/幻读:一个事务中多次读取数据的条数不一致
        
(3)设置数据库的隔离级别(isolation)解决并发问题
        read uncommitted: 都不能解决  没人用
        read committed:解决脏读    oracle的默认隔离级别
        repeatabel read:解决不可重复读和脏读     mysql的默认隔离级别
        serializable:都能解决  性能很低
        
(4)hibernate与事务相关的配置
       1)session与线程绑定
            作用:业务层使用session控制事务  dao层使用同一个session进行实体操作
            <property name="hibernate.current_session_context_class">thread</property>
            
        2)hibernate可以配置隔离级别

<property name="hibernate.connection.isolation">1/2/4/8</property>

            read uncommitted: 1
            read committed:2
            repeatabel read:4
            serializable:8

4、ibernate的查询操作(5种查询方式)
    1、oid方式 --- get/load方法
    2、对象导航方式
    3、HQL方式(Hibernate Query Language) --- 面向对象+结构化查询   (重点)
    4、QBC方式(Query By Criteria) --- 完全面向对象的(api)
    5、SQL方式 --- 通过sql语句查询

Hibernate快速入门五部曲

1、搭建环境(导入Hibernate的jar包)

(1)Hibernate必须的包:

Hibernate框架之快速入门

(2)日志记录包:

Hibernate框架之快速入门

(3)驱动包:

Hibernate框架之快速入门

(4)Hibernate的日志配置文件(一般放到src下):

Hibernate框架之快速入门

2、创建实体类和数据库表(cst_customer为例,需要生产get、set方法

实体类结构:

    private long cust_id;//客户编号(主键)
    private String cust_name;//客户名称(公司名称)
    private String cust_source;//客户信息来源
    private String cust_industry;//客户所属行业
    private String cust_level;//客户级别
    private String cust_phone;//固定电话
    private String cust_mobile;//移动电话

数据库表:

CREATE TABLE `cst_customer` (
  `cust_id` bigint(32) NOT NULL AUTO_INCREMENT COMMENT '客户编号(主键)',
  `cust_name` varchar(32) NOT NULL COMMENT '客户名称(公司名称)',
  `cust_source` varchar(32) DEFAULT NULL COMMENT '客户信息来源',
  `cust_industry` varchar(32) DEFAULT NULL COMMENT '客户所属行业',
  `cust_level` varchar(32) DEFAULT NULL COMMENT '客户级别',
  `cust_phone` varchar(64) DEFAULT NULL COMMENT '固定电话',
  `cust_mobile` varchar(16) DEFAULT NULL COMMENT '移动电话',
  PRIMARY KEY (`cust_id`)
) ENGINE=InnoDB AUTO_INCREMENT=15 DEFAULT CHARSET=utf8;

3、编写映射配置文件(配置实体与表的关系)

创建xml文件 该文件的命名约定 实体名.hbm.xml

<?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>
    <!-- 配置实体与表的关系
		name: 要映射的实体的全限定名
		table: 要映射的表的名称
	-->
    <class name="com.itheima.domain.Customer" table="cst_customer">
        <!-- 配置实体的属性和表的字段的关系
			在hibenrate中id具备特殊地位  修改、删除等默认都是根据id执行的
				id标签
					name:实体中的id的属性名称
					column:表中的id的字段名称
				主语:不管是id还是普通属性  当实体的属性名称 与 表的字段名称 一致时 此时column可以省略
		-->
        <id name="cust_id" column="cust_id">
            <generator class="native"></generator>
        </id>
        <!-- 配置普通属性
		    name:实体中的属性名称
			column:表中的字段名称
		-->
        <property name="cust_name" column="cust_name"></property>
        <property name="cust_source" column="cust_source"></property>
        <property name="cust_industry" column="cust_industry"></property>
        <property name="cust_level" column="cust_level"></property>
        <property name="cust_phone" column="cust_phone"></property>
        <property name="cust_mobile" column="cust_mobile"></property>
    </class>
</hibernate-mapping>

4、编写主配置文件(配置数据源的信息)

配置hibernate的核心文件,在src下创建 hibernate.cfg.xml文件
           约束:/org/hibernate/hibernate-configuration-3.0.dtd
           配置的name查看hibernate.properties  位置:hibernate-release-5.0.7.Final\project\etc\hiebernate.properties

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

<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">

<hibernate-configuration>
    <!--
		session工厂:造session对象
		session对象:会话对象 hibernate与数据库的连接对象

		session工厂内部需要配置三部分内容
			1、数据源信息
			2、hibernate其他配置参数
			3、加载映射关系
	-->
    <session-factory>
        <!--数据源信息:JDBC连接数据库的四个基本配置参数-->
        <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="hibernate.connection.url">jdbc:mysql:///hibernate</property>
        <property name="hibernate.connection.username">root</property>
        <property name="hibernate.connection.password">root</property>
        <!--
            hibernate的其他配置参数:我一般配置四个参数
                (方言、控制台显示SQL语句、格式化显示SQL语句、ddl策略)
         -->
        <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
        <property name="hibernate.show_sql">true</property>
        <property name="hibernate.format_sql">true</property>
        <property name="hibernate.hbm2ddl.auto">update</property>
        <!--加载映射-->
        <mapping resource="com/itheima/domain/Customer.hbm.xml"/>
    </session-factory>
</hibernate-configuration>

5、测试(操作实体类)

public class HibernateTest {

    @Test
    public void test(){
        //通过工具类获得session工厂
        Session session = HibernateUtils.openSession();
        //开启事务
        Transaction transaction = session.beginTransaction();

        //操作实体类
        Customer customer = new Customer();
        customer.setCust_name("阿里巴巴");
        //保存
        session.save(customer);

        //提交
        transaction.commit();
        //释放资源
        HibernateUtils.close(session);
    }
}

在这里,我将获得session工厂的操作提取成一个简单的工具类:

public class HibernateUtils {
    
    private static Configuration configuration = null;
    private static SessionFactory sessionFactory = null;

    static {
        //创建配置对象,加载路径下(src)hibernate.cfg.xml文件
        configuration = new Configuration().configure();
        //通过配置对象 去构建session工厂(session工厂的创建下需要使用到hibernate的核心配置文件)
        sessionFactory = configuration.buildSessionFactory();
    }

    public static Session openSession(){
        //通过sesson工厂开启一个新的session
        return sessionFactory.openSession();
    }

    public static void close(Session session){
        if(session!=null){
            session.close();
        }
    }
}