对象的状态
一、对象的状态
1. 临时状态:与数据库没有对应,跟Session没有关联。一般是新new出的对象。
2. 持久化状态:对象在Session的管理之中,最终会有对应的数据库记录。
特点:有OID、对对象的修改会同步到数据库。
3. 游离状态:数据库中有对象对应记录,但对象不再Session管理之中。修改此状态对象的数据不会又变化。
4. 删除状态:执行了delete()后的对象。
5. 持久化与游离态的区别:只在于对象有没有ID
二、Session操作对象的方法
1. 操作实体对象:
1) Save():将临时态变为持久态,把对象存入数据库中。即将对象交给Session管理。会生成:insert into … 。数据的保存立刻完成。
2) Update():将游离态变为持久态,会生成update …,在更新时,对象不存在就报错。数据的更新是在事务提交时完成。
3) SaveOrUpdate():把临时或游离态转为持久状态,会生成:insert into 或 update…。更新时对象不存在就报错。
本方法是根据id判断对象是什么状态的:如果id为原始值(对象的是null,原始类型数字是0)就是临时状态,如果不是原始值就是游离状态。
4) Delete():把持久化或游离转为删除状态,会生成:delete…,如果删除不存在对象,就会抛出异常。数据的删除是在事务提交时完成的。
2. 操作缓存
1) Clear():清除Session中的所有对象,其中的这些对象变为游离态。
2) Evict(Object):清除Session中一个指定的对象。
3) Flush():将session中的数据刷入到数据库中。即例如update、delete等操作提前于事务提交执行。执行flush后立刻执行。
3. 查询实体对象
1) Get():获取数据,是持久化状态,生成:select … where id=?,马上执行SQL语句,如果数据不存在返回null。
2) Load():获取数据,是持久态,生成:select … where id=?。
a) Load属于懒加载方式:不会马上执行SQL语句,而是在第一次使用非id或class属(因为这些属性在获取对象时已经给出)性时执行SQL。
b) 禁止来加载的方式:1.把实体写成final的;2.在hbm.xml中写
<class … lazy=”false”>
c) Load()后返回的是一个代理对象,要求类不能是final的,否则不能生成子类代理,就不能使用懒加载功能了。
d) 如果数据不存在,就抛出异常:ObjectNotFoundException。
3) createQuery():执行HQL语言,返回查询结果。
4) createCriteria():
4. get和load的区别
|
加载方式 |
返回值 |
如果数据不存在 |
get |
立即加载 |
真实对象或null |
返回null |
load |
懒加载 |
代理对象 |
抛出异常 |
HQL语言
1. 特点:
1) 与SQL相似,SQL中的语法基本上都可以直接使用。
2) SQL查询的是表和表中的列;HQL查询的是对象与对象中的属性。
3) HQL的关键字不区分大小写,类名与属性名区分大小写。
4) Select可以省略。
2. 简单查询语句:session.creatQuery(hql).list()
1) 使用别名(as关键字可以省略):hql = “FROM Employee e”;
2) 带上过滤条件的:From Employee e where id<10;
3) 带上排序条件的:From Employee e where e.id<10 Order By e.id;
4) 指定查询结果的(不可以使用select *):
Select e.id,e.name From Employee e Where e.id<10 OrderBy e.id;
5) 执行分页查询,获取多个或单个结果:
List list = session.createQuery(hpl)
.setFirstResult(firstResult)
.setMaxResult(maxResult)
.list();
Int result = session.createQuery(“Select count(*) fromEmployee”).uniqueResult();
3. 聚合函数(count()、max()、min()、avg()、sum()):
1) Count():SelectCount(*) From Employee e;
2) Max():selectMax(id) From Employee e;
3) Avg():selectavg(id) From Employee e;
4) Sum():selectsum(id) From Employee;
4. 分组:Group By … Having
Select e.name, Count(*) From Employee e where e.id >10Group By e.name Having Count(e.id)>1;
5. 连接查询/HQL是面向对象的查询
1) 内连接:SELECT e.name,COUNT(e.id) FROM Employee e GROUP BY e.name
2) 左外连接:
SELECT e.name,COUNT(e.id) FROM Employee e GROUP BY e.nameHAVING count(e.id)>1
3) 右外连接:
SELECT e.name,COUNT(e.id) FROM Employee e WHERE id<9GROUP BY e.name HAVING count(e.id)>1
4) 更方便的使用(常用):
Select e.id,e.name, e.department.name From Employee e
6. 查询时使用参数:
1) 方式一:使用’?’占位(不常用)
a) hpl=”From Employee e Where idBetween ? And ?;”
b) List list = session.createQuery(hpl)
.setParameter(0, 5)
.setParameter(1, 15)
.list();
2) 方式二:使用变量名(最常用)
a) hpl = “From Employee e Where idBetween :idMin And :idMax;”
b) List list = session.createQuery(hpl)
.setParameter(“idMin” , 5)
.setParameter(“idMax”, 15)
.list();
3) 参数为集合时:
a) hql :”FromEmployee e Where id IN ( :ids );”
b) List list = session.createQuery(hpl)
.setParameterList(”ids”,new Object[] {…})
.list();
7. 使用命名查询:
1) 配置映射文件:
2) 查询:
List list = session.createQuery("queryByIdRange”)
.setParameter(“idMin” ,5)
.setParameter(“idMax” ,15)
.list();
8. Update与delete,不会通知Session缓存
1) Update:intresult = session.createQuery(
“Update Employee e set e.name= :newName Where e.id> :idMin “)
.setParameter(“newName”, “新名字”)
.setParameter(“idMin” , 5)
.executeUpdate();
2) Delete:int result =session.createQuery(
“Delete From Employee e Where e.id > :idMin”)
.setParameter(“idMin” , 10)
.executeUpdate();
9. 使用QBC方式查询:
1) 创建Criteria对象:
Criteria criteria = new Ctiteria(Employee.class);
2) 增加过滤条件:
Criteria.add( Restrictions.ge(“id” , 1));
Criteria.add( Restrictions.le(“id” , 10));
3) 增加排序条件:
criteria.addOrder(Order.desc("name"));
criteria.addOrder(Order.desc("id"));
4) 查询结果:
List list = criteria.list();
懒加载特性
1. extra策略:与 lazy=“true” 类似。主要区别是增强延迟检索策略能进一步延迟对象中集合代理,集合中存放实例的初始化时机:
1) 当程序第一次访问懒加载对象 的 iterator() 方法时, 会导致代理类实例的初始化
2) 当程序第一次访问懒加载对象 属性的 size(),contains() 和 isEmpty() 方法时, Hibernate 不会初始化懒加载对象集合类的实例, 仅通过特定的 select 语句查询必要的信息, 不会检索所有的懒加载对象 。
2. 懒加载
也叫延迟加载,不是在执行获取操作时马上生成SQL,而是在第一次使用时生成SQL。
l 加载方式:
1) 类级别的:<class … lazy=”true/false”>
2) 属性级别的:
a) <set/list/map/bag … lazy=”true/fasle/extra” >
b) <many-to-one … lazy=” true/fasle/extra” >
c) <one-to-one … lazy=” true/fasle/extra” >
l 在使用懒加载特性是,可能会抛出LazyInitializationException异常
1) 原因:已关闭session后,再真正的去获取数据是,Session已经没有了。
2) 解决办法:
a) 让Session在真正加载后再关闭。
b) 在Session关闭前执行Hibernate.initialize(department.getEmployees());,即使用Hibernate中提供的静态方法,来获取数据。
获取数据的方式小结
1. 通过对象获取:获取指定Id的对象
1) session.get(“Employee.class”,1)
2) session.load(“Employee.class”,1)
2. 通过HQL语句获取对象:Query query = session.creatQuery("hql语句”);
1) 获取多值结果:
a) List():返回List集合。
b) Iterator:返回多值结果集合的迭代器。
2) 获取单值结果: UniqueResult()