2018-03-12 hibernate练习
在使用hibernate的HQL查询的时候 注意 from 后面的表明为实体类的名称 切区分大小写!!! 且不支持select * from Student这样的查询方式
String hql = "select id from Student where id = 2"; =======>>> 这里的Student 即为对应的实体类 不是表名 !!!
Query query = session.createQuery(hql);
Object stu = query.uniqueResult();
hibernate支持别名方式设置参数
Session session = sf.openSession();
String hql = "select id from Student where name = :name";
Query<Object> query = session.createQuery(hql);
query.setParameter("name", "xiaohua");
Integer i = (Integer) query.uniqueResult(); // 这里注意uniqueResult 无法自动包装
System.out.println(i);
hibernate 支持占位符设置参数
Session session = sf.openSession();
String hql = "select id,name,sex,birth,des from Student where name = ?";
Query query = session.createQuery(hql);
query.setParameter(0, "xiaohua");
List list = query.list();
这里要注意 query.list()
java.lang.ClassCastException:
[Ljava.lang.Object; cannot be cast to bean.PersonStatis居然不能转换。
通过多方验证,这个返回的List中并不是存放的是Student对象,而是存放的查询出来对应于字段顺序的一个数组对象。
于是我们需要通过Object[] obj = list.get(0);然后在根据相应的数组下标取得相应的值
Object[] arr = (Object[]) list.get(0);
System.out.println(arr[0] +"-" +arr[1]);
如果HQL 中不添加要查询的字段(即去掉 select xxx )则不会出现上述的异常!
Session session = sf.openSession();
String hql = "from Student"; ==> 这里去掉了 select子句
Query<Student> query = session.createQuery(hql);
List<Student> list = query.list();
for (Student s : list){
System.out.println(s);
}
HQL也支持 自定义返回类型 同时要注意这里的 new Student(id,name,sex) 对应 Student实体类中的构造器!!!
String hql = "select new Student(id,name,sex) from Student";
Query<Student> query = session.createQuery(hql);
List<Student> list = query.list();
for (Student s : list){
System.out.println(s);
}
返回Map类型 注意下面两种不同的HQL语句 所查出来的结果的查询方式不同!!!
Session session = sf.openSession();
String hql = "select new map(id,name) from Student";
String hql2 = "select new map(id as id,name as name) from Student";
Query<Map> query = session.createQuery(hql);
Query<Map> query2 = session.createQuery(hql2);
List<Map> list = query.list();
List<Map> list2 = query2.list();
for (Map m : list){
System.out.println(m.get("0") +"---"+ m.get("1"));
}
for (Map m : list){
System.out.println(m.get("id") +"---"+ m.get("name"));
}
HQL总结
1、没有select子句有from子句的HQL查询,查询表格的记录,返回的对象是查询类对象;即List<查询类名> list=query.list();
2、有select子句的HQL查询,查询表格记录,返回的对象是Object[]类对象,即List<Object[]> lsit=query.lsit();
3、我们可以通过在HQL语句中使用new list(...),new map(...),new Students2(...)的方式来指定查询返回的对象类型。
4、使用new Students2(...)的方式,即以自定义类型返回的方式,需要在该查询类的持久化类Students2.java中添加相应的构造函数
QBC查询
QBE查询
hibernate 缓存机制
一级缓存
Hibernate的一级缓存由Session提供,只存在于Session的生命周期中,当应用程序调用Session接口的
save(),update(),saveOrupDate(),get(),load()或者Query和Criteria实例的list(),iterate()等方法时
如果Session缓存中没有相应的对象,hibernate就会把对象加入到一级缓存中,当session关闭时,该Session所管理的一级缓存也会立即被清除;
hibernate 清理一级缓存的时机
(1)调用 事务的commit()方法时会自动清理缓存
(2)调用query 查询对象时 如果对象的属性发生了变化 则会自动清理缓存
(3)显示调用session.flush()时会自动清理缓存
(4)关闭session时 清理缓存
一级缓存由session(轻量级,线程不安全单位)提供 所以一般生命周期为一个事务的生命周期 事务开始打开 事务提交被关闭
二级缓存由sessionFactory (重量级,线程安全单位)提供 所以一般生命的周期为进程获取群集的周期
Hibernate java对象的三态变化
临时态 <—> 持久态 <—> 游离态
临时态 ===> 持久态 save() saveOrUpdate() 此时不存在session缓存中,数据库中也没有对应的记录
持久态 ===> 游离态 evict() clear() close()
游离态,持久态 ===> 临时态 delete()
游离态 ===> 持久态 update() saveOrUpdate() lock()
Hibernate 运行原理