一、Hibernate框架的概述

1.1 什么是Hibernate

  • 框架:软件的半成品,完成部分功能代码.
  • Hibernate:Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,使得Java程序员可以随心所欲的使用对象编程思维来操纵数据库。 Hibernate可以应用在任何使用JDBC的场合,既可以在Java的客户端程序使用,也可以在Servlet/JSP的Web应用中使用,最具革命意义的是,Hibernate可以在应用EJB的J2EE架构中取代CMP,完成数据持久化的重任。
  • Hibernate是轻量级JavaEE应用的持久层解决方案,是一个关系数据库ORM框架.
    • ORM:Object Relational Mapping.
    • 将Java中的实体类与数据库的关系表建立一个映射.就可以操作Java中对象,从而操作数据库.
  • 常见的持久层框架
    • Hibernate
    • JPA:JPA Java Persistence API.JPA通过JDK 5.0注解或XML描述对象-关系表的映射关系(只有接口规范)
    • MyBatis:前身Ibatis

1.2 Hibernate优点

  • Hibernate对JDBC访问数据库的代码做了封装,大大简化了数据访问层繁琐的重复性代码
  • Hibernate是一个基于jdbc的主流持久化框架,是一个优秀的orm实现,它很大程度的简化了dao层编码工作
  • Hibernate使用java的反射机制,而不是字节码增强程序类实现透明性
  • Hibernate的性能非常好,因为它是一个轻量级框架。映射的灵活性很出色。它支持很多关系型数据库,从一对一到多对多的各种复杂关系.

二、Hibernate的日志记录

  • 日志:程序开发中的一些信息.
  • 常用信息输出: System.out.println(“”);
    • 这种方式不好
    • 如果输出内容比较多,项目已经开发完毕,不想使用输出.需要打开每个类,将输出的代码注释.
  • 日志:Hibernate中使用slf4j技术.
    • slf4j:SLF4J,即简单日志门面(Simple Logging Facade for Java),不是具体的日志解决方案,它只服务于各种各样的日志系统。
    • 用于整合其他日志系统.
    • 在企业中常用的日志记录:log4j
    • 是具体的日志记录方案.
  • Log4J的日志级别:
    • fatal(致命的)、error(普通错误)、warn(警告)、info(信息)、debug(调试)、trace(堆栈信息).
  • Logger.error(“错误信息”);
  • 通过配置文件的形式,显示错误信息.
  • 配置的级别是info.
  • Log4J的三个组件:

    • 记录器(Loggers)

      • 格式:记录器 = 级别, 输出源1 , 输出源2
      • log4j.rootLogger=info, stdout
    • 输出源(Appenders)
      • log4j.appender.stdout=org.apache.log4j.ConsoleAppender,控制台进行输出.
      • log4j.appender.file=org.apache.log4j.FileAppender,向文件进行输出.
    • 布局(Layouts)
    log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
    log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n

依赖的jar包

<!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-api -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.25</version>
</dependency> <!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-log4j12 -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.25</version>
<scope>test</scope>
</dependency> <!-- https://mvnrepository.com/artifact/log4j/log4j -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>

三、Hibernate 入门程序

3.1 引入依赖(5.x版本)

<!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-core -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.4.2.Final</version>
</dependency>
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.15</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.mchange/c3p0 -->
<dependency>
<groupId>com.mchange</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.5.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-c3p0 -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-c3p0</artifactId>
<version>5.4.2.Final</version>
</dependency>

3.2 创建表(关系型数据库)

create table customer(
id int primary key auto_increment,
name varchar(20),
age int
);

3.3 创建一个实体类

public class Customer {
private int id;
private String name;
private int age;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}

3.4 创建ORM的映射.

  • 映射文件只要是一个XML格式文件就可以.名字任意.

    • 通常情况下名称规范:
    • 实体类名称.hbm.xml

