posts - 19, comments - 32, trackbacks - 0, articles - 51
  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

2015年4月24日

同事遇到问题是一个java web 工程,依赖了一个jar包,但是jar包中也有自己一套配置文件(例spring 配置文件,资源文件等),这样如果让web工程中的war 包去加载jar 中的配置文件和资源文件呢?
我当时也有一个思想误区,以为web中加载不到jar中的文件,但是经过一番研究,终于明白了,按J2EE规范中web-inf/lib目录下是web工程的classpath 目录,容器会自动去扫描这个目录下所有的配置文件和jar加载到容器中,即:像jar中有自己一套配置文件,war 中又要依赖jar包,这样只需要把这些jar包打成war时候放到web-inf/lib下即可。
注意:1:jar包和war包中配置文件和一些资源文件不能重名。
        
         2:要在war包中的spring 配置文件中引入jar包中的配置文件。



posted @ 2015-04-24 20:42 张钊钊 阅读(5507) | 评论 (0)编辑 收藏

2014年3月28日

1、不同的tomcat的启动文件startup.sh 中要指定各自的CATALINA_HOME和CATALINA_BASE这两个环境变量。

2、不同的tomcat启动和关闭监听不同的端口

很多人喜欢把CATALINA_HOME和CATALINA_BASE配置到系统环境变量中去,我们不这么做,我们要做的只是把JDK及CLASSPATH配置到环境变量中去即可,因为这个可以通用。
CATALINA_HOME和CATALINA_BASE的区别。简单的说,CATALINA_HOME是Tomcat的安装目 录,CATALINA_BASE是Tomcat的工作目录。如果我们想要运行Tomcat的 多个实例,但是不想安装多个Tomcat软件副本。那么我们可以配置多个工作 目录,每个运行实例独占一个工作目录,但是共享同一个安装目录

下面讲具体的配置方法。

找到Tomcat的startup.sh文件,打开进行编辑。

在文件的开始位置,可以在一大堆注释的后面,加入
export CATALINA_BASE=/usr/ratest/apache-tomcat-7.0.16
export CATALINA_HOME=/usr/ratest/apache-tomcat-7.0.16

/usr/ratest/apache-tomcat-7.0.16这个就是tomcat的安装文件夹位置,不同的tomcat指定相应的文件夹即可。

注意,这两句话一定要在exec “$PRGDIR”/”$EXECUTABLE” start “$@”这句话的前面,我们放在文件的开始位置了,所以,就可以不考虑了。

然后就是要修改shutdown.sh文件,同样在头部加入上面的两行即可,也要在exec “$PRGDIR”/”$EXECUTABLE” stop “$@”的前面。

好了,解决了第一个问题,下面说第二个问题的解决方法。

找到并打开server.xml文件,里面有诸如8080,8009,8443等等端口配置,统一给这些数字加上100,或者1000或者其他什么数字,只要是不跟其他Tomcat或者当前linux上其他服务的端口重复即可。

现在进入Tomcat的bin文件夹,运行./startup.sh看看是不是可以启动多个了。

posted @ 2014-03-28 19:58 张钊钊 阅读(256) | 评论 (0)编辑 收藏

2013年11月6日

1,设置跟路径时,三种方式

在Tomcat默认安装后,tomcat的主目录是webapps/root目录,所以如果想改变tomcat的主目录的话可以如下所做,所以
第一种方法是:
打开C:/Tomcat/conf/server.xml,在<host></host>之间
加入代码:<Context docBase="d:/Tomcat 5.5/webapps/medi" path="" debug="0" reloadable="true"/>
这样重新启动tomcat,我们的主目录就被设置为dolphin这个项目了。

第二种方法是:
将tomcat安装目录下的ROOT下的所有文件全部删除,然后将工程的解压后的文件全部拷进去。

第三种方法是:
Tomcat5.0以下版本在d:/Tomcat/conf/Catalina/localhost目录下会自动生成了一个ROOT.Xml,
但是5.0以上版本不再生成此文件,所以可以新建个ROOT.xml,在里面加入如下代码:
<?Xml version='1.0' encoding='utf-8'?>
<Context crossContext="true" docBase="d:/Tomcat 5.5/webapps/medi" path="" reloadable="true">
</Context>

