- 浏览: 25467 次
- 性别:
- 来自: 北京
-
最新评论
-
sprhib:
哥们,这么个写法估计就你能看懂了,对其他人估计没啥帮助。
Hibernate查询缓存中的1+N
文章列表
譬如我访问某个项目的页面,在页面中用到了facesContext对象,也就是用了f标签,这时他会到指定的目录中去找这个类
http://127.0.0.1:8080/project/
我第一时间想到的是web.xml文件出错了,结果一查:
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>/faces/*</url-pattern>
</servlet-mapping>
改成下面的地址就好了 ...
想要从一个Servlet转向另外一个Servlet,可以使用两种方法进行重定向:
forward(或称dispatch) - 服务器端重定向
redirect – 客户端重定向forward
服务器端从一个Servlet转向另外一个Servlet,在一个Servlet中可以通过setAttribute往requ ...
GET与POST,是HTTP协议中的内容,表示客户端向服务器递交请求的方法,GET/POST…等方法在协议中的大概用意是
GET – 获取资源信息
POST – 提交信息
DELETE – 删除资源
HEAD – 响应中不要包含消息体
PUT –创建或修改资源
...
Servlet是单例的,一般Tomcat服务器负责加载我们的Servlet,它会把这个类加载到方法区,同时创建他的对象放到堆里面,但是他只会创建一遍,因此无论你在浏览器中刷新多少次,内容一般都不会变化。
下面的切记:
JavaEE应 ...
查询缓存查找实体对象:
session.beginTransaction();
/**
* 如果查询的是实体对象,在查询缓存中缓存的是实体对象的ID列表,而实体对象本身被放到了二级缓存中,所以查询缓存需要配合二级缓存一起使用。
* 假如二级缓存没有启用,将导致即使是list操作也会发出n条查询语句去查询实体对象! */
String hql = "select p from Person p";
List persons = session.createQuery(hql)
.setCacheable(true) ...
查询缓存:
首先明确查询缓存缓存的是什么?缓存的
key
是
HQL
语句与参数,缓存的
value
则是:
1、
如果查询的是普通结果集,则缓存这些结果集
2、
如果查询的是实体对象,则缓存的是实体对象的
ID
...
假如有两个客户端或者说是两个事务同时去修改同一条数据,就会产生并发的现象,这时候有数据的更新丢失。现在就来模拟下这个并发现象的例子:
客户端
1
或者说是事务
1
:
session.beginTransaction();
Person p = (Person)session.load(Person.class, 1);
//Person p = (Person)session.load(Person.class, 1 ,LockOptions.UPGRADE);
p.setName("士兵乙");
session.getTransact ...
EntityManagerFactory相当于Hibernate中的SessionFactory对象,它里面有一个PersistenUnit就代表着一个EntityManagerFactory以及所包含的映射元数据,代表着一个数据库,如果有两个数据库,就可以在persistence.xml的配置文件中配置两个persistence-unit。EntityManager由EntityManagerFactory所创建,相当于Hibernate中的session,persistenceContext相当于session的一级缓存!由persistenceContext跟数据库进行打交道。
...
一级缓存,即session级缓存,是最最重要的,因为它不能够被取消,现在看看二级缓存.
Hibernate二级缓存不是由本身维护的,它是由第三发缓存框架来提供的。看一下如何使用二级缓存:
1、首先要打开二级缓存
<!-- 配置打开二级缓存 -->
<property name="hibernate.cache.use_second_level_cache">true</property>
2、指定缓存提供商。即有谁来提供缓存的功能
<!-- 指定二级缓存的具体实现! -->
<property n ...
一级缓存中的1+N问题
所谓1+N指的就是:一条查询实体对象的ID列表的查询语句和迭代查询具体的多个实体对象的查询语句
session的load/get或iterate操作会利用缓存,如果缓存中已有实体对象,将不再发出查询语句查询实体对象
session的list操作将不会利用缓存,每次查询,都会发出查询语句
如果查询实体对象,则list操作直接发查询语句把实体对象加载到内存,而iterate操作先发查询语句查ID列表,再发查询语句根据ID逐个查询实体对象
如果查询的是普通结果集,则list和iterate操作将没有区别
看看下面的代码及描述:
//lis ...
缓存相当于Map结构,讲的是命中率,就像Entryset中的key和Value。
Hibernate中的缓存:
一级缓存,也叫session级别的缓存,缓存的是实体
二级缓存,是SessionFactory级别的缓存,缓存的也是实体
查询缓存,也是SessionFactory级别的缓存,它缓存的是普通结果集,但如果缓存的是实体则缓存实体的Id列表
session级别的缓存即一级缓存,不能被取消,它一直存在,随着session的关闭,缓存也会随之失效!sessionFactory级别的缓存是可以取消的,甚至不用
。
现在让我们先来看看session级别的 ...
有一个线程:
public class MyThread extends Thread {
private StringBuffer sb;
public MyThread(String name,StringBuffer sb) {
super(name);
this.sb = sb;
}
@Override
public void run() {
for (int i = 0; i < 10000; i++) {
sb.append("abc");
}
}
}
测试类:
public static void main(String ...
synchronized关键字被添加到实例方法的前面时,只要一个线程访问了其中的一个synchronized方法,其它线程不能同时访问这个对象中任何一个synchronized方法(对象级的锁)
SomeClass中的同步方法:
public synchronized (static) void dosomething() {
...
共享资源(或称临界资源)问题:多个线程同时修改同一个数据(资源),导致最终结果不正确,这是典型的由于并发访问所产生的问题。
线程的内存结构:
当我们每启动一个线程,每个线程都会有一个它自己的栈,所以对于 ...
线程初步:
1、创建线程的两种方式:
通过Thread t = new Thread()创建,需要继承java.lang包中Thread类重写run()方法,然后让t.start()启动线程;
通过实现Runnable接口也重写了run()方法,接着把Runnable创建出来的对象当参数把它传进去
Runnable r = new XxxThread();
new Thread(r).start();
2、后台(daemon)线程 – 在后台提供一种通用服务的线程。当所有非后台线程结束之后,如main方法之类的线程,程序就终止了。
换句话说,即使daemon Thread还在运行, ...