您的位置:首页 > 其它

Hibernate 学习笔记

2013-04-08 11:58 316 查看
Hibernate学习笔记

第一章Hibernate入门

1.1 Hibernate制胜

1.1.1 JDBC的困扰

重复性的编码工作没有任何创造性,而且容易出错

1.1.2 Hibernate的优势

Hibernate是一个优秀的Java持久化层解决方案,Hibernate简化了JDBC繁琐的编码

1.1.3 持久化与ORM

持久化:程序运行的时候,有些程序数据保存在内存中,当程序推出后,这些数据就不复存在了,所以,我们称这些数据的状态为瞬时的(Transient)。有些数据,在程序退出后,还以文件等形式保存在存储设备中,我们称这些数据的状态是持久的(Persistent)。持久化是将程序中的数据在瞬时状态和持久化状态间转换的机制。

ORM(Object Relational Mapping 对象关系映射):在编写程序的时候,以面对对象的方式处理数据;保存数据的时候,却以关系型数据库方式存储,所以,客观上我们需要一种能在两者间进行转换的机制,这样的机制就是ORM(对象关系映射)。

1.2 Hibernate入门

1.2.1 准备Hibernate

1、下载需要的jar包

2、编写hibernate.cfg.xml文件

3、在src目录下添加log4j.properties文件

4、创建实体类的实体映射文件

1.3 使用Hibernate操作数据库

1.3.1 使用Hibernate实现数据库的增、删、改操作

1、增加 session.save(obj);

2、删除 Object obj = session.get(Object.class, 1L);

session.delete(obj);

3、更改 session.update(obj);

1.3.2 使用Hibernate实现对数据库的查询操作

1、Object obj = session.get(Object.class, 1L);
//查询出来的是一个实例对象

2、Object obj = session.load(Object.class, 2L);
//查询出来的是一个只有id的代理对象

1.3.3 Hibernate中实体对象的三种状态

以实体类User的对象为例演示Hibernate的三种状态

1、在使用进行持久化操作前,实例化 User 对象,此时,User 对象并未与数据库中的数据有任何的关系,这是User对象的状态为瞬时状态(Transient)。

解释:所谓 Transient 即实体对象在内存中瞬时存在,它与数据库中的记录无关。

2、当使用 Session 的 get 方法或者 load 方法加载数据库中一条数据的时候,返回的 User 对象是与数据库中的一条数据关联的,此时 User 对象为持久化状态(Persistent)。

解释:所谓 Persistent,即实体对象处于由 Hibernate 框架所管理的状态。这种状态下,实体对象的引用被纳入 Session 实例中加以管理。处于持久状态的对象,其变更将有 Hibernate 固化到数据库中。

3、处于持久化状态的对象,其对应的 Session 实例关闭之后,User 对象的各个属性的值与数据库中一条书库的数学组是对应的,但是此时 User 对象并受到 Session 实例的管理,所以此时的 User 对象处于游离状态(Detached)。

解释:Session 实例可以看作是 Persistent 对象的宿主,一旦此宿主失效,那么其从属的持久状态的对象即进入游离状态。

第二章 Hibernate的关联映射

2.1 单向多对一关联

2.1.1 实现关联关系

实体之间的关系主要有以下两种

关联关系:如用户可以发布多条信息,这就是表示用户和信息之间存在关联关系。

泛化关系:如老虎是动物,就表示老虎和动物之间存在着泛化关系。

解释:实体之间的关联关系:关联是指不同表之间的数据彼此联系的方法。数据库的表与表之间的关联关系,以外键的形式体现。

经验:数据关联是ORM的一个重要特征,但往往也是导致系统性能低下的原因。不良的关联设计会对系统的性能表现产生致命的影响,在实际卡发中我们需要特别注意这一点。

2.1.2 配置单向多对一关联

以District和Street两张表为示例

实体类中数据库中表就是类名,列名就是属性

添加数据时(many-to-one):逐一添加

2.2 单向一对多关联

以District和Street两张表为示例

实体类中District类的属性就应该有Street类型的Set集合

District的映射文件中添加set集合映射属性

<set name="streets" table="street">

<key>

<column name="district_id"/>

</key>

<ont-to-many class="Street"/>

</set>

2.3 双向一对多关联

以District和Street两张表为示例

实体类中District类的属性就应该有Street类型的Set集合,Street类中应该有District类对象

District的映射文件中添加set集合映射属性

<set name="streets" table="street">

<key>

<column name="district_id"/>

</key>

<ont-to-many class="Street"/>

</set>

Street的映射文件添加many-to-one属性

<many-to-one name="district" class="District" column="distrct_id" />

2.4 cascade和inverse

2.4.1 cascade属性

作用是级联在<set>标签中

2.4.2 inverse属性

作用是反转在<set>标签中

2.5 多对多关联

2.5.1 配置多对多关联

必须将一方设置为inverse

<!-- Project一方的设置 -->