2,注意
此时即然配置了 默认访问目录,则不要再tomcat 部署工程了,
比如 在 conf\Catalina\localhost 增加配置文件 指定的工程路径 此文件要去掉, 否则会重复加载工程。

posted @ 2013-11-06 18:44 张钊钊 阅读(404) | 评论 (0)编辑 收藏

2013年10月30日

很多tomcat进程退出(或者进程假死),都是由于频繁的抛出OutOfMemeoryError导致的。

为了让tomcat退出前或者发生OutOfMemeoryError时自动dump堆栈信息,方便事后排查问题,我们可以做如下操作:

1、 在tomcat启动参数中加入两个参数 -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/export/home/tomcat/domains/server2/oom.hprof

2、 重启tomcat

参数说明
(1)-XX:+HeapDumpOnOutOfMemoryError 表示当JVM发生OOM时,自动生成DUMP文件。
(2)-XX:HeapDumpPath=存储文件/目录 表示生成DUMP文件的路径

posted @ 2013-10-30 13:51 张钊钊 阅读(4331) | 评论 (2)编辑 收藏

2012年10月17日

想从JAVA转到obj-c,看了些基础的东西,感觉很奇怪,可能不太习惯,在网上看到一个不错文章有助理解obj-c的一些核心机制。

Objective-C——消息、Category和Protocol

2012-06-22 20:13 by 池建强, 2627 阅读, 11 评论, 收藏, 编辑

面向对象永远是个可以吐槽的话题,从开始提出到推崇备至,到充满质疑,一路走来让人唏嘘不已。面向对象的思想可谓历史悠久,20世纪70年代的Smalltalk可以说是面向对象语言的经典,直到今天我们依然将这门语言视为面向对象语言的基础。
面向对象是大部分编程语言的基本特性,像 C++、Java、Objective-C这样的静态语言,Ruby、Python这样的动态语言都是面向对象的语言。但是如何编写面向对象的程序却一直是困扰人们的话题,即使是Smalltalk,也有人认为这是一个有缺陷的面向对象的语言实现。
 
我在2010年翻译过的一篇InfoQ的文章,《面向对象编程──走错了路》中提到,面向对象编程的三个原则是:基于消息传递机制,对象分离和多态。文章中还举了Erlang例子,认为Erlang具备了这些原则,“所以可能是唯一的面向对象语言”。除了之前提到的三个特征,单继承和动态类型也被引用为面向对象语言的“绝对需求”。基于这些考虑,文章指出,Smalltalk在实现对象思想时的“错误”──例如,只关注状态和行为,在类和基于映像的语言里缺乏良好的并发模型和消息机制。
 
这篇文章中的核心就是,面向对象思想中除了对象的状态、行为,还应该关注其并发机制、消息机制,后者更为重要。这一点事实上是我在接触了Objective-C之后才有了更深入的体会。
 
Ojbective-C的语法设计主要基于Smalltalk,除了提供传统的面向对象编程特性之外,还增加了很多类似动态语言Ruby、Python才具有的特性,例如动态类型、动态加载、动态绑定等等,同时强化了消息传递机制和表意(Intention Revealing Interface)接口的概念。
 
—消息—
消息传递模型(Message Passing)是Objective-C语言的核心机制。在Objective-C中,没有方法调用这种说法,只有消息传递。在C++或Java中调用某个类的方法,在Objective-C中是给该类发送一个消息。在C++或Java里,类与类的行为方法之间的关系非常紧密,一个方法必定属于一个类,且于编译时就已经绑定在一起,所以你不可能调用一个类里没有的方法。而在Objective-C中就比较简单了,类和消息之间是松耦合的,方法调用只是向某个类发送一个消息,该类可以在运行时再确定怎么处理接受到的消息。也就是说,一个类不保证一定会响应接收到的消息,如果收到了一个无法处理的消息,那么程序就是简单报一个错。甚至你可以向一个值为nil的空对象发送消息,系统都不会出错或宕掉。这种设计本身也比较符合软件的隐喻。
 