<!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:表名称 -->
<class name="com.hao.entity.Customer" table="customer">
<!-- 建立类中属性与表中的字段映射 -->
<!-- 唯一标识 -->
<!-- 使用id的标签 配置唯一属性 -->
<!-- 在<id>标签中配置一个主键的生成策略. 此处用native 会根据数据库的设置自动选择主键生成策略 -->
<id name="id" column="id">
<generator class="native"/>
</id>
<!-- 普通属性 -->
<!-- property标签:映射类中的普通属性 name:类中的属性名称, column:表中字段名称 -->
<!--
type:三种写法
* Java类型 :java.lang.String
* Hibernate类型 :string
* SQL类型 :不能直接使用type属性,需要子标签<column>
* <column name="name" sql-type="varchar(20)"/>
-->
<property name="name" column="name" type="string"/>
<property name="age" column="age"/>
</class>
</hibernate-mapping>

3.5 创建一个核心配置文件.

<hibernate-configuration>
<session-factory>
<!-- 必须去配置的属性 -->
<!-- 配置数据库连接的基本信息:此处引用了mysql-conn 5.8 最新的连接驱动 -->
<property name="hibernate.connection.driver_class">
com.mysql.cj.jdbc.Driver
</property>
<property name="hibernate.connection.url">
jdbc:mysql:///test
</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">rootroot</property>
<!-- Hibernate的方言 -->
<!-- 生成底层SQL不同的 -->
<property name="hibernate.dialect">
org.hibernate.dialect.MySQLDialect
</property>
<!-- 可选的属性 -->
<!-- 显示SQL -->
<property name="hibernate.show_sql">true</property>
<!-- 格式化SQL -->
<property name="hibernate.format_sql">true</property>
<!-- hbm:映射 to DDL: create drop alter -->
<property name="hibernate.hbm2ddl.auto">update</property> <!-- C3P0连接池设定 -->
<!-- 使用c3po连接池 配置连接池提供的供应商 5.X版本此处变化了,如下:-->
<property name="connection.provider_class">org.hibernate.c3p0.internal.C3P0ConnectionProvider</property> <!--在连接池中可用的数据库连接的最少数目 -->
<property name="c3p0.min_size">5</property>
<!--在连接池中所有数据库连接的最大数目 -->
<property name="c3p0.max_size">20</property>
<!--设定数据库连接的过期时间,以秒为单位, 如果连接池中的某个数据库连接处于空闲状态的时间超过了timeout时间,就会从连接池中清除 -->
<property name="c3p0.timeout">120</property>
<!--每3000秒检查所有连接池中的空闲连接 以秒为单位 -->
<property name="c3p0.idle_test_period">3000</property> <!-- 通知Hibernate加载那些映射文件 ->
<mapping resource="com/hao/entity/Customer.hbm.xml" />
</session-factory>
</hibernate-configuration>

3.6 编写测试

// 向数据库中插入一条记录
@Test
public void demo1(){
// 1.Hiberante框架加载核心配置文件(有数据库连接信息)
Configuration configuration = new Configuration().configure();
// 2.创建一个SessionFactory.(获得Session--相当连接对象)
SessionFactory sessionFactory = configuration.buildSessionFactory();
// 3.获得Session对象.
Session session = sessionFactory.openSession();
// 4.默认的情况下,事务是不自动提交.
Transaction tx = session.beginTransaction();
// 5.业务逻辑操作 // 向数据库中插入一条记录
Customer customer = new Customer();
customer.setName("小明");
customer.setAge(23); session.save(customer); // 6.事务提交
tx.commit();
// 7.释放资源
session.close();
sessionFactory.close();
}

四、CRUD的操作

4.1 保存记录:

session.save(customer);

4.2 根据主键进行查询:

Customer customer = (Customer)session.get(Customer.class ,1);
Customer customer = (Customer)session.load(Customer.class,1);
  • get 和load的区别:(面试题)

  • 1.发送SQL的时机:

    • load这个方法采用了一个技术.lazy延迟加载(懒加载).真正使用这个对象的数据的时候.(对象的数据不包括主键).
    • get这个方法是立即检索.当执行session.get()方法的时候,马上发送SQL语句查询.
  • 2.返回的对象:

    • load方法返回的是代理对象.
    • get方法返回的是真实的对象.
  • 3.查询一个不存在的数据:

    • load方法抛异常:ObjectNotFoundException.(会抛出此异常)
    • get方法抛异常:NullPointException.(现在没有异常抛出)

4.3 修改记录

session.update(customer);
修改有两种方式 :
// 5.1手动创建对象的方式
Customer customer = new Customer();
customer.setId(2);
customer.setName("小明"); session.update(customer);
***** 这种方式如果没有设置的属性,将这个属性的默认值存入了.(不推荐使用.) // 5.2先查询在修改的方式(推荐方式)
Customer customer = (Customer) session.get(Customer.class, 1);
customer.setName("小李"); session.update(customer);

4.4 删除记录

session.delete(customer);
//删除记录有两种方式:
// 5.1手动创建对象的方式
Customer customer = new Customer();
customer.setId(2);
session.delete(customer); // 5.2先查询在删除的方式
Customer customer = (Customer)session.get(Customer.class, 1);
session.delete(customer);

4.5 查询所有

//1. HQL:
// HQL:Hibernate Query Language.
// 面向对象的写法:
Query query = session.createQuery("from Customer where name = ?");
query.setParameter(0, "小明");
Query.list(); //2. QBC: Query By Criteria.(条件查询)
//此方法已经过时
Criteria criteria = session.createCriteria(Customer.class);
criteria.add(Restrictions.eq("name", "小李"));
List<Customer> list = criteria.list(); //3. SQL //这里用的5.x的版本,与原来的3.x版本不同
NativeQuery query = session.createSQLQuery("select * from customer");
List<Object[]> list = query.list(); // 每一个数组就是一条记录 NativeQuery query = session.createSQLQuery("select * from customer");
query.addEntity(Customer.class); //这里添加一个实体,list方法返回的就是一个Customer的集合,上面的那种方式返回的是一个Object数组的集合,
List<Customer> list = query.list();

五、Hibernate的常用的配置及核心API

5.1 Hibernate的常见配置

1. 核心配置

  • 核心配置有两种方式进行配置:
  • 1.属性文件的配置

    • hibernate.properties
    • 格式:
    • key=value
    • hibernate.connection.driver_class=com.mysql.jdbc.Driver

    • 注意:没有办法在核心配置文件中加载映射文件.(必须手动编码的方式进行加载.)

  • 2.XML格式文件配置:

    • hibernate.cfg.xml
    • 格式:
      <property name="hibernate.connection.username">root</property>

    • 在核心配置中

    • 1.必须的配置:

      • 连接数据库4个基本参数:
      hibernate.connection.driver_class  连接数据库驱动程序
      hibernate.connection.url 连接数据库URL
      hibernate.connection.username 数据库用户名
      hibernate.connection.password 数据库密码
      • Hibernate的方言:
      hibernate.dialect   操作数据库方言
    • 2.可选的配置

    hibernate.show_sql  true 在控制台上输出SQL语句
    hibernate.format_sql true 格式化控制台输出的SQL语句
    hibernate.connection.autocommit true 事务是否自动提交
    hibernate.hbm2ddl.auto create/create-drop/update/validate
    * create : 每次执行的时候,创建一个新的表.(如果以前有该表,将该表删除重新创建.) 一般测试的时候的使用.
    * create-drop : 每次执行的时候,创建一个新的表,程序执行结束后将这个表,删除掉了. 一般测试的时候使用.
    * update : 如果数据库中没有表,创建一个新的表,如果有了,直接使用这个表.可以更新表的结构.
    * validate : 会使用原有的表.完成校验.校验映射文件与表中配置的字段是否一致.不一致报错.
    • 3.映射的配置:
    • 在核心配置文件中加载映射文件:
    <mapping resource="cn/hao/hibernate/demo/Customer.hbm.xml" />

