您的位置:首页 > 其它

初识Hibernate

2017-11-05 00:00 169 查看

一、Hibernate的下载与目录结构

hibernate官网:http://hibernate.org/

下载成功后的目录结构如下(以Hibernate 5.0.0为例):



document:存放了hibernate的相关文档,包括草参考文档与API文档等。

lib文件夹:该文件夹存放Hibernate框架的核心类库以及HIbernate的第三方类库。该文件夹下的required子目录存放运行Hibernate项目必须的核心类库。

project文件夹:该文件夹存放Hibernate各种相关项目的源代码。

注意:实际开发中除了required文件夹下的jar包,还需要添加hibernate对JPA支持的jar,以及实现日志功能的jar和数据库连接池相关的jar。

二、第一个hibernate程序

1、准备数据库

create database hibernate;

create table customer(
id int(11) not null auto_increment,
name varchar(20) ,
age int(11) ,
sex varchar(8) ,
city varchar(20),
primary key(id)
);

2、创建Java project并导入hibernate需要的jar包(required+jpa+log4j)



3、创建Customer实体类

package bean;

public class Customer {

private Integer id;
private String name;
private Integer age;
private String sex;
private String city;

public Integer getId() {
return id;
}

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

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public Integer getAge() {
return age;
}

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

public String getSex() {
return sex;
}

public void setSex(String sex) {
this.sex = sex;
}

public String getCity() {
return city;
}

public void setCity(String city) {
this.city = city;
}

}

4、配置Customer.hbm.xml

在与Customer实体类同package下创建Customer.hbm.xml。

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated 2017-11-8 21:51:12 by Hibernate Tools 3.5.0.Final -->
<hibernate-mapping>
<!-- name代表的是实体类名,table代表的是表名 -->
<class name="bean.Customer" table="CUSTOMER">
<id name="id" type="java.lang.Integer">
<column name="ID" />
<generator class="native" /><!-- 主键生成策略 -->
</id>
<!-- 其他属性使用property标签来映射 -->
<property name="name" type="java.lang.String">
<column name="NAME" />
</property>
<property name="age" type="java.lang.Integer">
<column name="AGE" />
</property>
<property name="sex" type="java.lang.String">
<column name="SEX" />
</property>
<property name="city" type="java.lang.String">
<column name="CITY" />
</property>
</class>
</hibernate-mapping>

5、配置hibernate.cfg.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>
<session-factory>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">admin</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/hibernate?characterEncoding=UTF-8</property>

<!-- 指定使用的数据库语言 -->
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- 显示sql语句 -->
<property name="hibernate.show_sql">true</property>
<!-- 格式化sql语句 -->
<property name="format_sql">true</property>
<!-- 用来关联hbm配置文件 -->
<mapping resource="bean/Customer.hbm.xml"/>
</session-factory>
</hibernate-configuration>

6、测试类

package test;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;

import bean.Customer;

public class testHibernate {

public static void main(String[] args) {
// TODO Auto-generated method stub

//加载hibernate.cfg.xml文件
Configuration configuration = new Configuration().configure();
//获取SessionFactory
SessionFactory factory = configuration.buildSessionFactory();
//得到一个session
Session session = factory.openSession();
//开启事务
Transaction transaction = session.beginTransaction();
//操作
Customer customer = new Customer();
customer.setAge(18);
customer.setName("GL");
customer.setSex("man");
customer.setCity("MAS");
//将数据存储到表中
session.save(customer);
//提交事务
transaction.commit();
//关闭资源
session.close();
factory.close();
}

}


三、hibernate.cfg.xml

src目录下创建 hibernate.cfg.xml配置文件,配置文件包含了连接持久层与映射文件所需的基本信息。发布后,该文件会在项目的WEB-INF/classes路径下。

<hibernate-configuration>
<!-- 构造数据库的连接工厂,这是Hibernate的核心类 -->
<session-factory>

<!-- 这里是简单的数据库连接的基本信息 -->
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/example?useUnicode=true&characterEncoding=utf8</property>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.username">ljh</property>
<property name="hibernate.connection.password">ljh</property>

<!-- 在控制台里打印生成的SQL语句 -->
<property name="hibernate.show_sql">true</property>
<!-- 格式化控制台输出的SQL语句,这两条都是方便我们来学习Hibernate框架 -->
<property name="hibernate.format_sql">true</property>

<!--
方言:根据指定的方言与数据库打交道,完成SQL的具有语句生成,因为不同的数据库sql语法还是有区别的,
这里相当于告诉Hibernate框架,我们使用的是什么数据库。
MySQL : org.hibernate.dialect.MySQLDialect
Oracle : org.hibernate.dialect.OracleDialect
-->

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

