Hibernate的基础知识

什么是框架?

什么是Hibernate框架?

|--1.应用在javaee三层结构中的dao层

|--2.在dao层里面做对数据库进行crud操作,使用hibernate实现crud操作, hibernate底层代码就是jdbc,不需要写复杂的jdbc代码了,

不需要写sql语句实现

|--3.hibernate开源轻量级的框架

|--4.版本

Hibernate3.x

Hibernate4.x过度版本

Hibernate5.0.7.Final

Orm思想

Object relational mapping  对象关系映射

1.hibernate使用orm思想对数据库进行crud操作

2.在web中学习 javabean,更正确的叫法:实体类

描述:

1)让实体类和数据库表进行一一对应关系

让实体类和数据库表对应

让实体类属性和表里面的字段对应

2)不需要直接操作数据库表,而操作表对应的实体类对象

JavaBean知识

Bean:在软件开发领域里,Bean代表的是所有可重用组件

JavaBean:也就是用java开发的可重用组件

JavaBean的编写规范是什么:

类都是public的

都有默认无参构造函数

成员变量都是私有的

都有公有的get/set方法

一般都实现Serializable接口。

基本类型和包装类的选择问题:

由于包装类可以有null值。所以实际开发中都是用包装类。

hibernate中对象标识符

什么是OID:

OID全称是Object Identifier,又叫做对象标识符。数据库通过主键区分不同记录,并要求主键不能为null,不能重复,持久不变。Java中区分同个类中的不同对象是通过对象的句柄(有的地方叫指针或者内存地址)。在hibernate中,区分两个对象是否是同一个对象的标识就是oid。

Hibernate为了方便我们管理对象,提供了很多主键生成策略

1)increment 代理主键,hibernate自动以递增的方式来生成标识符,每次增加1.
2)identity 代理主键,由底层数据库生成标识符,前提就是底层的数据库支持自动增长的类型.
3)sequence 代理主键,hibernate根据底层数据库生成的标识符,前提是底层数据库支持序列
4)hilo 代理主键,hibernate根据higg/low算法来生成的标识符,把特定表的字段作为high的值,默认选用   hibernate_unique_key表的next_hi字段
5)native 代理主键,根据底层数据库对自动生成标识符的支持能力,还选择identity,sequence,或hilo.
6)uuid.hex 代理主键,hibernate采用128位的uuid算法生成标识符,uuid算法能够在网络环境下生成唯一字符串标识符.不过字符串要比数据占用的空间多的多.所以不流行使用.
7)assigned 适用于自然主键,由java应用程序负责生成标识符,为了能让java设置oid.不能吧setid方法设置为非公共类型了,这种方式也尽量避免使用.

2)

Hibernate中的一级缓存

什么是缓存

数据库本身就是文件系统。使用流的方式来操作文件效率并不是很高

1.把数据存到内存中,不需要使用流的方式可以直接读取内存中数据

2.把数据放到内存中,提高读取效率

什么事hibernate一级缓存

就是在hibernate中,当开启session的时候,hibernate会在内存中开辟一个空间,用来存放管理的java对象。如果第二次操作的java对象的OID与一级缓存中的相匹配,就不会去数据库中查找,直接从缓存中取数据。这样能减少数据库大的压力,并提高了整体的查询效率。

快照机制

什么事快照机制?

快照是存在于堆内存中对数据库中的数据进行备份的副本,它是一级缓存数据前后的参照,主要是为了保证数据的一致性。

随着事务的提交,hibernate在提交数据之前会先和快照中的数据进行对比。如果一级缓存中的数据和快照中的数据不一致,发送update语句进行同步。注意:快照一般是和数据库中的记录保持一致

对象的三种状态

|-- 瞬时态

对象里面没有id值,与session对象没有关联

一般为save方法的对象

|-- 持久态

对象里面有id值,与session对象有关连

一般为get方法获取出来的对象

||

\/

|-- 脱管态 对象里面有id 与session对象没有关联

