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集合映射属性
<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();
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值