2. 映射文件的配置

  • ORM:对象和关系映射.
  • 配置Java对象与表映射.
  • 配置类与表的映射
name:类的全路径:
table:表的名称:(可以省略的.使用类的名称作为表名.如果类名为Order时,由于order为数据库的关键字,所以此时是不能创建表的);
<!-- 如果为Order table应写为orders-->
<class name="com.hao.entity.Order" table=”orders”>
  • ☆☆配置普通属性与字段映射☆☆: 看到name 找类里面的,看到column 找数据库表里面的
<property name="name" column="name" type="string" length=”20”/>
  • 其中 type 三种写法

  • Java类型:java.lang.String

  • Hibernate类型:string

  • SQL类型:不能直接使用type属性,需要子标签

<property name="name" column="name" length="20">
<column name="name" sql-type="varchar(20)"></column>
</property>
  • ☆☆配置唯一标识与主键映射☆☆

    • 一个表中只有一个主键的形式:
    <id name="id" column="id">
    <generator class="native"/>
    </id>
    • 生成策略 sequence、identity、increment、assigned、uuid/hilo、native
    • 一个表对应多个主键形式:(复合主键:) (实体类必须实现序列化接口)---了解.
    <composite-id></composite-id>
  • 关联关系

  • 命名SQL

<query name="findAll">
from Customer
</query>
<sql-query name="sqlFindAll">
select * from customer
</sql-query>

六、核心API

6.1 Configuration

  • 负责管理 Hibernate 的配置信息

加载核心配置文件

  • 核心配置有两种:
  • 1.hibernate.properties 加载方式如下:
Configuration configuration = new Configuration();
  • 2.hibernate.cfg.xml 加载方式如下:
Configuration configuration = new Configuration().configure();

加载映射文件:

a.在核心配置文件中配置映射文件
b.手动加载映射文件的方法

// 第一种写法:
configuration.addResource("com/hao/entity/Customer.hbm.xml");
//第二种写法:(要求:映射文件名称要规范,类与映射在同一个包下)
configuration.addClass(Customer.class);

6.2 SessionFactory(Session工厂)

  • Configuration对象根据当前的配置信息生成 SessionFactory对象
  • SessionFactory 对象中保存了当前的数据库配置信息和所有映射关系以及预定义的SQL语句
  • SessionFactory 对象是线程安全的
  • SessionFactory还负责维护Hibernate二级缓存
  • SessionFactory对象根据数据库信息,维护连接池,创建Session(相当于Connection)对象.

  • 抽取工具类

public class HibernateUtils {
private static Configuration configuration;
private static SessionFactory sessionFactory; static{
configuration = new Configuration().configure();
sessionFactory = configuration.buildSessionFactory();
} public static Session openSession(){
return sessionFactory.openSession();
} public static void main(String[] args) {
openSession();
}
}

6.3 Session

  • 相当于JDBCConnection
  • Session 是应用程序与数据库之间交互操作的一个单线程对象,是 Hibernate 运作的中心
  • Session是线程不安全的
  • 所有持久化对象必须在 session 的管理下才可以进行持久化操作
  • Session 对象有一个一级缓存,显式执行 flush 之前,所有的持久化操作的数据都缓存在 session 对象处
  • 持久化类与 Session 关联起来后就具有了持久化的能力
  • Session维护了Hiberante一级缓存.
Session session = HibernateUtils.openSession();
session.save()/persist() //添加.
session.update() //修改
session.saveOrUpdate() //增加和修改对象
session.delete() //删除对象
session.get()/load() //根据主键查询
session.createQuery() //创建一个Query接口,编写HQL语句
session.createSQLQuery() //创建一个SQLQuery接口,编写SQL语句数据库操作对象
session.createCriteria() //返回一个Criteria接口.条件查询

