Hibernate 学习笔记

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集合映射属性






2.3 双向一对多关联
以District和Street两张表为示例
实体类中District类的属性就应该有Street类型的Set集合,Street类中应该有District类对象
District的映射文件中添加set集合映射属性






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

2.4 cascade和inverse
2.4.1 cascade属性
作用是级联在标签中
2.4.2 inverse属性
作用是反转在标签中
2.5 多对多关联
2.5.1 配置多对多关联
必须将一方设置为inverse


















第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)在
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:

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



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 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 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 list = criteria.list();

你可能感兴趣的:(Hibernate)