一般为delete对象

核心api

Configuration

作用:

就是用于加载主配置文件的。

常用方法:

默认构造函数:它只能加载类的根路径下,名称为hibernate.properties的配置文件。不能加载xml

configure():它用于加载类的根路径下,名称为hibernate.cfg.xml的配置文件。

buildSessionFactory():根据配置文件,构建SessionFactory

addResource(String url);指定映射文件的位置

addClass(Class clazz);指定实体类的字节码

SessionFactory

作用:

就是用于创建Session的

常用方法:(今天只能介绍一个,不是就有一个方法)

openSession():每次都是生成一个新的Session

细节:

它维护了很多信息:

连接数据库的信息

hibernate的基本配置

映射文件的位置,以及映射文件中的配置

一些预定义的SQL语句(这些语句都是通用的) 比如:全字段保存,根据id的全字段更新,根据id的全字段查询,根据id的删除等等。

hibernate的二级缓存(了解)

特性:

它是一个线程安全的对象,所有由该工厂生产的Session都共享工厂中维护的数据。

SessionFactory的使用原则:

由于它维护了很多信息,所以创建和销毁会消耗很多资源,所以不应该反复的创建和销毁。

原则就是:一个应用应该只有一个SessionFactory。在应用加载时创建,应用卸载时销毁。

Session

作用:

就是用于跟数据库交互。包含了增删改查以及获取事务对象。

常用方法:

save(Object entity);  :保存一个实体到数据库

update(Object entity);:更新一个实体

delete(Object entity);:删除一个实体

get(Class clazz,Serializable id);:根据id查询一个实体。参数的含义:Class表示要查询的实体类字节码。Serializable就是查询的条件。

beginTransaction();:开启事务,并返回事务对象

细节:

由于SessionFactory已经维护了很多数据,所以Session就维护较少的内容。

它是一个轻量级对象。并且:它不是线程安全的!!!!!!!

它维护了hibernate的一级缓存(关于一级缓存的问题都是明天的内容)。

它的反复创建销毁不会消耗太多资源。

使用原则:

每个线程都只有一个Session对象。

Transaction

作用:

就是用于控制事务的

常用方法:

commit():提交事务

rollback():回滚事务

hibernate 事务操作

配置事务级别:1,2,3,4---〉级别越高越严谨

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

Hibernate绑定session

1.session类似于connection,之前web端学过 threadLocal//与本地线程绑定

2.帮我们实现与本地线程绑定session

3.获取与本地线程session

1)在hibernate核心配置文件添加

<property name="hibernate.current_session_context_class">thread</property>

获取与本地现场绑定session时候,关闭session报错,不需要手动进行关闭

查询对象的api

Query-----session.createQuery(hql语句)

1   query.list()---获取查询结果的list集合

2   query.uniqueResult()---获取查询结果的单个对象,和统计查询结合

1、使用 query对象不需要写sql语句,但需要写hql语句(hibernate query language)

Hql是对实体类和属性进行编写

例子 from User where userName = ?

分页查询

limit的参数含义

第一个:查询的开始记录索引

第二个:每次查询的条数

hibernate中针对分页提供了两个方法

setFirstResult(int firstResult);设置开始记录索引

setMaxResults(int maxResults);设置每次查询的记录条数

投影查询:

*   投影:使用一个实体的部分字段信息,来构建实体类对象,叫做对象的投影(在hibernate中的叫法)

*  使用HQL的方式查询实体类的部分字段信息,并且封装到实体类中。(QBC也能实现投影查询,但是不如hql的好用,所以使用投影查询,一般都用HQL)

* HQL语句的写法:

*   select  new Customer() from Customer

*   如果工程只有一个唯一的类,可以不写全限定类名,否则必须写全限定类名。

* 实体类要求:

*  必须提供一个相同参数列表的构造函数

例子

Select new Customer(id ,username) from Customer

Criteria:

不需要任何的sql语句或者hql语句,通过方法对sql进行拼接。

--添加查询条件

C.add(Restrictions.like(“”,””))

添加分页条件

c.setFirstResult(2);

c.setMaxResult(2);

排序查询

c.addOrder(Order.desc(“”))

统计查询

c.setProjection(Projection.count(“”))

离线查询

离线条件查询

*  离线:

*  它是和在线对应的。

*  Criteria对象是一个在线对象,它是由一个可用的(活动的)Session对象获取的出来的。

*  当session失效时,就无法再获取该对象了。

*  有一个对象,它也可以用于设置条件,但是获取的时候并不需要Session对象。

*  该对象就叫做离线对象:

*   DetachedCriteria对象

*  使用该对象进行的查询就叫做:离线查询

*

*  如何获取该对象

*  DetachedCriteria dCriteria = DetachedCriteria.forClass(要查询的实体类字节码);

短语

含义

Restrictions.eq

等于=

Restrictions.allEq

使用Map,使用key/value进行多个等于的判断

Restrictions.gt

大于>

Restrictions.ge

大于等于>=

Restrictions.lt

小于<

Restrictions.le

小于等于<=

Restrictions.between

对应sql的between子句

Restrictions.like

对应sql的like子句

Restrictions.in

对应sql的in子句

Restrictions.and

and 关系

Restrictions.or

or关系

Restrictions.sqlRestriction

Sql限定查询

Restrictions.asc()

根据传入的字段进行升序排序

Restrictions.desc()

根据传入的字段进行降序排序

运算类型

HQL运算符

QBC运算方法

比较运算

=

Restrictions.eq()

<>

Restrictions.not(Restrictions.eq())

>=

Restrictions.ge()

<

Restrictions.lt()

<=

Restrictions.le()

is null

Restrictions.isNull()

is not null

Restrictions.isNotNull()

范围运算符

in

Restrictions.in()

not in

Restrictions.not(Restrictions.in())

between

Restrictions.between()

not between

Restrictions.not(Restrictions.between())

运算类型

HQL运算符

QBC运算方法

字符串模式匹配

like

Restrictions.like()

逻辑

and

Restrictions.and()|

Restrictions.conjunction()

or

Restrictions.or()|

Restrictions.disjunction()

not

Restrictions.not()

SqlQuery

和Query用法类似,就是将hql语句改成sql语句

Hibernate中的概念

实体查询---hibernate中的检索策略

Get方法---立即检索

调用get方法马上发送sql语句查询数据库

Load方法---延迟检索

调用load方法不会马上去查下数据库,在 session关闭前得到对象除id以外属性的值才会发送sql语句查询

上面两种都是返回实体类的 代理对象

关联级别查询

查询某个客户,在查询这个客户的所有联系人,查询客户的所有联系人的过程是否需要延迟

默认在得到set集合后不会发送语句,只有调用集合里对象的方法后才会发送语句

基于xml方式学习hibernate

Hibernate的核心配置文件---hibernate.cfg.xml

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

<!-- 导入dtd约束:

位置:在核心jar包中的名称为hibernate-configuration-3.0.dtd中

-->

<!DOCTYPE hibernate-configuration PUBLIC

"-//Hibernate/Hibernate Configuration DTD 3.0//EN"

"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">

<hibernate-configuration>

<!-- 配置SessionFactory

SessionFactory就是一个工厂,用于生产Session对象的。

Session就是我们使用hibernate操作数据库的核心对象了。

创建SessionFactory由三部分组成,缺一不可。要知道是哪三部分

1、连接数据库的基本信息

2、hibernate的基本配置

3、映射文件的位置

找配置文件的key都是在hibernate的开发包中project文件夹下的etc目录中的hibernate.properties

-->

<session-factory>

<!-- 1、连接数据库的基本信息 -->

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

<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/day36_ee48_hibernate</property>

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

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

<!-- 2、hibernate的基本配置 -->