6.4 Transaction

Transaction tx = session.beginTransaction();
  • 事务常用方法
commit()        //提交相关联的session实例
rollback() //撤销事务操作
wasCommitted() //检查事务是否提交
  • 如果没有开启事务,那么每个Session的操作,都相当于一个独立的事务

6.5 Query

  • Query代表面向对象的一个Hibernate查询操作
  • session.createQuery 接受一个HQL语句
  • HQL是Hibernate Query Language缩写, 语法很像SQL语法,但是完全面向对象的

6.6 Criteria

  • Criteria条件查询

七、Hibernate中的持久化类

  • 持久化类:实体类 + 映射文件.
  • 持久化类是有编写规范:
  • 提供一个无参数 public访问控制符的构造器 : 用到反射.
  • 提供一个标识属性,映射数据表主键字段 :
    • java区分两个对象是否是同一个使用 --> 地址.
    • 数据库区分两条记录是否一致:使用 --> 主键.
    • Hibernate中区分持久化对象是否是同一个 -->根据唯一标识:
  • 所有属性提供public访问控制符的 set get 方法 : 框架中存值和取值的时候使用.

    • 标识属性应尽量使用基本数据类型的包装类型
    • 使用基本数据类型:
    • 成绩表:
      学号 姓名 成绩
      1 张三 null
    • 持久化类尽量不要使用final进行修饰 :
      • 用final修饰的类是不能被继承.无法生成代理对象.(延迟加载的时候返回代理对象.延迟加载就失效.)
  • 建表的时候:

  • 自然主键和代理主键:

  • 自然主键:

  • 创建一个人员表.人员表中某条记录唯一确定.人都有身份证号.我们可以使用身份证号作为主键.(身份证号本身就是人员的一个属性.作为主键.)

  • 代理主键:

  • 创建一个人员表.人员表中某条记录唯一确定.但是没有使用身份证号作为主键,新建字段(用新建的字段作为主键.只是一个标识作用.)

  • 尽量要Hibernate自己去维护主键

  • ☆☆主键的生成策略☆☆

  • increment :自动增长.适合 short int long...不是使用数据库的自动增长机制.使用Hibernate框架提供的自动增长方式.

    • select max(id) from 表;
    • 在最大值的基础上+1.(多线程的问题.)在集群下不要使用
  • identity :自动增长.适合 short int long...采用数据库的自动增长机制.不适合于Oracle数据库.

  • sequence :序列.适用于 short int long ... 应用在Oracle上 .

  • uuid :适用于字符串类型的主键.采用随机的字符串作为主键.

  • native:本地策略.底层数据库不同.自动选择适用identity 还是 sequence.

  • assigned :Hibernate框架不维护主键,主键由程序自动生成.

  • foreign :主键的外来的.(应用在多表一对一的关系.)