在表意接口(Intention Revealing Interface)方面,Objective-C也是设计的比较出色的语言。面向对象语言的特性之一就是通过API把实现封装起来,为上层建筑提供服务。但是需要注意的一点就是,你封装的API最好能够让调用者看到接口描述就知道怎么使用。如果为了使用一个API必须要去研究它的实现,那么就失去了封装的意义。Objective-C通过显式的API描述,让开发者不自觉的写出满足表意接口的API,比如下图中的API描述。

 
上图中描述了一个传统意义的实例方法,但和Java或C++不同的是,其方法关键字由多个字符串组成,在这个例子是insertObject和atIndex,(id)anObject和 (NSUInterger)index分别表示参数类型和参数名称。整个方法看上去就像一个英语句子,我们可以很容易的知道,这个方法就是在索引为 index处插入一个对象。如果你是从其他语言转到Objective-C,那么开始的时候会感觉这种写法有些繁复,但是一旦理解并习惯了你会感受到其巨大的好处,这种写法会强制你写出优美易读的代码和API,而且有了XCode强大的提示功能,再长的方法也是一蹴而就。
 
下面我们来说说多态和继承。
 与Java一样,Objective-C一样不支持多重继承,但是通过类别(Category)和协议(Protocol)可以很好的实现代码复用和扩展。
 
—Category—
首先我们来谈谈Category。
 
Objective-C提供了一种与众不同的方式——Catagory,可以动态的为已经存在的类添加新的行为。这样可以保证类的原始设计规模较小,功能增加时再逐步扩展。使用Category 对类进行扩展时,不需要访问其源代码,也不需要创建子类。Category使用简单的方式,实现了类的相关方法的模块化,把不同的类方法分配到不同的分类文件中。
 
实现起来很简单,我们举例说明。
SomeClass.h
@interface SomeClass : NSObject{
}
-(void) print;
@end 
 
这是类SomeClass的声明文件,其中包含一个实例方法print。如果我们想在不修改原始类、不增加子类的情况下,为该类增加一个hello的方法,只需要简单的定义两个文件 SomeClass+Hello.h和SomeClass+Hello.m,在声明文件和实现文件中用“()”把Category的名称括起来即可。声明文件代码如下:
 
#import "SomeClass.h"
 
@interface SomeClass (Hello)
-(void)hello;
@end
实现文件代码如下
#import "SomeClass+Hello.h"
@implementationSomeClass (Hello)
-(void)hello{
    NSLog (@"name:%@ ", @"Jacky");
}
@end 
其中Hello是Category的名称,如果你用XCode创建Category,那么需要填写的内容包括名称和要扩展的类的名称。这里还有一个约定成俗的习惯,将声明文件和实现文件名称统一采用“原类名+Category”的方式命名。
调用也非常简单,毫无压力,如下:
首先引入Category的声明文件,然后正常调用即可。
#import "SomeClass+Hello.h"
 
SomeClass * sc =[[SomeClass alloc] init];
[sc hello] 
执行结果是:
nameJacky 
 
Category的使用场景:
1、当你在定义类的时候,在某些情况下(例如需求变更),你可能想要为其中的某个或几个类中添加方法。
2、一个类中包含了许多不同的方法需要实现,而这些方法需要不同团队的成员实现
3、当你在使用基础类库中的类时,你可能希望这些类实现一些你需要的方法。
 
遇到以上这些需求,Category可以帮助你解决问题。当然,使用Category也有些问题需要注意,
1、Category可以访问原始类的实例变量,但不能添加变量,如果想添加变量,可以考虑通过继承创建子类。
2、Category可以重载原始类的方法,但不推荐这么做,这么做的后果是你再也不能访问原来的方法。如果确实要重载,正确的选择是创建子类。
3、和普通接口有所区别的是,在分类的实现文件中可以不必实现所有声明的方法,只要你不去调用它。
 
用好Category可以充分利用Objective-C的动态特性,编写出灵活简洁的代码。
 