<!-- 管理所有的映射资源文件,这里仅仅配置了User类的配置映射文件,应该将我们的所有的映射配置文件设置到这里,这样我们框架才能找到 -->
<mapping resource="com/ljh/hibernate/pojo/User.hbm.xml"/>

</session-factory>
</hibernate-configuration>

Hibernate实现了一种插件结构,它可以集成任何连接池软件,Hibernate对C3P0连接池提供了内嵌支持,所以可以在Hibernate中直接配置与使用C3P0的。

首先导入C3P0的jar包,此jar包可以在下载Hibernate包的lib文件下的子目录optional中找到。

然后再Hibernate.cfg.xml中添加C3P0的配置信息。代码如下:

<!-- 设定c3p0连接池配置连接池提供的供应商 -->
<property name="connection.provider_class">
org.hibernate.connection.C3P0ConnectionProvider
</property>
<!-- 在连接池中可用的数据库连接的最少数量 -->
<property name="c3p0.min_size">5</property>
<!-- 在连接池中所有数据库连接的最大数目 -->
<property name="c3p0.max_size">20</property>
<!-- 设定数据库连接的过期时间,以ms为单位 -->
<property name="c3p0.timeout">120</property>
<!-- 没3000秒检查所有连接池中空闲连接,以s为单位 -->
<property name="c3p0.idle_test_period">3000</property>


四、*.hbm.xml

<?xml version="1.0"?>

<!-- 映射文件的dtd信息 -->
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>

<!-- name代表的是实体类名,table代表的是表名 -->
<class name="bean.Customer" table="CUSTOMER">

<id name="id" type="java.lang.Integer">
<column name="ID" />
<generator class="native" /><!-- 主键生成策略 -->
</id>

<!-- 其他属性使用property标签来映射 -->
<property name="name" type="java.lang.String">
<column name="NAME" />
</property>
<property name="age" type="java.lang.Integer">
<column name="AGE" />
</property>
<property name="sex" type="java.lang.String">
<column name="SEX" />
</property>
<property name="city" type="java.lang.String">
<column name="CITY" />
</property>

</class>
</hibernate-mapping>

在上述代碼中,首先进行了XML声明,然后定义了映射文件的dtd信息,此dtd信息读者不需要手写,可以在项目的Web APP Libraries目录(或Referenced Libraries目录)中,可以找到Hibernate的核心jar包(5.0版本为hibernate-core-5.0.0.Final.jar),打开jar包后再org.hibernate包中即可找到hibernate-mapping-3.0.tdt文件。打开文件,在文件的最上方即有此dtd信息。



在映射文件的dtd信息下面,就是Hibernate映射的具体配置,每个元素的具体属性如下:

1、hibernate-mapping元素

该元素定义了XML配置文件的基本属性,它所定义的属性在映射文件的所有节点都有效。

schema: 指定所映射的数据库schema的名称。若指定该属性, 则表明会自动添加该 schema 前缀

catalog:指定所映射的数据库catalog的名称。

default-cascade(默认为 none): 设置hibernate默认的级联风格. 若配置 Java 属性, 集合映射时没有指定 cascade 属性, 则 Hibernate 将采用此处指定的级联风格.

default-access (默认为 property): 指定 Hibernate 的默认的属性访问策略。默认值为 property, 即使用 getter, setter 方法来访问属性. 若指定 access, 则 Hibernate 会忽略 getter/setter 方法, 而通过反射访问成员变量.

default-lazy(默认为 true): 设置 Hibernat morning的延迟加载策略. 该属性的默认值为 true, 即启用延迟加载策略. 若配置 Java 属性映射, 集合映射时没有指定 lazy 属性, 则 Hibernate 将采用此处指定的延迟加载策略

auto-import (默认为 true): 指定是否可以在查询语言中使用非全限定的类名(仅限于本映射文件中的类)。

package (可选): 指定一个包前缀,如果在映射文档中没有指定全限定的类名, 就使用这个作为包名。

2、class元素

该元素用于指定类和表的映射

name:指定该持久化类映射的持久化类的类名

table:指定该持久化类映射的表名, Hibernate 默认以持久化类的类名作为表名

dynamic-insert: 若设置为 true, 表示当保存一个对象时, 会动态生成 insert 语句, insert 语句中仅包含所有取值不为 null 的字段. 默认值为 false

dynamic-update: 若设置为 true, 表示当更新一个对象时, 会动态生成 update 语句, update 语句中仅包含所有取值需要更新的字段. 默认值为 false