<!-- 让hibernate框架识别不同数据库的语句,自己特有的语句 --> <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>

<!-- 是否让hibernate根据表结构的变化来生成DDL语句

DDL:数据定义语言

hibernate可以根据映射文件来为我们生成数据库的表结构。

但是他不能生成数据库。

hbm2ddl.auto的取值

* none:不用Hibernate自动生成表.

* create:每次都会创建一个新的表.(测试)

* create-drop:每次都会创建一个新的表,执行程序结束后删除这个表.(测试)

* update:如果数据库中有表,使用原来的表,如果没有表,创建一个新表.可以更新表结构。

* validate:只会使用原有的表.对映射关系进行校验.

-->

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

<!-- 3、映射文件的位置 -->

<mapping resource="com/itheima/domain/Customer.hbm.xml"/>

</session-factory>

</hibernate-configuration>

单表配置文件解析

例子:

# 约束 hibernate会帮我们自动创建表

<?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>

<!-- 1.配置类和表对应

Class--name:实体类的全路径

table对应隐射的表

-->

<class name="cn.itcast.entity.User" table="t_user">

<!-- 配置实体类的id和表id对应,hibernate要求实体类有一个属性唯一值,

hibernate要求表有字段作为唯一值 -->

<!-- id标签

name属性:实体类里面id属性名称

column属性:生成的表字段名称 -->

<id name="uid" column="uid">

<!-- 设置数据库表id增长的策略

native:生成表id值就是主键自动增长

-->

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

</id>

<!-- 配置其他属性和表字段对应 -->

<property name="username" column="username"></property>

<property name="password" column="password"></property>

<property name="address" column="address"></property>

</class>

</hibernate-mapping>

多表设计和查询

一对多

客户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>

<class name="cn.itcast.entity.Customer" table="hiber_customer" lazy="extra">

<id name="cid" column="cust_id">

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

</id>

<property name="custName" column="cust_name"></property>

<property name="custSource" column="cust_source"></property>

<property name="custAddress" column="cust_address"></property>

<property name="custPhone" column="cust_phone"></property>

#标识一个customer有多个联系人对象

inverse的值有两种,“true”和“false”。inverse="false"是默认的值,如果设置为true则表示对象的状态变化不会同步到数据库 ;设置成false则相反;

inverse的作用:在hibernate中是通过inverse的设置来决定是有谁来维护表和表之间的关系的。

<set name="linkMan" inverse="true">

@标识所映射到那个字段上--也就是外键

<key column="lkm_cust_id"></key>

<one-to-many class="cn.itcast.entity.LinkMan"/>

</set>

</class>

</hibernate-mapping>

基于注解学习hibernate

JPA的了解

在学习注解前首先要先了解jpa是什么?

JPA是SUN公司提出的一套对ORM框架的POJO持久化标准规范。并提供了注解和xml的支持。Hibernate也是实现jpa规范的一种ORM框架。

单表

import javax.persistence.Column;

import javax.persistence.Entity;     #所有导的包都是javax下的

import javax.persistence.GeneratedValue;

import javax.persistence.GenerationType;

import javax.persistence.Id;

import javax.persistence.Table;

@Entity#声明该类是表所对应的实体类

@Table(name="m_user")#声明该实体类所对应的表

public class User {

@Id#声明类中的该属性是与表的主键相对应

@GeneratedValue(strategy = GenerationType.IDENTITY)#声明主键的生成策略,与之前的xml配置有些不同 

@Column(name="uid")#申明该属性所对应表中的字段

private Integer id;

@Column(name="username")

private String username;

@Column(name="password")

private String password;

@Column(name="address")

private String address;

@Column(name="telephone")

private String telephone;

@Column(name="remake")

private String remake;

@Column(name="department")

private String department;

public Integer getId() {

return id;

}

public void setId(Integer id) {

this.id = id;

}

..........

}

注释:JPA中有四种生成策略分别为:table 、 sequence、identity和auto

Identity和sequence:都是主键自增长,针对不同的数据库,所支持的策略是不一样的,mysql支持identity

Table:当数据库不支持Identity和sequence,hibernate会提供一张表来维护主键生成

Auto:由用户自己维护主键

多表之一对多----  一

@Entity

@Table(name="s_customer")

public class Customer implements Serializable{

@Id

@GeneratedValue(strategy=GenerationType.IDENTITY)

@Column(name="cid")

private Integer custId;

@Column(name="cust_name")

private String   custName;

@Column(name="cust_industry")

private String custIndustry;

。。。。。。。。。

#一对多,表示该类对应的多个LinkMan对象 ,该表为主表

@OneToMany(targetEntity=LinkMan.class,mappedBy="customer")

#targetEntity表示与哪张表的实体类建立关系,

#mappedBy表示该类映射到实体类上的属性名称,在mysql中对应的是外键字段

#由于一对多的情况下只需要多的一方维护外键,所以在这里不需要加@JoinColumn

private Set<LinkMan> linkMans = new HashSet<>(0);

提供set/get方法

多表之多对一----- 多

@Entity

@Table(name="s_linkman")

public class LinkMan implements Serializable{

@Id

@GeneratedValue(strategy=GenerationType.IDENTITY)

@Column(name="lkm_id")

private Integer lid;

@Column(name="lkm_name")

private String lkmName;

@Column(name="lkm_gender")

private String lkmGender;

@Column(name="lkm_phone")

private String lkmPhone;

@Column(name="lkm_mobile")

private String lkmMobile;

@Column(name="lkm_email")

private String lkmEmail;

@Column(name="lkm_position")

private String lkmPosition;

@Column(name="lkm_memo")

private String lkmMemo;

#多对一的映射,表示该实体类对应的表示从表

@ManyToOne(targetEntity=Customer.class)

#targetEntity:表示和哪张表的实体类建立关系

@JoinColumn(name="lkm_cust_id",referencedColumnName="cid")

#由于从表需要维护外键@JoinColumn表示外键的声明,其中name为外键名称

ReferencedColumnName表示所映射到主表的字段

private Customer customer;

。。。。。。。。。。。

多对多

Role

@Entity

@Table(name="hiber_role")

public class Role {

@Id

@Column(name="role_id")

@GeneratedValue(strategy=GenerationType.IDENTITY)

private Integer role_id;

@Column(name="role_name")

private String role_name;

@Column(name="role_memo")

private String role_memo;

@ManyToMany(mappedBy="roles")

private Set<User> users = new HashSet<>(0);

。。。。。。。。。。。。。

User

@Entity

@Table(name="hiber_user")

public class User {

@Id

@GeneratedValue(strategy = GenerationType.IDENTITY)

@Column(name="user_id")

private Integer user_id;

@Column(name="user_name")

private String user_name;

@Column(name="user_password")

private String user_password;

@ManyToMany

@JoinTable(name="user_role_rel",//中间表名称

joinColumns={@JoinColumn(name="user_id",referencedColumnName="user_id")},

//中间表user_role_rel字段关联

inverseJoinColumns = {@JoinColumn(name="role_id",referencedColumnName="role_id")}

)

private Set<Role> roles = new HashSet<>(0);

。。。。。。。。。。。。。

Hibernate学习总汇的更多相关文章

  1. Hibernate学习之——搭建log4j日志环境

    昨天讲了Hibernate开发环境的搭建以及实现一个Hibernate的基础示例,但是你会发现运行输出只有sql语句,很多输出信息都看不见.这是因为用到的是slf4j-nop-1.6.1.jar的实现 ...

  2. Hibernate学习笔记(二)

    2016/4/22 23:19:44 Hibernate学习笔记(二) 1.1 Hibernate的持久化类状态 1.1.1 Hibernate的持久化类状态 持久化:就是一个实体类与数据库表建立了映 ...

  3. Hibernate学习笔记(一)

    2016/4/18 19:58:58 Hibernate学习笔记(一) 1.Hibernate框架的概述: 就是一个持久层的ORM框架. ORM:对象关系映射.将Java中实体对象与关系型数据库中表建 ...

  4. Hibernate 学习笔记一

    Hibernate 学习笔记一 今天学习了hibernate的一点入门知识,主要是配置domain对象和表的关系映射,hibernate的一些常用的配置,以及对应的一个向数据库插入数据的小例子.期间碰 ...

  5. Hibernate学习笔记-Hibernate HQL查询

    Session是持久层操作的基础,相当于JDBC中的Connection,通过Session会话来保存.更新.查找数据.session是Hibernate运作的中心,对象的生命周期.事务的管理.数据库 ...

  6. 我的hibernate学习记录(二)

    通过上一篇文章我的hibernate学习记录(一)基本上的入门了hibernate,但是,里面还有还多东西是通过迷迷糊糊的记忆,或者说copy直接弄进去的,所以这篇文章就需要对上篇的一些文件.对象进行 ...

  7. Hibernate学习(二)关系映射----基于外键的单向一对一

    事实上,单向1-1与N-1的实质是相同的,1-1是N-1的特例,单向1-1与N-1的映射配置也非常相似.只需要将原来的many-to-one元素增加unique="true"属性, ...

  8. Hibernate学习一:Hibernate注解CascadeType

    http://zy19982004.iteye.com/blog/1721846 ———————————————————————————————————————————————————————— Hi ...

  9. Hibernate学习---缓存机制

    前言:这些天学习效率比较慢,可能是手头的事情比较多,所以学习进度比较慢. 在之前的Hibernate学习中,我们无论是CURD,对单表查询还是检索优化,我们好像都离不开session,session我 ...

随机推荐

  1. markdown基础

    介绍: markdown是一种可以使用普通文本编译器编写的标记语言,通过简单的标记语法,它可以使普通文本具有一定的格式.说的简单一点,markdown其实就是一种简单的文本,与普通的文本文件(txt文 ...

  2. Sql_Case_When用法

    http://wenku.baidu.com/link?url=XBnkUzGtiJFhTnQk5HbmdgndhVEYJdcfDEhSEIFeTRn9-41KMLf_49wKiydNCF-4g3Qi ...

  3. 根据list得到list中的最大值最小值

    List ll = new ArrayList(); ll.add(new BigDecimal(1)); ll.add(new BigDecimal(4.99)); ll.add(new BigDe ...

  4. Entity Framework入门教程: Entity Framework支持的查询方式

    Entity Framework支持的查询方式有三种 LINQ to Entities Entity SQL Native SQL [LINQ to Entities] LINQ(语言集成查询)是从V ...

  5. ASP.NET Core 源码学习之 Options[4]:IOptionsMonitor

    前面我们讲到 IOptions 和 IOptionsSnapshot,他们两个最大的区别便是前者注册的是单例模式,后者注册的是 Scope 模式.而 IOptionsMonitor 则要求配置源必须是 ...

  6. win 10 开机后无法显示桌面

    我整理了几种方法,可以试一下 1> win + x 然后运行explorer.exe 2> 1/// shift + ctrl + esc 进入 任务管理器 2///        点击 ...

  7. Java添加JDBC

    添加JDBC 1.SQL Server SQL Server2005 下载 sqljdbc_4.0 https://www.microsoft.com/en-us/download/details.a ...

  8. Java post提交表单限制

    According to Tomcat7's documentation, setting maxPostSize in Connector to a value less than or equal ...

  9. OJ2237第k小数题解

    题目描述: 有n个数,请你找出第k小的数. 输入描述: 第一行有2个正整数n,k(n,k<=10^7)第二行有n个非负数ai(ai<=10^5) 输出描述: 输出第k小的数. 输入样例: ...

  10. JQuery获取Dom元素的方法

    (function (window) { var arr = []; var VP = function (selector, context) { return new VP.fn.init(sel ...