—Protocol— 
下面我们再来看Protocol。
Protocol,简单来说就是一系列不属于任何类的方法列表,其中声明的方法可以被任何类实现。这种模式一般称为代理(delegation)模式。你通过Protocol定义各种行为,在不同的场景采用不同的实现方式。在iOS和OS X开发中,Apple采用了大量的代理模式来实现MVC中View和Controller的解耦。
 
定义Protocol很简单,在声明文件(h文件)中通过关键字@protocol定义,然后给出Protocol的名称,方法列表,然后用@end表示Protocol结束。在@end指令结束之前定义的方法,都属于这个Protocol。例如:
@protocol ProcessDataDelegate <NSObject>
@required
- (void) processSuccessful: (BOOL)success;

@optional
- (id) submitOrder: (NSNumber *) orderid;
@end
 
以上代码可以单独放在一个h文件中,也可以写在相关类的h文件中,可以视具体情况而定。该Protocol包含两个方法,processSuccessful和submitOrder。这里还有两个关键字,@required和@optional,表示如果要实现这个协议,那么processSuccessful方法是必须要实现的,submitOrder则是可选的,这两个注解关键字是在Objective-C 2.0之后加入的语法特性。如果不注明,那么方法默认是@required的,必须实现。
 
那么如何实现这个Protocol呢,很简单,创建一个普通的Objective-C类,取名为TestAppDelegate,这时会生成一个h文件和m文件。在h文件中引入包含Protocol的h文件,之后声明采用这个Protocol即可,如下:
@interface TestAppDelegate : NSObject<ProcessDataDelegate>;

@end
用尖括号(<...>)括起来的ProcessDataDelegate就是我们创建的Protocol。如果要采用多个Protocol,可以在尖括号内引入多个Protocol 名称,并用逗号隔开即可。例如<ProcessDataDelegate,xxxDelegate>
 
m文件如下:
@implementation TestAppDelegate

- (void) processSuccessful: (BOOL)success{
    if (success) {
        NSLog(@"成功");
    }else {
        NSLog(@"失败");
    }
}

@end 
由于submitOrder方法是可选的,所以我们可以只实现processSuccessful。
 
Protocol一般使用在哪些场景呢?Objective-C里的Protocol和Java语言中的接口很类似,如果一些类之间没有继承关系,但是又具备某些相同的行为,则可以使用 Protocol来描述它们的关系。不同的类,可以遵守同一个Protocol,在不同的场景下注入不同的实例,实现不同的功能。其中最常用的就是委托代理模式,Cocoa框架中大量采用了这种模式实现数据和UI的分离。例如UIView产生的所有事件,都是通过委托的方式交给Controller完成。根据约定,框架中后缀为Delegate的都是Protocol,例如UIApplicationDelegate,UIWebViewDelegate 等,使用时大家可以留意一下,体会其用法。
 
使用Protocol时还需要注意的是:
1、Protocol本身是可以继承的,比如:
@protocol A
     -(void)methodA;
@end
@protocol B <A>
     -(void)methodB;
@end

如果你要实现B,那么methodA和methodB都需要实现。 

2、Protocol是类无关的,任何类都可以实现定义好的Protocol。如果我们想知道某个类是否实现了某个Protocol,还可以使用conformsToProtocol进行判断,如下:
[obj conformsToProtocol:@protocol(ProcessDataDelegate)] 
 
好吧,具体的语言特性这次就介绍这么多。从某种意义上来说,Objective-C是一门古老的语言,发明于1980年。1988年,乔布斯的Next公司获得了Objective-C语言的授权,并开发出了Objective-C的语言库和NEXTSTEP的开发环境。NextStep是以Mach和BSD为基础,Objective-C是其语言和运行库,后来的事大家都清楚,苹果买了Next,乔布斯回归苹果,开始神奇的苹果振兴之路,NextStep成了Max OS X的基础。以后发展越来越好,Objctive-C成了Apple的当家语言,现在基本上是Apple在维护Objctive-C的发展。
 
在苹果的AppStore推出之前,Objective-C一直相对小众,但是其优秀的语言特性似乎一直在为后面的爆发积蓄力量,当苹果平台级的应用出现之后,Objective-C开始大放异彩,静态语言的效率和动态语言的特性得到众多程序员的喜爱,目前它已经以火箭般的速度蹿升TIOBE语言排行版第四位。
 