select-before-update:设置 Hibernate 在更新某个持久化对象之前是否需要先执行一次查询. 默认值为 false

batch-size:指定根据 OID 来抓取实例时每批抓取的实例数.

lazy: 指定是否使用延迟加载.

mutable: 若设置为 true, 等价于所有的 <property> 元素的 update 属性为 false, 表示整个实例不能被更新. 默认为 true.

discriminator-value: 指定区分不同子类的值. 当使用 <subclass/> 元素来定义持久化类的继承关系时需要使用该属性

3、id元素

该元素用来设定持久化类的OID和表的主键的映射

name: 标识持久化类 OID 的属性名

column: 设置标识属性所映射的数据表的列名(主键字段的名字).

unsaved-value:若设定了该属性, Hibernate 会通过比较持久化类的 OID 值和该属性值来区分当前持久化类的对象是否为临时对象

type:指定 Hibernate 映射类型. Hibernate 映射类型是 Java 类型与 SQL 类型的桥梁. 如果没有为某个属性显式设定映射类型, Hibernate 会运用反射机制先识别出持久化类的特定属性的 Java 类型, 然后自动使用与之对应的默认的
Hibernate 映射类型

Java 的基本数据类型和包装类型对应相同的 Hibernate 映射类型. 基本数据类型无法表达 null, 所以对于持久化类的 OID 推荐使用包装类型

在讲解Hibernate的主键生成策略之前,先来了解两个概念,即自然主键和代理主键,具体如下:

自然主键:把具有业务含义的字段作为主键,称之为自然主键。例如在customer表中,如果把name字段作为主键,其前提条件必须是:每一个客户的新明不允许为null,不允许客户重名,并且不允许修改客户姓名。尽管这都是可行的,但是补能满足不断变化的业务需求,一旦出现了客户重名的业务需求,就必须修改数据库模型,这给数据库的维护增加了难度。

代理主键:把不具有业务含义的字段当作主键,称之为代理逐主键,该字段一般取名为“id”,通常为整数类型,在上面的例子中,显然更合理的方式是使用代理主键。

Hibernate中,提供了几个内置的主键生成策略

increment:用于long,short或int类型,由Hibernate自动以递增的方式生成唯一标识符,每次增量为1.只有当没有其他进程向同一张表中插入数据时才可以使用,不能再集群环境下使用,适用于代理主键

identity:采用底层数据库本身提供的主键生成标识符,条件是数据库支持自动增长数据类型。在DB2,Mysql,SqlServer,Sybases中可以使用该生成器,该生成器要求在数据库中把主键定义为自增长类型,适用于代理主键

sequence:Hibernate根据底层数据库序列生成标识符,条件时数据库支持序列,支持序列的数据库包括:DB2,Oracle等,OID必须为long,int或short类型。

hilo:由HIbernate按照一种high/low算法生成标识符,它从数据库的特定表的字段中获取high值。Hibernate在持久化一个对象时,由hibernate负责生成主键值,hilo标识符生成器在生成标识符时需要读取并修改HI_TABLE表中的NYEXT_VALUE值,由于hilo生存标识符机制不依赖于底层数据库系统,因此它适合所有的数据库系统,此外OID必须为long,int或short类型。

native:依据底层数据库对自动生成标识符的支持能力,来选择identity,sequence或hilo标识符生成器。由于 native 能根据底层数据库系统的类型, 自动选择合适的标识符生成器, 因此很适合于跨数据库平台开发 ,此外OID必须为long,int或short类型。

4、properties

该元素用来指定类的属性和表的字段的映射。

name:指定该持久化类的属性的名字

column:指定与类的属性映射的表的字段名. 如果没有设置该属性, Hibernate 将直接使用类的属性名作为字段名.

type:指定 Hibernate 映射类型. Hibernate 映射类型是 Java 类型与 SQL 类型的桥梁. 如果没有为某个属性显式设定映射类型, Hibernate 会运用反射机制先识别出持久化类的特定属性的 Java 类型, 然后自动使用与之对应的默认的 Hibernate 映射类型.

not-null:若该属性值为 true, 表明不允许为 null, 默认为 false

access:指定 Hibernate 的默认的属性访问策略。默认值为 property, 即使用 getter, setter 方法来访问属性. 若指定 field, 则 Hibernate 会忽略 getter/setter 方法, 而通过反射访问成员变量

unique: 设置是否为该属性所映射的数据列添加唯一约束.


五、Hibernate核心API

在Hibernate中有6个常用的核心接口,他们分别是Configuration、SessiobFactory、Session、Transaction、Query和Criteria。

1、Configuration

负责管理Hibernate的配置信息

