HIbernate简介
1、hibernate是什么?
A、它是连接Java应用程序和关系数据库的中间件。
B、它对JDBC API进行了封装,负责Java对象的持久化。
C、在分层的软件架构中它位于持久层,封装了所有数据访问细节,使业务层可以专注于实现业务逻辑。
D、它是一种ORM映射工具,能够建立面向对象的域模型和关系数据模型之间的映射。
Hibernate的三个组件: 连接管理组件,事务管理组件,对象/关系映射组件
2、软件的三种模型:概念模型,域模型,数据模型。
3、三层结构:
表述层:提供与用户交互的界面。GUI(图形用户界面)和Web页面是表述层的两个 典型的例子。
业务逻辑层:实现各种业务逻辑。
数据库层:负责存放和管理应用的持久性业务逻辑。
4、软件的分层:物理分层--两层,业务逻辑层和数据库层运行在同一台机器上。
逻辑分层--三层。
5、软件的层必须符合一下特点:
A:每一层由一组相关的类或组件(如EJB)构成,共同完成特定的功能。
B:层与层之间存在自上而下的依赖关系,即上层组件会访问下层的API,而下层的组件不能访问上层。
6、业务逻辑层不仅负责业务逻辑,而且直接访问数据库,提供对数据库的保存、更新、删除和查新操作。为了把数据访问细节二环业务逻辑分开,可以把数据访问作为单独的持久化层。
7、中间件:中间件是在应用程序和系统程序之间的连接管道。
hibernate可以看成是连接Java和关系数据库的管道。中间件和普通的应用程序代码的区别在于,前者据有很高的可重用性,对于各种应用领域都适用,后者和特定的业务功能有关,不同业务领域的应用程序代码显然不一样。
8、软件的模型:模型用来表示真实世界的实体。
在软件开发的不同阶段,需要为目标系统创建不同类型的模型。在分析阶段,需要创建概念模型,在设计阶段,需要创建域模型和数据模型。
9、实体的生命周期:
Transient:瞬态 persistent:持久态 detached:游离态
Transient(瞬态):
表示该实体对象在内存中是自由存在的,也就是说与数据库中的数据没有任何关系。
该实体从未与任何持久化上下文关联过,它没有持久化标识(相当于主键)。
特点:
A:与数据库中的记录没有任何联系,也就是说没有与其相关联的数据库记录。
B:与Session没有任何联系,也就是没有通过Session对象的实例对其进行过任何持久化的操作。
Persistent(持久态)
所谓持久态,是指该实体对象处于Hibernate框架所管理的状态,也就是说这个实体对象是与Session对象的实例相关的。处于吃就态的对象的最大特征是对其所作的任何变更操作都将被Hibernian持久化到数据库中。
特征:
A:每个persistent状态的实体对象都与一个Session对象的实例相关联。
B:处于persistent状态的实体对象与数据库中的记录相关联的。
C:hibernate会依据persistent状态的实体对象的属性变化而改变数据库中相对应的记录。
Detached(游离态)
所谓游离态,是指处于persistent状态的对象,当不再与它所对应的Session对象相关联时,这个对象就变成了游离态。
Hibernate API
1、应用程序可以直接通过hibernate api访问数据库。hibernate api中的接口可以分为以下几类:
A:提供数据库的操作(如保存,更新,删除和查询对象)的接口。这些包包括:Session,Transaction和Query接口。
B:用于配置hibernate的接口:configuration.
C:回调接口,使应用程序接受hibernate内部发生的事件,并做出相关的回应。这些接口包括:Interceptor,Lifecycle,Validatable接口。
D:用于扩展hibernate的功能的接口。如 UserType,CompositeUserType和IdentifierGenerator接口。如果需要的话,应用程序可以扩展这些接口。
2、Hibernate的核心接口
所有的Hibernate应用中都会访问hiberante的5个核心接口:
A:Configuration接口:配置hibernate,根启动hibernate,创建SessionFactory对象。
B: SessionFactory接口:初始化hibernate,充当数据存储源的代理,创建Session对象。
C: Session接口:负责保存、更新、删除、加载和查询对象。
D: Transaction:管理事物。
E: Query和Criteria接口:执行数据库查询。
1、 Configuration接口
Configuration对象用于配置并且启动hibernate。Hibernate应用通过Configuration实例来
指定对象—关系映射文件的位置或着动态配置Hibernate的属性,然后创建SessionFactory.
实例。
2、 SessionFactory接口
一个SessionFactory实例对应一个数据存储源,应用从SessionFactory中获得Session实例。
SessionFactory有一下特点:
A:它是现成安全的,这意味着它的同一个实例可以被应用的多个线程共享。
B: 它是重量级的,这意味着不能随意创建或销毁它的实例。如果应用访问一个数据库。只
需创建一个SessionFactory实例,在应用初始化的时候创建该实例。如果应用同时访问多个
数据库,则需要为每个数据库创建一个单独的SessionFactory实例。
SessionFactory中保存了对应当前数据库配置的所有映射关系,它是将某个数据库的所有映射关系经过编译后保存在内存中。
3、Session接口
Session接口是Hibernate应用使用最广泛的接口。Session接口也被成为持久化管理器,是Hibernian的持久话管理器的核心,也是Transaction的工厂。它提供了和持久化相关的操作,如添加和更新对象。(Hibernate中的Session和HttpSessionzh中的Session没有任何关系。)。
Session有一下特点:
A:不是线程安全的,因此在设计软件架构时,应该避免多个线程共享一个Session实例。
B: Session实例是轻量级的,它的创建和销毁不需要消耗太多资源。这意味着程序中可以
经常创建和销毁Session对象。
4、Transaction接口
Transaction接口是hiberante的数据库事物接口,它对底层的事物接口做了封装,底层事物
接口包括:
A :JDBC API
B: JTA API
C :CORBA API
5、Query和Criteria接口
Query和Criteria接口是hibernate的查询接口,用于向数据库查询对象,以及控制执行查询的过程。Query实例包装了一个HQL(Hiberniate Query Language)查询语句,HQL查询语句与SQL查询语句有些相似,但HQL查询语句是面向对象的,它引用类名及类的属性名,而不是表名及表的字段名。Criteria 接口完全封装了基于字符串形式的查询语句,比Query接口更加面向对象,Criteria接口擅长执行动态查询。
Session接口的find()方法也具有数据查询功能,但它执行一些简单的HQL查询语句的
快捷方法,它的功能远没有Query接口强大。
ConnectionProvider:
主要用于生成与数据库建立了连接的JDBC对象,同时,它还将作为数据库连接的缓冲池。通过ConnectionProvider对象实现了应用程序和底层的Datasource和DriverManager的隔离。
这就为使用各种不同的Datasource和DriverManage提供了可能。
TransactionFactory:
TransactionFactory是生成Transaction对象的工厂,通过TransactionFactory实现了对事物的
封装,使其具体的实现方法与应用程序无关。
回调接口
Hibernate 映射类型接口
可供扩展的接口
Hibernate 入门
1、hibernate----应用程序
A:创建hibernate的配置文件
B:创建持久化类
C:创建对象—关系映射文件
D:通过hibernate api编写访问数据库的代码
2、 创建hibernate配置文件
Hibernate从其配置文件中读取和数据库连接有关的信息,这个配置应该位于应用的classpath中。
Hibernate配置文件有两种形式:A:XML格式的文件 B:Java属性文件,采用 键=值 的形式,默认名为hibernate.properties。
持久化类:如果属性为boolean类型,那么它的方法即可以用get,也可以用is.其他的必须用get,否则会报错。一下两种方法是等价的:
Public Boolean isMarried(){
Return married;
} 或者
Public Boolean getMarried(){
Return married;
}
Hibernate 并不要求持久化类必须实现java.io.Serializable接口,但是对于分布式结构的Java应用,当Java对象在不同的进程节点之间传输时,这个对象的类必须实现Serializable接口。在Java Web 应用中,如果希望对HttpSession中存放的Java对象进行持久化,那么
这个java对象所属的类也必须实现Serializable接口。
Hibernian 要求持久化类必须提供一个不带参数的默认构造方法,在程序运行时,hibernate
运行Java反射机制,调用java.lang.reflect.Constructor.newInstance()方法来构造持久话类的实例。
3、 创建对象—关系映射文件
在Hibernian中采用XML格式的来对象关系数据之间的映射。 类名.hbm..xml
//HBM 根元素,指定PoJo类所在的包
<hibernate-mapping package="org.lxh.hibernate.demo01">
//指定Person类与PERSON表的映射
<class name="Person" table="PERSON">
//name:表名Person类中的属性名
//colume:表示表中的字段名
//type:
<id name="id" column="ID" type="string">
//说明主键的生成方式
<generator class="asigned"/>
</id>
//表示Person类中与表中其它字段的映射
//name: Person类中的属性名称
//column:表中的字段名称
//type: 类型
//not-null: 不允许为空
<property name="name" column="NAME" type="string" not-null="true"/>
<property name="password" column="PASSWORD" type="string" not-null="true"/>
<property name="sex" column="SEX" type="string" not-null="true"/> <property name="email" column="EMAIL" type="string" not-null="true"/>
</class>
</hibernate-mapping>
此文件完成Person类到PERSON表的关系
Class :指定类和表的映射。Class包含一个子id元素和多个property子元素。
Id :设定持久化类的OID和表的主键的映射。
Property:设定类的属性和表的字段的映射。
通过Hibernate API 操纵数据库
Public class BusinessService{
Public static SessionFactory sessionFactory;
//初始化hibernate,创建SessionFactory实例
Static{
Try{
//根据默认位置的hibernate配置文件的配置信息,创建一个configuration实例
Configuration config=new Configuration();
config.addClass(Custormer.class);
//创建SessionFactory实例
sessionFactory =config.buildSessionFactory();
}cath(Exception e){e.printStackTrace();}
}
}
}
//查询所有的customer 对象,然后调用printCustomer()方法打印customer 对象信息
Public void findAllCustomers(ServletContext context,OutputStream out)throws Exception{}
//持久化一个customer对象
Public void saveCustomer(Customer customer) throws Excepton{}
//按照OID加载一个customer对象,然后修改它的属性
Public void loadAndUpdateCustomer(Long customer_id,String address)throws Exception{}
//删除所有的customer对象
Public void deleteAllCustomers() throws Exception{
Session session=sessionFactory.openSession();
Transaction tx=null;
Try{
Tx=session.beginTransaction();
Session.delete(“from customer as c”);
Tx.comit();
}catch(Excepton e){
If(tx!=null){
Tx.rollback();
}
Throw e;
}finally{
Session.close();
}
}
通过Hibernate访问session接口
初始化结束后就可以调用SessionFactory实例的openSession()方法来或得Session实例,
然后通过它执行访问数据库的操作。
Session接口提供的部分方法:
A: save(); 把Java对象保存数据库中。
B: update(); 更新数据库中的Java对象。
C:delete(); 把Java对象从数据库中删除。
D:load(); 从数据库中加载Java对象。
E:find(); 从数据库中查询Java对象。
F:get(); 通过标识符得到指定类的持久化对象的实例。通过get()方法只能得到唯一的一个才持久化对象,该对象如果不存在,那么返回值为空(null) 。
G:load(); 通过标识符得到指定类的持久化对象的实例。这个方法和上面的get()方法的区别是应该确保要得到的持久化对象的实例的存在,否则,将会产生异常。
Get()和Loaded()的区别
Session对象的Load()方法和get()方法都可以根据实体对象的id来读取数据库中的记录,并得到与数据库中的记录相对应的实体对象。但这两种方法存在一定区别:
记录不存在时,get()方法返回null,而load()方法将会抛出一个HibernateException异常。Load()方法可以返回实体的代理类实例,而get()方法永远都直接返回实体类。Load()方法可以充分利用Hibernate的内部缓存和二级缓存中的数据,而get()方法则仅仅在Hibernate内部缓存中进行数据查找,如果内部缓存没有则直接执行SQL语句进行数据查询,并生成相对应的实体对象。
H:contains()方法
Contains()方法用于判断一个实体对象是否与当前的Session对象相关联,这个方法可以用来判断一个实体对象是否处于persistent状态。
J: evict():
用于移除一个实体对象与Session对象之间的关联关系,也就是将一个实体对象由persistent状态转变为detached状态。
Session是一个轻量级对象。通常将每个Session实例和一个数据库事物绑定,也就是说,每执行一个数据库事物,都应该先创建一个新的Session实例。如果事物执行中出现异常,应该撤销事物。不论执行成功与否,最后都应该调用Session的close()方法,从而释放Session实例占用的资源。以下代码演示了用Session来执行事物的流程,其中transaction类用来控制事物。
Session session=factory.openSession();
Transaction tx;
Try{
//开始一个事物
Tx=session.beginTransanction();
//执行事物
…………
//提交事物
Tx.commit();
}
Cathch(Eception e){
//如果出现异常,就撤销事物
If(tx!=null) tx.rollback();
Throw e;
}
Finally{
//不管执行成功与否,最后都关闭Session
Session.close();
}
运行session.delete()方法时,Hibernte先执行select语句,查询CUSTOMERS表的所有
Customer对象: select * from CUSTOMERS;
接下来Hibernate根据customer对象的OID,依次删除每个对象:
Delete form CUSTOMERS where ID=1
创建查询对象:
这一类的方法用于创建用户执行数据库查询的查询对象。在Hibernate中,即可以通过Session实例来直接得到某个持久化对象(get()/load()方法),也可以通过创建Query,Criteria或者SQLQuery对象根据不同的条件得到不同的持久化对象。
A:createQuery():
创建一个Query查询接口的实例,该实例可以利用HQL语言进行数据库的查询操作。
B:createCriteria():
创建一个Criteria查询接口的实例。
C: createSQLQuery():
创建一个SQLQuery查询接口的实例。该查询接口通过标准的SQL语句来执行数据的查询操作。
D:createFilter():
通过一个对象的集合以及查询的HQL语句来生成一个Query对象的实例。
Query接口
1、Hibernate具有三种检索方式,分别是HQL检索方式,QBC检索方式和SQL检索方式。
其中HQL(Hbernate Query Language)是面向对象的查询语言,它和SQL查询语言有些相似。这三种方式,HQL检索方式被使用最广泛。
特点:
A:通过各种条件来执行数据库的查询。
B:支持分页查询,并且特别针对不同的数据库做了不同的处理,以此来提高分页查询的效率。
C:支持连接查询。
D:支持分组查询,允许使用having和group by关键字。
E:支持各种聚集函数,例如,sum(),min()和max().
F:支持各种子查询。
G:能够调用自定义函数。
H:支持动态绑定查询参数。
[select/update/delete……] [from……][where……] [group by……[having……]] [order by……]
2、在Hibernate中,是通过Query接口来执行HQL语句并完成对象的检索操作的。
Query用于执行数据库的查询操作,通过Session对象的createQuery()方法可以得到一个Query对象的实例,通过Query对象可以设置查询语句的参数。Query还有三个重要的方法用于指定获取的结果集的范围. setMaxResults(), setFierstResult(), setFetchSize(). 在调用Query对象的list(),iterator(),scroll()方法后将得到查询的结果。使用uniqueResult()可以得到唯一的一个对象的实例。
例子要查询的是 年龄大于20的所有用户对象。
//创建一个Query对象
Query query=session.createQuery(“from User as u where u.age> : userAge”);
//设置动态参数
Query.setInteger(“userAge”,20);
//执行查询语句,返回查询结果
List list=query.list();
4、 创建Query对象
Session.createQuery(); 其中createQuery()方法需要使用一个HQL查询语句作为参数,这个查询语句中可以包括一系列的查询参数。
5、 设置动态参数
对于查询中使用的参数要设置其具体的值,是Query对象所提供的一系列的setter方法。
setBigDecimal() 设置映射类型为big_decimal的参数值
setBigInteger()
以上每个方法都提供了两种设置参数的方式,一种是根据名称来设置参数,另一种是根据参数的位置来设置参数。
6、 执行查询语句,返回查询结果
为了查询结果的处理方便,Hibernate提供了两种返回结果的方式。使用Query接口的list()方法可以返回任意多数目的符合条件的对象,而使用uniqueResult()方法则只返回第一个满足条件的对象,如果没有满足条件的对象爱,那么返回值为空。
7、 查询参数的处理(建议使用第二种)
A:直接将参数拼接为HQL语句
使用这种方式进行查询时,需要根据不同的参数来动态生成HQL语句。
Form User as u where u.age>20;
B:通过参数名称来标识参数
这种方式为每个参数都定义一个名称,然后通过setter方法来动态设置这些参数的值
C: 按照参数的位置设置参数的值
这种方法需要将HQL语句中的每个参数都使用“?”,然后根据“?”的位置依次设置每个参数的值。
Query query=session.createQuery(“from User as u where u.age>?”);
query.setLong(0,20);/
List list=query.list();
8、 返回查询结果
A:list(); 这个方法返回的是一个List对象,可以按照索引的位置来随机访问结果集中的对象。采用这个方式要求Hibernate将所有的数据都转换为java实体对象,而不管是否用到了其中所有的对象。所以,在只有部分对象被使用时会造成资源浪费。
B:iterator(); 这种方式将返回一个Iterator对象,只能按照从前向后的顺序依次读取数据库中的记录。这种方法的优点是不用一次读取所有的数据并转换为Java对象,避免读取不需要使用的数据而造成资源浪费。缺点是,只能按顺序来访问结果集,并且也不知道结果集中的数目。
C:uniqueResult(); 这个方法返回唯一的结果对象,一般在确信只有一个满足条件的记录时使用此方法。
另外,在Hibernate 3中,还可以使用Query对象来实现数据库的更新操作,也就是通过HQL语句实现一次更新或者删除多个数据库中的记录。对于删除大批量的数据时可以使用此方法,但对于小批量的数据改变,还是使用实体对象逐个更新。
HQL 语言介绍
1、L语言是不区分大小写的,但对于对象和属性的名字则必须区分大小写!!!
HQL的as和where两个子句跟SQL一样,as用来指定对象的别名。HQL几乎支持标准SQL语言中所有查询条件的设定方法,HQL语言所支持的运算符和含义以及使用方法与标准的SQL是完全一致的。
注意:::
A:参与逻辑比较的是实体的属性而不是数据库中字段的名字。
B:在HQL语言中使用的实体对象和实体对象的属性是区分大小写的,而其他的关键字或运算符是不区分大小写的。
C:在like子句中使用的通配符与标准SQL是完全一样的。‘%’表示任意长度的任意字符
‘—’表示任意字符。
D:where子句的优先级别与SQL相同,可以用()改变条件运算的顺序。
2、在实体查询中,所查询的内容是整个对象的所有属性。只需要取出一部分时,可以通过select子句来指定查询的属性。
3、动态构造实例对象
将返回的结果进行封装,使用户可以直接得到实体对象的实例,而不是一个Object对象的数组。
String hsql=”select new User(u.name,u.password)from User u”;
Query query =session.createQuery(hsql);
Iterator it=query.iterator();
While(it.hasnext())
{
//注意查询结果的处理方法
User u=(User)it.next();
System.out.println(u.getName());
System.out.println(u.getPassword());
}
注意:这里返回的Java实体对象仅仅是一个普通的Java对象,仅仅是对查询结果封装。也就是说,使用这种方法得到的实体对象并不是处于持久化状态,不能通过直接修改它的属性值而修改数据库中的数据。
函数:
Count():计算记录的条数。
Min(): 取得最小值。
Max(): 取得最大值。
Sum(): 计算数值的和。
Avg(): 计算数值的平均数。