对于喜爱苹果技术的技术人员来说,Objective-C是你必须深入了解和值得学习的一门语言,希望以后有机会多写一些相关的文章。

转载于:http://www.cnblogs.com/chijianqiang/archive/2012/06/22/objc-category-protocol.html

 

posted @ 2012-10-17 13:49 张钊钊 阅读(239) | 评论 (0)编辑 收藏

2012年6月1日

     摘要: 我们大部分情况使用默认的或者chain或者redirect,其实struts2还有很多其他类型的,今天我们就来看一下都有哪些类型。 struts2的源码中struts-default.xml文件有全部类型下边解释下: 类型 chain 描述 用来处理Action链,被跳转的action中仍能获取上个页面的值,如request信息。 使用的类...  阅读全文

posted @ 2012-06-01 12:56 张钊钊 阅读(294) | 评论 (0)编辑 收藏

2012年5月22日

 org.apache.cxf.binding.soap.SoapFault: "http://schemas.xmlsoap.org/wsdl/" is  not a valid SOAP version.

在写好服务器端测试没有问题,在客户端调用时候出现上面错误,经过分析原面如下:

1:CXF 有两种客户端调用,一种是动态工厂形式, 第二种是通过CXF 中wsdl2java 命令先把客户端类生成到本地,在调用;

第一种: 1:  用org.apache.cxf.jaxws.JaxWsProxyFactoryBean配置

<bean id="msgWebServiceSoap" class="com.jd.sms.MsgWebServiceSoap" factory-bean="msgClientFactory"
          factory-method="create"/>
    <bean id="msgClientFactory" class="org.apache.cxf.jaxws.JaxWsProxyFactoryBean">
        <property name="serviceClass" value="com.jd.sms.MsgWebServiceSoap"/>
        <property name="address" value="http://127.0.0.1/services/AlarmInformationServices"/>
    </bean>


第二种: 2:  

   用标签<jaxws:client直接配置:

<jaxws:client id="orderClient" serviceClass=

                "demo.order.OrderProcess" address=

                 "http://localhost:8080/orderapp/OrderProcess" />

以上两种webService 的接口地址都不需要在后面加上?wsdl这个后缀,因为这样spring 调用时候要先通过 CXF/bin 命令行wsdl2java 这个命令生成本地客户端调用,把生成的本地客户端代码复制到客户端工程中去,在spring 配置文件中通过上面的任意一种配置方式选择配置,即可调用。
以上CXF异常,就是用这种方式调用,但是接口URL 多了?wsdl后缀的原面;
附wsdl2java 使用方式cd CXF/bin目录下:

例输入:wsdl2java -p com.jd.ws.all  -d F://src - client http://localhost:9000/helloWorld?wsdl
其作用上面的build.xml作用一样。
附加:wsdl2java用法:
wsdl2java -p com -d src -all aa.wsdl
-p 指定其wsdl的命名空间,也就是要生成代码的包名:
-d 指定要产生代码所在目录
-client 生成客户端测试web service的代码
-server 生成服务器启动web service的代码
-impl 生成web service的实现代码
-ant 生成build.xml文件


posted @ 2012-05-22 14:00 张钊钊 阅读(1686) | 评论 (0)编辑 收藏

2010年1月28日

首先在web工程src目录下新建一个database.properties 文件
内容如下:

user=root
password=root
databaseType=com.mysql.jdbc.Driver
url=jdbc:mysql://192.168.2.232:3306/oa? seUnicode=true&amp;characterEncoding=UTF8&amp;zeroDateTimeBehavior=convertToNull

 这里的内容随自己的合适而变化,这里不多说了;

在新建一个读取.properties文件新类:

package com.junhai.tamsys.util;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Properties;

public class DatabaseConfigure {
 private Properties property;
 private FileInputStream inputFile;
 private FileOutputStream outputFile;

 public DatabaseConfigure() {
  property = new Properties();
 }