【Hibernate】入门的更多相关文章

  1. 三大框架之hibernate入门

    hibernate入门   1.orm      hibernate是一个经典的开源的orm[数据访问中间件]框架           ORM( Object Relation Mapping)对象关 ...

  2. Hibernate入门案例及增删改查

    一.Hibernate入门案例剖析: ①创建实体类Student 并重写toString方法 public class Student { private Integer sid; private I ...

  3. Hibernate入门案例 增删改

    一.Hibernate入门案例剖析: ①创建实体类Student 并重写toString方法 public class Student { private Integer sid; private I ...

  4. Hibernate入门6.Hibernate检索方式

    Hibernate入门6.Hibernate检索方式 20131128 代码下载 链接: http://pan.baidu.com/s/1Ccuup 密码: vqlv Hibernate的整体框架已经 ...

  5. Hibernate入门5持久化对象关系和批量处理技术

    Hibernate入门5持久化对象关系和批量处理技术 20131128 代码下载 链接: http://pan.baidu.com/s/1Ccuup 密码: vqlv 前言: 前面学习了Hiberna ...

  6. Hibernate入门4.核心技能

    Hibernate入门4.核心技能 20131128 代码下载 链接: http://pan.baidu.com/s/1Ccuup 密码: vqlv 前言: 前面学习了Hibernate3的基本知识, ...

  7. Hibernate入门3.配置映射文件深入

    Hibernate入门3.配置映射文件深入 2013.11.27 前言: 之前的两节是在Java项目中如何使用hibernate,并且通过一个简单地项目实践,期间有很多的错误,一般都是因为配置包的问题 ...

  8. 简单的Hibernate入门简介

    其实Hibernate本身是个独立的框架,它不需要任何web server或application server的支持.然而,大多数的Hibernate入门介绍都加入了很多非Hibernate的东西, ...

  9. Hibernate入门(1)-第一个Hibernate程序

    Hibernate入门(1)-第一个Hibernate程序 Hibernate是最著名的ORM工具之一,本系列文章主要学习Hibernate的用法,不涉及Hibernate的原理.本文介绍第一个Hib ...

  10. hibernate入门之person表

    下面的hibernate入门person表指的是:根据mysql数据库中的test表和其中的元素-->建立映射表==>进而创建持久化类的顺序来操作了,下面为步骤 1.配置MySQL驱动程序 ...

随机推荐

  1. Block pool ID needed, but service not yet registered with NN java.lang.Exception: trace 异常解决

    以上为报错信息: 原因大概为:dd和nd关联的versionId不同导致, 解决方案,备份之前的current文件夹,让其自己生成新的.

  2. python检测文件的MD值

    使用hashlib模块,可对文件MD5一致性加密验证: #python 检测文件MD5值 #python version 2.6 import hashlib import os,sys #简单的测试 ...

  3. PAT 甲级 1047 Student List for Course (25 分)(cout超时,string scanf printf注意点,字符串哈希反哈希)

    1047 Student List for Course (25 分)   Zhejiang University has 40,000 students and provides 2,500 cou ...

  4. ElasticSearch——Curator索引管理

    简介 curator 是一个官方的,可以管理elasticsearch索引的工具,可以实现创建,删除,段合并等等操作.详见官方文档 功能 curator允许对索引和快照执行许多不同的操作,包括: 从别 ...

  5. AFNetWorking实现参数以body传输请求数据

    /** * 异步POST请求:以body方式,支持数组 * * @param url 请求的url * @param body body数据 * @param success 成功回调 * @para ...

  6. 【Leetcode_easy】599. Minimum Index Sum of Two Lists

    problem 599. Minimum Index Sum of Two Lists 题意:给出两个字符串数组,找到坐标位置之和最小的相同的字符串. 计算两个的坐标之和,如果与最小坐标和sum相同, ...

  7. Tools - Nmap

    Nmap Homepage Nmap参考指南(Man Page) Nmap中文网 wiki - Nmap 常用示例 1) Ping扫描,打印出对扫描做出响应的主机 nmap -sP 192.168.1 ...

  8. iOS-SDWebImage使用(转)

    SDWebImage提供了如下三个category来进行缓存. MKAnnotationView(WebCache) UIButton(WebCache) UIImageView(WebCache) ...

  9. 网络编程(socket).WinSocket_recvfrom出错,GetLastError()为10054

    1.在写 我的Qt598(vs2017)x64版本的 shadowsocks程序时遇到的. 具体问题情况 大概是这样:QUdpSocket(假设是sktA) connect接收函数,sktA侦听 端口 ...

  10. C#使用KingAOP实现AOP面向切面编程一

    AOP面向切面编程(Aspect Oriented Programming),是通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术. 实现AOP主要由两种方式,一种是编译时静态植入,优点是 ...