<set name="Project" table="Project">

<key>

<column name="Project_id"/>

</key>

<ont-to-many class="Employe"/>

</set>

<!-- Employe一方的设置 -->

<set name="Employe" table="Employe">

<key>

<column name="Employe_id"/>

</key>

<ont-to-many class="Project"/>

</set>

第3章 HQL使用技术

3.1 Hibernaet 查询语言

3.1.1 为什么使用 HQL

因为JDBC代码繁琐,容易出错

3.1.2 如何使用 HQL

1、得到session

2、编写 HQL 语句

3、创建 Query 对象

4.、执行查询,得到结果。

3.2 实体查询

3.2.1 where子句

示例:String hql = "from Street as s where s.name='南门大街'";

3.3 属性查询

示例: String hql = "select u.username from Users as u where u.username='admin'";

Query query = session.createQuery(hql);

List list = query.list();

Iterator it = list.iterator();

if(it.hasNext()){

syso.(it.next());

}

3.4 参数绑定

1、"?"占位符
String hql = "select user.password form Users as user where user.name=? and user.password=?";

Query query = session.createQuery(hql);

query.setString(0,"admin");

query.setString(1,"123");

2、命名参数
String hql = "select user.password form Users as user where user.name=:name and user.password=:pass";

Query query = session.createQuery(hql);

query.setString("name","admin");

query.setString("pass","123");

3.5 使用聚合函数

select count(*) from Users

select max(age),min(age) from Users

select avg(age) from Users;

select sum(age) from Users;

3.6 排序

from House house order by house.price;

from House house order by house.price desc;

from House house order by house.price,house.id

3.7 分组

select sum(house.price) from House house group by house.street_id having sum(house.price) > 1000'

3.8 分页

int count = list.size();

int pageSize = 3;

int pageNow = 1;

int totalPages = (count%pageSize==0)?(count/pageSize):(count/pageSize+1);

query.setFirstResult((pageNow-1)*pageSize);

query.setMaxResult(pageSize);

List list = query.list();

3.9 子查询

select * from House as h1 where h1.price>(slect avg(h2.price) from House h2 where he.street_id = '1000');

第4章 HQL进阶

4.1 HQL查询性能优化

4.1.1 HQL优化

1、避免or操作,尽量使用in条件来替换

2、避免使用not建议使用 不大于、不小于条件

3、避免使用like的特殊形式

4、避免使用having子句,经历的在where子句中写条件

5、编码使用distinct(清除重复的记录)

4.1.2 数据加载方式

1、即时加载(Immediate Loading)

2、延迟加载(Lazy Loading)在<property lazy="true"/>

4.1.3 list()方法和iterate()方法

list()方法将不会在缓存中读取数据,它总是一次性的从数据库中直接查询所有符合条件的数据,同时将获取的数据写入缓存中。

iterate()方法则是获取了符合条件的数据的id后,首先根据id在缓存中寻找符合条件的数据,若缓存中无符合条件的数据,再到数据库中查询。

4.2 HQL连接查询

4.2.1 内连接
from entity inner join [fetch] entity.property;

4.2.2 外连接
from entity (left/right) join [fetch] entity.proprty;

4.2.3 其他多表查询方式 from entity1,entity2 where ……

4.3 命名查询

4.3.1 命名查询
太麻烦就是用query.append()拼接SQL语句

4.4 本地SQL查询

示例1:

String sql = "select {u.*} from users u where u.name='admin'";

SQLQuery query = session.createSQLQuery(sql).addEntity("u",Users.class);

示例2:

String sql = "select {u.*},{h.*} from users as u"+"house as h where u.id=h.user_id";

SQLQuery query = session.createSQLQuery(sql).addEntity("u",Users.class).addEntity("h",House.class);

示例3:

<sql-query name="findUserHouse">

<![CDATA[

select {u.*},{h.*} from users as u,house as h where u.id=h.user_id

]]>

<return alias="u" class="Users" />

<return alias="h" class="House" />

</sql-query>

Query query = session.createQuery("findUserHouse");

第5章 Criteria查询

5.1 Criteria查询

5.1.1 Criteria查询表达式

Criteria criteria = session.createCriteria(Users.class);

criteria.add(Restrictions.eq("name","admin"));

List<Users> list = criteria.list();

5.1.2 使用Example

Users user = Users(1L,"admin","123");

Criteria criteria = session.createCriteria(Users.class);

criteria.add(Example.create(user));

Users u = criteria.list.get(0);

5.2 Criteria高级特性

5.2.1 Criteria查询排序

Criteria criteria = session.createCriteria(Users.class);

criteria.add(Order.desc("id"));

List<Users> list = criteria.list();

5.2.2 限定返回数据行数

Criteria criteria = session.createCriteria(Users.class);

criteria.add(Restrictions.eq("name","admin"));

criteria.setFirsResult(3);

criteria.setMaxResult(2);

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