 public DatabaseConfigure(String filePath) {
  property = new Properties();
  try {
   inputFile = new FileInputStream(filePath);
   property.load(inputFile);
   inputFile.close();
  } catch (FileNotFoundException e) {
   System.out.println("读取属性文件--->失败!- 原因:文件路径错误或者文件不存在");
   e.printStackTrace();
  } catch (IOException e) {
   e.printStackTrace();
  }
 }

 /*
  * 重载函数,得到key的值 @param key 取得其值的键 @return key的值
  */
 public String getValue(String key) {
  if (property.containsKey(key)) {
   return property.getProperty(key);

  } else
   return "";
 }

 /*
  * 重载函数,得到key的值
  *
  * @param fileName propertys文件的路径+文件名 @param key 取得其值的键 @return key的值
  */
 public String getValue(String fileName, String key) {
  try {
   String value = "";
   inputFile = new FileInputStream(fileName);
   property.load(inputFile);
   inputFile.close();
   if (property.containsKey(key)) {
    value = property.getProperty(key);
    return value;
   } else
    return value;
  } catch (FileNotFoundException e) {
   e.printStackTrace();
   return "";
  } catch (IOException e) {
   e.printStackTrace();
   return "";
  } catch (Exception ex) {
   ex.printStackTrace();
   return "";
  }
 }

 /*
  * 清除properties文件中所有的key和其值
  */
 public void clear() {
  property.clear();
 }

 /*
  * 改变或添加一个key的值,当key存在于properties文件中时该key的值被value所代替, 当key不存在时,该key的值是value
  * @param key 要存入的键 @param value 要存入的值
  */
 public void setValue(String key, String value) {
  property.setProperty(key, value);
 }

 /*
  * 将更改后的文件数据存入指定的文件中,该文件可以事先不存在。 @param fileName 文件路径+文件名称 @param
  * description 对该文件的描述
  */
 public void saveFile(String fileName, String description) {
  try {
   outputFile = new FileOutputStream(fileName);
   property.store(outputFile, description);
   outputFile.close();
  } catch (FileNotFoundException e) {
   e.printStackTrace();
  } catch (IOException ioe) {
   ioe.printStackTrace();
  }
 }

 public static void main(String[] args) {
  DatabaseConfigure test=new DatabaseConfigure("./src/database.properties");
  System.out.println(test.getValue("user"));
  System.out.println(test.getValue("databaseType")+";"+test.getValue("url"));
  
 }
}


这样就可以通过key得到相应的value了;
想在这里多说一点是路径问题,java工程和web 工程读取.properties路径是不一样的,我在这里就花了不少时间。
JAVA工程: DatabaseConfigure test=new DatabaseConfigure("./src/database.properties");这样读取就可以了:
web工程这样读取:DatabaseConfigure  dc = new DatabaseConfigure(Thread.currentThread().getContextClassLoader()
                                                .getResource("").getPath()+"database.properties");
 
因为当服务器启动后工程里面东西会编译后加到\WEB-INF\classes这个目录,服务也是从这个目录下读取信息的。所以先取到这个路径,才能正确读取到database.properties这里边的内容。

posted @ 2010-01-28 15:46 张钊钊 阅读(2393) | 评论 (0)编辑 收藏

2009年10月12日

     摘要:   Struts2 拦截器详细配置过程 1:所有拦截器的超级接口Interceptor ,Action去实现这个接口;  Interceptor 它其中有三个方法(init(),destroy() ,interceptor()):       Init()方法:在服务器起动的时候加载一次,并且只加载一次;  ...  阅读全文

posted @ 2009-10-12 22:41 张钊钊 阅读(23317) | 评论 (6)编辑 收藏

2009年8月11日

 

Hiberante3 一级缓存总结

1.             Session 级别的缓存,它同session邦定。它的生命周期和session相同。Session消毁,它也同时消毁;管理一级缓存,一级缓存无法取消,用两个方法管理,clear(),evict()

2.             两个session 不能共享一级缓存,因它会伴随session的生命周期的创建和消毁;

3.             Session缓存是实体级别的缓存,就是只有在查询对象级别的时候才使用,如果

使用HQLSQL是查询属性级别的,是不使用一级缓存的!切记!!!!

4 .  iterate 查询使用缓存,会发出查询IdSQLHQL语句,但不会发出查实体的,