加载核心配置文件

    hibernate.properties
       加载:Configuration configuration = new Configuration();
    hibernate.cfg.xml:
       加载:Configuration configuration = new Configuration().configure();

这种方式默认会取src下读取hibernate.cfg.xml配置文件。如果不想使用默认的hibernate.cfg.xml配置文件,而是使用指定目录下的配置文件,则需要向configure()方法中传递一个文件路径的参数。例如:

Configuration configuration = new Configuration().configure("/config/hibernate.cfg.xml");

2、SessionFactory

SessionFactory接口负责Hibernate的初始化和建立Session对象,它在Hibernate中起到一个缓冲区的作用,Hibernate可以将自动生成的SQL语句、映射数据以及某些可重复利用的数据放在这个缓冲区中,同时它还保存了对这个数据库配置的我所有映射关系,维护了当前的二级缓存。

SessionFactory  sessionFactory = configuration.buildSessionFactory();

SessionFactory具有以下特点:

》线程安全

》重量级的,不能随意的创建和销毁它的实例

由于这些特点,在实际开发中,一个项目只需一个SessionFactory,通常会抽取一个工具类:

class HibernateUtils {
private static Configuration configuration;
private static SessionFactory factory;
private static Session session;
static {
configuration = new Configuration().configure();
factory = configuration.buildSessionFactory();
}

public static Session openSession() {
session = factory.openSession();
return session;
}

}

3、Session

Session 是应用程序与数据库之间交互操作的一个单线程对象,是 Hibernate 运作的中心,是线程不安全的,所有持久化对象必须在 session 的管理下才可以进行持久化操作,Session 对象有一个一级缓存,显式执行 flush 之前,所有的持久化操作的数据都缓存在 session 对象处,持久化类与 Session 关联起来后就具有了持久化的能力,Session维护了Hiberante一级缓存.

创建Session的代码如下:

//采用openSession方法创建Session
Session session = SessionFactory.openSession();

//采用getCurrentSession()方法创建Session
Session session = SessionFactory.getCurrentSession();

这两种方法的区别是:第一种·需要手动调用close方法关闭session,第二种session实例被绑定到当前线程中,它在提交或回滚操作时会自动关闭。

在Session中提供了大量的常用方法,具体如下:

save(),update()和saveOrUpdate()方法用于增加和修改对象

delete()方法:用于删除对象

get()和load()方法:根据主键查询

createQuery()和createSQLQuery()方法:用于数据库操作对象

createCriteria()方法:条件查询

4、Transaction

获得:Transaction tx = session.beginTransaction();

  常用方法:
    commit() :提交相关联的session实例
    rollback() :撤销事务操作
    wasCommitted() :检查事务是否提交

如果没有开启事务,那么每个Session的操作,都相当于一个独立的事务

5、Query

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

// 1.简单查询
List<Customer> list = session.createQuery("from Customer").list();

// 2.条件查询:
List<Customer> list = session.createQuery("from Customer where name = ?").setParameter(0, "芙蓉").list();

// 3.分页查询:select * from customer limit a,b; a:从哪开始  b:每页显示记录数.
Query query = session.createQuery("from Customer");
query.setFirstResult(3);
query.setMaxResults(3);
List<Customer> list = query.list();

Query常用方法如下:

setter方法:Query接口中提供了一系列的setter方法用于设置查询语句中的参数,针对不同的数据类型,需要用到不同的setter方法。

iterator()方法:该方法用于查询语句,返回结果为一个Iterotor对象,在读取时只能按照顺序方式读取,它仅把使用到的数据转换成java实体对象。

uniqueResult()方法:该方法用于返回唯一的结果,在确保只有一条记录的查询时可以使用该方法。

excuteUpdate()方法:该方法时Hibernate的新特性,它支持HQL语句的更新和删除操作。

setFirstResult()方法,该方法可以设置获取第一个记录的位置,也就是它表示从第几条记录开始查询,默认从0开始计算。

setMaxResult()方法:该方法用于设置对象集的最大记录数,通常与setFirstResult()结合使用,用于限制结果集的范围,以及实现分页功能。

6、Criteria

条件查询接口

// 1.简单查询
List<Customer> list = session.createCriteria(Customer.class).list();

// 2.条件查询:
Criteria criteria = session.createCriteria(Customer.class);
criteria.add(Restrictions.eq("name","芙蓉"));
List<Customer> list = criteria.list();

// 3.分页查询:
Criteria criteria = session.createCriteria(Customer.class);
criteria.setFirstResult(3);
criteria.setMaxResults(3);
List<Customer> list = criteria.list();
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: