初识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();
相关文章推荐
- 初识Hibernate 缓存
- 'Hibernate 完全手册' 读书笔记(二) 初识、体系、对象标识符、配置、映射类型
- 初识Hibernate
- hibernate学习(二)----初识标签
- 千里之行,始于足下之:初识Hibernate
- Hibernate 之 初识 uuid 和 native
- hibernate初识
- Hibernate初识
- hibernate--初识
- 深入浅出学习Hibernate框架(一):从实例入手初识Hibernate框架
- Hibernate4自学入门(一)——初识Hibernate
- 初识Hibernate
- Hibernate框架学习之初识Hibernate
- 初识hibernate框架之一:进行简单的增删改查操作
- 初识Hibernate
- 初识hibernate——基础与核心
- 初识hibernate
- 初识Hibernate
- 【Hibernate】——初识hibernate
- 初识Hibernate之继承映射