它查询完会把相应的实体放到缓存里边,一些实体查询如果缓存里边有,就从缓存中查询,但还是会发出查询idSQLHQL语句。如果缓存中没有它会数据库中查询,然后将查询到的实体一个一个放到缓存中去,所以会有N+1问题出现。

5 . List()iterate 查询区别:

使用iterate,list查询实体对象*N+1问题,在默认情况下,使用query.iterate查询,有可以能出现N+1问题

所谓的N+1是在查询的时候发出了N+1sql语句1:首先发出一条查询对象id列表的sqlN:

根据id列表到缓存中查询,如果缓存中不存在与之匹配的数据,那么会根据id发出相应的sql语句listiterate的区别?

list每次都会发出sql语句,list会向缓存中放入数据,而不利用缓存中的数据

iterate:在默认情况下iterate利用缓存数据,但如果缓存中不存在数据有可以能出现N+1问题

6Get()load(),iterate方法都会使用一级缓存,

 

7.hiberate3 session 存储过程如下:

       例如 object 对象

       Session.save(object);

       这时候不会把数据放到数据库,会先放到session缓存中去,数据库中没有相应记录,session.flush();才发SQLHQL语句,数据库中有了相应记录,

       但是数据库用select查不到,这是跟数据库事物级别有关系,(这里在说下数据库的事务隔离级别一共四种如下:)
    数据库隔离级别:
        隔离级别                       是否存在脏读  是否存在不可重复读     是否存在幻读;
    Read UnCommited(未提交读)               Y            Y                     Y
    Read Commited (提交读 oraclel默认)      N            Y                     Y
    Repeatable Read(不可重复读(Msql默认))  N            N                     Y 
    Serializable(使用很少)                  N            N                     N

    


       Session.beginTrransaction().commit();

       事物提交后可以查询到了。

Session.flush()语句但是为什么不写呢,因为commit()会默认调用flush();


Hiberante3 二级缓存总结

1.Hibernate3的(sessionFactory)二级缓存和session级别的缓存一样都只对实体对象做缓存,不对属性级别的查询做缓存;二级缓存的生命周期和sessionFactory的生命周期是一样的,sessionFactory可以管理二级缓存;

2.sessionFactory级别的缓存,需要手动配置;所有的session可以共享sessionFactory 级别的缓存;(一般把一些不经常变化的实体对象放到sessionFactory级别的缓存中,适合放不经常变化的实体对象。)

3.Hiberante3二级缓存的配置和使用方法如下:

1. 必须把ehcache.jar包导入,然后到Hibernate3.2etc文件下把ehcache.xml复制到工程src目录下(ehcache.xml里边的参数里边有详细英文说明);

(说明:ehcache.jar是第三方法的缓存产品,hiberante只是把它做了集成,还有好多第三方hibernate集成的缓存产品,相关说明请查阅hiberante3开发手册;ehcache支持分布应用的(这个和Hibernate3.2开发手册有出入,经过官网查证确实支持了),如果有分布式需求,请换成支持分布式的二级缓存产品,hiberate3开发手册都有相头说明。配置方法都类似);

4.Hibernate3的二级缓存默认是开起的,也可以指定开起。在hibernate.cfg.xml 文件下配置如下:

*修改hibernate.cfg.xml文件,开户二级缓存;

                     <property name=”hibernate.cache.use_second_level_cache”>true</property>

                     *指定二级缓存产品的提供商;

<property name=”hibernate.cache.provider_class”> org.hibernate.cache.EhCacheProvider

</property>

要让那些实体使用二级缓存,在hibernate.cfg.xml配置文件中加入:

<!—

让这个实体用二级缓存 也可以在实体中映射文件去配置即:

<cache usage="read-only"/>

-->

<class-cache class=”com.zzz.hibernate.ClassT” usage=”read-only”/>

Read-only一般使用这个策略,其它的hibernate3开发手册中也有详细介绍;

CacheModehibernate3开发手册中搜索这个关键字,可以找到一级缓存和二级缓存交互使用的问题;

posted @ 2009-08-11 23:01 张钊钊 阅读(6615) | 评论 (3)编辑 收藏