Hibernate介绍

  1. Hibernate介绍
  2. 是什么
    1. 是一个持久层框架(与数据库保持同步数据的 jdbc mybatis)
    2. 基于orm思想的框架
    3. 是对jdbc 的非常轻量级封装
    4. 有什么特性(与jdbc对比)
    5. jdbc 加载驱动 获取连接 写sql 执行sql 把获取的数据手动封装起来
  3. hibernate
    1. 加载【配置文件(加载驱动 获取连接)
    2. 写hql =hinernate sql 他最终也是要转换成sql 执行,把手动转封装起来了,不需要手动转化,全自动的,所以开发的效率更高,但是效率比jdbc慢
    3. 都是跨平台的
  4. 怎么融进项目
    1. 导入jar包
    2. hibernate所需要的驱动包
    3. 加载配置文件
    4. ibernate.cfg.xml
    5. 驱动 连接 用户名 密码 方言(跨平台)
    6. sql 显示 sql格式化 反向生成表 c3p0
    7. xxx.hbm.xml
    8. 映射实体
    9. 5大核心类

ORM(Object/Relation Mapping): 对象/关系映射

ORM 主要解决对象-关系的映射

ORM的思想:将关系数据库中表中的记录映射成为对象,以对象的形式展现,程序员可以把对数据库的操作转化为对对象的操作。

ORM 采用元数据来描述对象-关系映射细节, 元数据通常采用 XML 格式, 并且存放在专门的对象-关系映射文件中.

 

<?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><!-- configuration配置 -->

<session-factory><!-- factory 工厂 --><!-- connection ==session -->

<!-- 加载驱动  获取连接 用户名  密码 方言 -->

<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>

<property name="hibernate.connection.url">jdbc:mysql:///1804</property>

<property name="hibernate.connection.username">root</property>

<property name="hibernate.connection.password">root</property>

<property name="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</property>

 

<!-- 选填项   显示sql 格式化sql 反向生成表-->

<property name="hibernate.show_sql">true</property>

<property name="hibernate.format_sql">true</property>

<!--

create-drop 先创建,再删除

create 先删除,再创建

validate 验证存在,不存在报错

update:存在则操作,不存在则创建

 -->

<property name="hibernate.hbm2ddl.auto">update</property>

<!-- 引进映射文件 -->

<mapping resource="com/mr/hibernate/pojo/User.hbm.xml"/>

<mapping resource="com/mr/hibernate/pojo/Order.hbm.xml"/>

<mapping resource="com/mr/hibernate/pojo/Customer.hbm.xml"/>

</session-factory>

</hibernate-configuration>

什么是Hibernate方言?

Hibernate方言是用来告诉Hibernte如何对指定的数据库生成相应的SQL语句。
尽管做了很多尝试去使SQL语句标准化,但是不同的数据库支持的SQL语句还是有很多不同的地方。
所以Hibernate使用方言来辅助生成正确的SQL语句。

MySQL5Dialect与MySQL5InnoDBDialect有什么区别?

他们最大的区别是,在使用Hibernate创建表时MySQL5InnoDBDialect会在生成的建表SQL语句最后加上"ENGINE=InnoDB"。
InnoDB是一种MySQL数据库引擎.MySQL5.5及之后使用它做为默认引擎。它提供了ACID兼容的事务(Transaction)功能,并提供外键支持。

MySQLDialect与MySQL5Dialect有什么区别?

MySQLDialect是针对MySQL5之前的版本。主要变化还是在于建表SQL语句。
MySQL由于4到5还是有不小的变化。比如varchar在4及之前版本最大长度限制为255,5及之后版本最大长度限制为65535。
MySQLInnoDBDialect会在生成的建表SQL语句最后加上"TYPE=InnoDB"。

 

  1. *.hbm.xml文件;

创建实体

package com.mr.hibernate.pojo;

import java.util.Date;

public class User {

public User(String userName, Date userBir) {

super();

this.userName = userName;

this.userBir = userBir;

}

private Integer userId;

private String userName;

private Date userBir;

public Integer getUserId() {

return userId;

}

public void setUserId(Integer userId) {

this.userId = userId;

}

public String getUserName() {

return userName;

}

public void setUserName(String userName) {

this.userName = userName;

}

public Date getUserBir() {

return userBir;

}

public void setUserBir(Date userBir) {

this.userBir = userBir;

}

@Override

public String toString() {

return "User [userId=" + userId + ", userName=" + userName + ", userBir=" + userBir + "]";

}

public User(Integer userId, String userName, Date userBir) {

super();

this.userId = userId;

this.userName = userName;

this.userBir = userBir;

}

public User() {

super();

}

public User(String userName) {

super();

this.userName = userName;

}

}

创建映射文件:充分体现orm思想 把对象和表关系通过映射的方式联系起来

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

<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"

"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<!-- Generated 2018-6-15 10:32:56 by Hibernate Tools 3.5.0.Final -->

<hibernate-mapping>

<class name="com.mr.hibernate.pojo.User" table="t_user">

<!-- 主键 -->

<id name="userId" column="USER_ID">

<!--

name :属性      column :字段

generator:主键生成策略

native:本地  identity:自增      increment:最大加1       

sequence:序列       foreign:外键      uuid:32位的字符串

 -->

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

</id>

<!--

property:普通属性 :name:属性    column:表字段

 -->

<property name="userName" column="USER_NAME"></property>

<property name="userBir" column="USER_BIR"></property>

</class>

</hibernate-mapping>

Configuration类:加载配置文件的类

SessionFactory:会话工厂用来创建session

Session:会话 用来连接数据库,相当于jdbc中的connection

Transaction:事务,用来开启和提交回滚事务

Query:查询,用来查询数据

Hibernate主键生成策略

1.sequence  标识符生成器利用底层数据库提供的序列来生成标识符.

由于 sequence 生成标识符的机制依赖于底层数据库系统的序列, 因此, 要求底层数据库系统必须支持序列. 支持序列的数据库包括: DB2, Oracle 等

OID 必须为 long, int 或 short 类型, 如果把 OID 定义为 byte 类型, 在运行时会抛出异常

2. increment  每次从数据库中查询出最大的 id  然后 +1 

由于 increment 生存标识符机制不依赖于底层数据库系统, 因此它适合所有的数据库系统,适用于只有单个 Hibernate 应用进程访问同一个数据库的场合, 在集群环境下不推荐使用它,OID 必须为 long, int 或 short 类型, 如果把 OID 定义为 byte 类型, 在运行时会抛出异常

3. native ( 本地的 ) 把主键生成策略交给数据库管理 不同的数据库有不同的主键生成策略

    适用与 mysql 和 oracle 数据库 mysql 在使用时 必须设定主键自增策略,oracle 在使用时 如果不指定具体的 sequence ,会使用 Hibernate 默认的序列 Hibernate_seq

  1. uuid

生成一个 32 位的随机字符串 该字符串基本不会出现重复,机器码 + 纳秒 +  生成一个唯一不重复的字符串

5.foreign

一般用于一对一对应关系 ,子表没有自己的 id ,子表使用主表的 id

6 identity mysql 主键自增

由于 identity 生成标识符的机制依赖于底层数据库系统, 因此, 要求底层数据库系统必须支持自动增长字段类型. 支持自动增长字段类型的数据库包括: DB2, Mysql, MSSQLServer, Sybase 等

OID 必须为 long, int 或 short 类型, 如果把 OID 定义为 byte 类型, 在运行时会抛出异常

 

 

  • 常用方法

1.保存对象到数据库 session.save(Object user); 

2.返回值为生成的主键id。

3.数据更新,session.update(Object user);update

4.更新或者保存,session.saveOrUpdate(Object  user);   有id则更新,没有id,则保存

5.删除操作,session.delete(Object user);

6.查询操作,session.get(Class clazz, Serializable id);

7.查询操作,session.load(Class theClass, Serializable id);

8.强制同步数据到数据库,session.flush();

9.同步数据库中数据到java对象,session.refresh(Object user);

10.查询 createQuery("from User");

11.查询 createSqlQuery("select * from t_user");

12.关闭 close();

13.ession中get() load()区别

  1.  get与load区别

get() 为立即加载,调用方法就会打印查询sql语句;

load() 为懒加载 ,调用方法时不会打印 sql语句,只有在调用的时候,才会打印;

b)从查询结果对比

get()查询不到数据,返回null ;

load():查询不到数据则抛异常org.hibernate.ObjectNotFoundException;

Hibernate对象状态

 

  1. Hibernate 把对象分为 4 种状态:

1.临时状态(Transient):在使用代理主键的情况下, OID 通常为 null,不处于 Session 的缓存中,在数据库中没有对应的记录  。例如:临时工,没有编号,不在公司编制里面;

2.持久化状态(也叫”托管”)(Persist):

OID 不为 null ,位于 Session 缓存中,若在数据库中已经有和其对应的记录, 持久化对象和数据库中的相关记录对应,Session 在 flush 缓存时, 会根据持久化对象的属性变化, 来同步更新数据库

在同一个 Session 实例的缓存中, 数据库表中的每条记录只对应唯一的持久化对象,例如上班之后;有编号,也在公司编制里面了;

3.游离状态(也叫”脱管”) (Detached):

OID 不为 null,不再处于 Session 缓存中,一般情况需下, 游离对象是由持久化对象转变过来的, 因此在数据库中可能还存在与它对应的记录,例如:你请假了;

4.删除状态(Removed)

在数据库中没有和其 OID 对应的记录,不再处于 Session 缓存中

一般情况下, 应用程序不该再使用被删除的对象,例如,你被开除了

四种状态的转换

 

  • 缓存
    • 什么是缓存hibernate一共有三级缓存

缓存就是数据交换的缓冲区(称作Cache),当某一硬件要读取数据时,会首先从缓存中查找需要的数据,如果找到了则直接执行,找不到的话则从内存中找。由于缓存的运行速度比内存快得多,故缓存的作用就是帮助硬件更快地运行。缓存是指可以进行高速数据交换的存储器,它先于内存CPU交换数据,因此速率很快。

  1. 测试session一级缓存

/**

 * session的状态

 * 瞬时态 没有oid

 * 持久态 有oid  和数据库同步 === session 的缓存

 * 游离态  有oid 和数据库不同步

 * 删除态 没有oid

 */

@Test

public void test() {

// 临时状态(Transient):

User user = new User();

user.setUserName("瞬时态");

System.out.println(user);

 

// 持久化状态(也叫”托管”)(Persist):

Serializable oid = session.save(user);

user.setUserName("持久态");

System.out.println(user);

transaction.commit();

session.close();

 

// 游离状态(也叫”脱管”) (Detached):session 关闭或者session 清除

user.setUserName("游离状态");

System.out.println(user);

 

// 删除状态(Removed)

session.delete(user);

}

 

 

通过结果可以看出:从sql上看 两次查询只打印了一次select语句;

从时间上看:缓存的读取速度明显要高于从数据库中的速度

原理:因为第二次查询的时候会先去查看缓存中是否存在该对象,如果缓存中存在该对象,直接从缓存中进行获取,如果缓存中不存在,才去数据库进行查询,

作用:缓存的存在有效的减少了对数据库的访问次数;有效减少时间,提高用户体验度减少程序的压力

  1. 二级缓存

SessionFactory 的缓存可以分为两类:

内置缓存: Hibernate 自带的, 不可卸载. 通常在 Hibernate 的初始化阶段, Hibernate 会把映射元数据和预定义的 SQL 语句放到 SessionFactory 的缓存中, 映射元数据是映射文件中数据(.hbm.xml 文件中的数据)的复制. 该内置缓存是只读的.

外置缓存(二级缓存): 一个可配置的缓存插件. 在默认情况下, SessionFactory 不会启用这个缓存插件. 外置缓存中的数据是数据库数据的复制, 外置缓存的物理介质可以是内存或硬盘

适合放入二级缓存中的数据:

–很少被修改

–不是很重要的数据, 允许出现偶尔的并发问题

-高并发 ,访问次数多的

不适合放入二级缓存中的数据:

–经常被修改

–财务数据, 绝对不允许出现并发问题

–与其他应用程序共享的数据

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值