JaveWeb 程序开发
一、 表单及表单元素
a) 文本框的应用:
不能复制,剪贴,黏贴一般用于密码框!
二、 窗口与导航条
a) 打开一个窗口自动关闭:
i. 父页面:
window.open("child.html","新的窗口","width=500;heigth=300;top=10;left=10")
ii. 子页面为body的onload 事件添加:
οnlοad="window.setTimeout('window.close()',5000);";
b) 弹出窗口居中显示
function shownewpage(){
varhc=window.open("child.html","新的窗口","width=500;height=300;");
varwidth=screen.width;
varheigth=screen.height;
hc.moveTo((width-500)/2,(heigth-300)/2);
}
c) 关闭窗口时,刷新父窗口
Window.opener.location.reload();
Window对象的opener 属性返回一个引用,表示返回打开这个子窗口的窗口的!所有通过它可以调用打开它的窗口的属性!
d) 弹出模式对话框
varresult=window.showModalDialog("child.html","","dialogWidth=407;dialogHeight=257;");
然后再模式对话框里:
parent.window.returnValue=document.form1.userPass.value;
window.close();
var width=screen.width;
var height=screen.height;
varresult=window.showModalDialog("child.html","全屏的模式对话框","Dialogwidth="+width+";Dialogheight="+height+";");
三、 JavaScript函数:
a) 小写的金额转换为大写的金额
四、 JavaBean技术
a) String 类的 split() 应注意的地方:
1、如果用“.”作为分隔的话,必须是如下写法:String.split("\\."),这样才能正确的分隔开,不能用String.split(".");
2、如果用“|”作为分隔的话,必须是如下写法:String.split("\\|"),这样才能正确的分隔开,不能用String.split("|");
“.”和“|”都是转义字符,必须得加"\\";
3、如果在一个字符串中有多个分隔符,可以用“|”作为连字符,比如:“acount=? and uu=? or n=?”,把三个都分隔出来,可以用String.split("and|or");
五、 正则表达式在JAVA中的应用:
Pattern p = Pattern.compile("a*b");
Matcher m = p.matcher("aaaaab"); s
boolean b = m.matches();
在仅使用一次正则表达式时,可以方便地通过此类定义 matches 方法。此方法编译表达式并在单个调用中将输入序列与其匹配。
六、 MySQL数据库
1.选择唯一值:
selectdistinct * from student;
2.为某一列取别名,不能使用as :
selectstuScore*0.9 '结果'from student order by stuScore desc;
3.条件查询:
select* from student where stuAddress!='泾阳';
4.范围查询:
select* from student where stuScore between 80 and 100;
5.自增长标识列:
auto_increment;
6.选择来自一个集合的数据:(当集合中的数据不存在时,不会出现异常!)
select* from student where stuId in(1,2);
7.识别null数值或isnull :
select* from student where stuScore is not null;
8.模糊查询:
select * from student where stuName like'高%';
9.分组条件:(可以不查出stuAddress)
select * from student group by stuAddress
having count(*)>3;
10.查询最大值:
select max(stuScore) '最大分数' from student;
11.实现四舍五入到指定长度:
select round(100.12345,3);
12.显示当前时间(获取系统的当前时间):
select now();
13.日期函数:
selectmonth(),year(),dayofmonth();
selectdayofmonth(now());
七、 JSP部分:
a) 使用 application 内置对象读web.xml 中的参数:
Web.xml 中如下:
driver
com.jdbc.mysql.Driver
uri
jdbc:mysql://localhost:3306/shopping
user
root
pwd
root
上面就是在 web.xml 中配置将要读取的的全局参数! 下面使用 application 进行读取并显示到页面上:
Servlet中的代码:
String driver =getServletContext().getInitParameter("driver");
Stringuri=getServletContext().getInitParameter("uri");
Stringuser=getServletContext().getInitParameter("user");
Stringpwd=getServletContext().getInitParameter("pwd");
通过上面的连个步骤就可以读取全局变量!
b) 使用 config 对象,读取servlet 的参数:
不管是Jsp页面还是servlet, config内置对象代表翻译之后的的 .java 本身!这种方法读取参数的使用场合:字符过滤器:
Serlet 中的配置如下:
config
config
charset
utf-8
在serlvet 中的代码如下:
Stringcharset=this.getServletConfig().getInitParameter("charset");
c) request 对象:
使用 request.getParameterMap() 可以获取请求的Map 集合对象;使用request应注意以下情况:
并不是每个表单域都可以生成请求参数的,只有有name属性的表单域才可以生成请求参数的!如果多个表单域的name值相同,则生成一个请求参数;表单域的name属性为请求参数的名,value属性值为请求的值;如果某个表单的disabled=”true”则该表单不在生成请求参数!
Mapres=request.getParameterMap();
Iterator>iter=res.keySet().iterator();
while(iter.hasNext()) {
Stringstr=iter.next().toString();
System.out.println(str);
}
使用如上代码获取请求信息的Map
Stringqstr=request.getQueryString();
System.out.println(qstr);
StringstrE=java.net.URLDecoder.decode(qstr,"utf-8");
System.out.println(strE);
String []arrayStr=strE.split("&");
for (Stringstring : arrayStr) {
System.out.println("每个请求参数的值,对"+string);
String []subStr=string.split("=");
System.out.println("名称:"+subStr[0]);
System.out.println("值"+subStr[1]);
}
Request 对象的 getQuaryString() 方法,可以获取请求字符串,java.net.Decoder.decode()用于解码(原因是在请求参数中含有非西欧字符的参数,所以要使用java.net.Decoder.decode()进行解码);
使用getRequestDispatcher(“{0}”).forward()跳转时,要在 0 处的项目资源加 ‘/’;
d) response 对象:
比较request.getRequestDispatcher().forward(request,response) 与response.sendRedirect():
Forward 执行完之后还是上一次的请求,而redirect 后生成第二次请求;forward 请求后,目标页面可以访问请求的请求参数,因为是同一个request请求,即所有的请求参数在同一个 request对象中都存在,而使用 redirect 后目标页面不能使用原来的请求参数,因为已经是第二次请求了,那也就是说,request对象的消失,请求的参数就会跟着消失;还有使用 forward 请求 url 中的地址不会改变. 而使用 redirect 会改变为目标的 url;
e) cookie 的读写:
写入 cookie 对象:ss
//设置临时Cookie
Cookie tempCookie=newCookie("temp","222222");
tempCookie.setMaxAge(-1); //默认值,不会把 Cookie 保存到硬盘上
response.addCookie(tempCookie);
//设置 MaxAge 为 0 的 Cookie
Cookie cookie=newCookie("cookie","111111");
cookie.setMaxAge(0); //表示浏览器接受 Cookie 后会被立即删除
response.addCookie(cookie);
//设置永久的 Cookie
Cookie mcookie=newCookie("name","000000");
mcookie.setMaxAge(60*60*24);
response.addCookie(mcookie);
读取 cookie 对象:
protectedCookie getCookie(Cookie [] cookies,String name){
if(cookies!=null){
for(Cookie c : cookies) {
if(c.getName().equals(name)){
returnc;
}
}
}
returnnull;
}
PrintWriter out = response.getWriter();
//获得临时的 Cookie
Cookie temp=getCookie(request.getCookies(),"temp");
if(temp!=null){
out.print("临时Cookie的值为:"+temp.getValue());
}else{
out.print("没有值!");
}
//获取时间为 0 的Cookie,这个 Cookie永远都不可能获得到
Cookiecookie=getCookie(request.getCookies(), "cookie");
if(cookie!=null) {
out.print("MaxAge为零的Cookie:"+cookie.getValue());
}else {
out.print("没有值!");
}
//获取永久的Cookie
Cookiename=getCookie(request.getCookies(), "name");
if(name!=null) {
out.print("永久Cookie 值:"+name.getValue());
}else {
out.print("没有值!");
}
在cookie中写的时候对汉字的处理:
添加之前将字符串使用java.net.URLEncoder.encode("高江涛","utf-8"); 取出来之后将结果java.net.URLDecoder.decode(temp.getValue(),"utf-8");
f) 自定义标签:
传统的Jsp脚本有什么坏处:
i. Jsp 脚本非常丑陋,难以阅读!
ii. Jsp 脚本和 HTML 代码混杂,维护成本高!
iii. HTML 页面中嵌入 Jsp 脚本,导致美工难以参加开发!
g) 自定义标签的开发步骤:
i. 建立自定义标签的处理类;
ii. 建立一个 *.tld 文件,每一 tld文件都对应一个标签库,每个标签库对应多个个标签!
iii. 在Jsp 页面上使用自己的标签!
h) .tld 文件的描述(根元素为 tag-lib):
i. tlib-version:标签库的版本,这个对程序的作用不大!
ii. short-name:标签库默认的短名,通常对程序的作用也不大!
iii. uri: 该标签库的uri,指定该标签库的唯一标示;
iv. tag:tag-lib 下可以有多个 tag,每个 tag 都代表一个标签;
i) tag 下的元素描述:
name: 这个非常重要,jsp页面就是根据这个来使用这个标签的;
tag-class: 这个是这个标签的后台处理类!
body-content: 这个属性可以是一下值:tagdependent: 指定标签的处理类,自己负责处理标签体! Empty: 空体标签;scriptless: 该标签里面可以含有静态的 HTML , 表达式语言,但不可以是JSP 脚本! JSP :这个已被忽视;
j) 带属性自定义的标签开发:
对于有属性的标签,要为tag添加 attribute 子元素: 每个 attribute 子元素定义一个属性,attribute含有一下子元素:
Name: 属性的名称;
Required:设置该属性为必须属性;
Fragment:是否支持Jsp脚本等动态内容!s
k) 在页面上使用自己定义的标签:
<%@ taglib uri="http://xabc.net"prefix="mytag" %>
带体的标签:
Collection>itemList=
(Collection>)getJspContext().getAttribute(this.getCollection());
for (Object object : itemList) {
getJspContext().setAttribute(this.getItem(),object);
getJspBody().invoke(null);
}
g) 过滤器:
a) 过滤器的使用场合:
i. 权限过滤;
ii. 日志过滤;
iii. 非法IP过滤;
iv. 字符集过滤;
b) 创建过滤器的后台处理类,实现Filter接口,实现如下方法:
i. init(FilterConfigconfig); 用于对过滤器的初始化;
ii. defiler(ServletRequestrequest,SerletResponse response,FilterChain chain);用于将请求继续传递;
iii. destroy():用于在 Filter 销毁之前将某些资源回收!
c) 在 web.xml 下如下配置:
filter
util.DoFilter
endoding
utf-8
fristPage
index.jsp
IP
127.0.0.2
filter
/*
* 过滤器主要是对用户的请求进行预处理,也可以对 HttpServletResponse 进行后处理!
过滤器的核心代码:
public void doFilter(ServletRequest request,ServletResponse response,
FilterChainchain) throws IOException, ServletException {
request.setCharacterEncoding(this.encoding);
HttpServletRequesthrequest=(HttpServletRequest)request;
HttpServletResponsehresponse=(HttpServletResponse)response;
Stringspath=hrequest.getServletPath();//获取请求的路径
Stringip=hrequest.getLocalAddr();//获取请求的IP
if(!ip.equals(this.IP)) {
if(!spath.endsWith(this.firstpage)) {
request.getRequestDispatcher(this.firstpage).forward(hrequest,hresponse);
}else{
chain.doFilter(hrequest,hresponse);
}
}else{
hrequest.setAttribute("msg","window.alert('您被限制了!')");
hrequest.getRequestDispatcher("error.jsp").forward(hrequest,hresponse);
}
}
h) 监听器:
a) 使用 Listener 的步骤:
i. 创建 Listener 实现类,实现ServeltContextListener 接口;包含一下方法:
1. contextInitialized (ServletContextEvent sce): 启动web应用时,系统调用的方法;
2. contextDestroyed(ServletContextEvent sce): 关闭 web 应用时,系统调用的方法;
ii. 在web.xml 中配置如下:
util.Listener
监听器如 servlet的 load-on-startup一样,但是比servlet的 load-on-startup 执行的还早,还有监听器不负责处理及相应用户的请求; 还有监听器在web.xml 下配置的时候无需配置参数,所访问的参数为全局共有参数。
v) JSP中表达式语言(Expressionlanguage):
a) ${1+2}: 前加 ‘ \’ 表示此EL 表达式不被解析;
b) 表达式语言的内置对象:
i. pageContext:代表页面的 pageContext 对象,与JSP中的PageContext相同;
ii. pageScope:获取page 范围内的属性;
iii. requestScope:获取 request 范围内的属性;
iv. sessionScope: 获取 session 范围内的属性;
v. applicationScope: 获取 application 范围内的属性;
vi. param :用于获取请求参数;
vii. paramValues:用于获取请求的参数,与param不同的是该对象是用于获取返回值为数组的参数;
viii. header:用于获取请求头信息;
ix. headerValues: 用于获取请求头信息; 与header不同的是该对象是用于获取返回值为数组的请求参数;
x. initParam:用于获取有 web 应用初始化的参数;
xi. cookie:用于获取指定 cookie 的值;
i) EL的自定义函数:
i. 自定义表达式语言与自定义标签类似;步骤分为:
1. 开发 EL函数处理类,这个类中的方法要求是静态的方法;
2. 建立tld 文件,tld 文件的描述:
name: 指定了函数的名称;
function-class: 函数对应的处理类;
function-signature: 指定函数的实现方法;
3. 使用该函数;
<%@ taglib uri="http://xabc.com"prefix="fn" %>
ii.
public staticString reverse(String str){
returnnew StringBuffer(str).reverse().toString();
}
publicint countChar(String text){
returntext.length();
}
reverse
demo.myfunction
java.lang.Stringreverse(java.lang.String)
countChar
demo.myfunction
intcountChar(java.lang.String)
八、 ajax中dwr框架的使用:
a. 配置dwr.xml:
b.配置 web.xml:
dwr
org.directwebremoting.servlet.DwrServlet
debug
true
dwr
/dwr/*
c.在js中设置回调函数:
functioncheckName(){
var name= document.getElementById("uName").value;
JCheckName.checkName(name,checkUserName);
}
九、 Struts2技术应用:s
1. Struts2上传文件:
原理:
Struts 2是通过Commons FileUpload文件上传。Commons FileUpload通过将HTTP的数据保存到临时文件夹,然后Struts使用fileUpload拦截器将文件绑定到Action的实例中。从而我们就能够以本地文件方式的操作浏览器上传的文件。
Web.xml 下的配置:
< filter >
< filter-name > struts-cleanup
< filter-class >
org.apache.struts2.dispatcher.ActionContextCleanUp
filter-class >
filter >
< filter >
< filter-name > struts2 filter-name>
< filter-class >
org.apache.struts2.dispatcher.FilterDispatcher
filter-class >
filter >
< filter-mapping >
< filter-name > struts-cleanup
< url-pattern > /* url-pattern >
filter-mapping >
< filter-mapping >
< filter-name > struts2 filter-name>
< url-pattern > /* url-pattern >
filter-mapping >
org.apache.struts2.dispatcher.ActionContextCleanUp 在 struts 是对org.apache.struts2.dispatcher.FilterDispatcher 的一个补充,在做上传文件加上这个配置时,上传文件就万无一失了!
Struts.xml中的配置:
< action name ="fileUpload" class="tutorial.FileUploadAction" >
< interceptor-refname ="fileUpload" >
< param name="allowedTypes" >
image/bmp,image/png,image/gif,image/jpeg
param >
interceptor-ref>
< interceptor-refname ="defaultStack" />
< result name="input" > /FileUpload.jsp result >
< result name="success" > /ShowUpload.jsp result >
action >
通过在 strust.xml 中拦截器的配置,可以限制上传文件的大小和类型!但是如果在一个 Action 中配置拦截器,那么要在引用一次默认的拦截器栈!
在程序中:
private List photo;
private List photoContentType;
private ListphotoFileName;
private String savePath;
这四个属性是必须的并且为他提供 get,setter 方法,这几个属性是 struts 框架自动为其赋值的!
九、Struts2 的输入验证:
基本原理:
遇到类型转换错误的时候(也就是说不能进行类型转换),struts2框架自动生成一条错误信息,并且将该错误信息放到addFieldError里面
类型转换与输入校验的流程
1. 首先Struts2对客户端传来的数据进行类型转换
2. 类型转换完毕后再进行输入校验
3. 如果类型转换和输入校验都没有错误发生,那么进入execute方法(调用商业逻辑)
注意:如果类型转换不成功,也同样要进行输入校验!
在xxx-validation.xml 中的一段配置:
true
${getText('name.requied')}
${getText('name.regex')}
true
${getText('pass.required')}
${getText('pass.regex')}
150
0
${getText('age.range')}
1900-01-01
2050-02-21
${getText('birth.range')}
使用 ${getText(‘ xxx’)}获取国际化资源文件!这段配置存在于 classpath 目录下 XXXXX-validation.xml 中!xxxx表示处理逻辑的 Action;
自动搜索:
如果在一个action中有多个业务,struts支持 效验文件自动搜索规则;如:UserAction-login-validation.xml;UserAction 是处理业务的Aciton, login 是登录的方法!struts2搜索规则是从上到下的,实际上用的效验规则是所有的效验规则总和;如果在两个效验文件中指定的效验规则发生了冲突,则后面的的取胜!
校验器的配置风格:
A. 字段效验风格:
true
${getText('name.requied')}
${getText('name.regex')}
B. 非字段效验风格:
username
true
${getText('username.required')}
注意:如果使用非字段效验风格的话,必须指定 filedName 属性!
短路校验器:
通过在
Struts2 中所有的内建校验器:
A. 必填校验器:
userNameto be not null!
B. 必填字符串校验器:
true
请填写用户名!
注:该校验器有一个属性 trim表示是否在校验前清空前后的空格;默认为true;
C. 整数校验器:
age
150
0
年龄必须在 0-150 岁之间!
D. 日期校验器:
birthday
2050-02-01
1990-01-01
对不起,您的生日超范围了!
注:max和min指的是最大和最小!
E. 表达式校验器:
1==1
正确!
F. 字段表达式校验器:
pass
原密码要和重复密码相同!
G. 网址校验器:
url
您的主页必须是一个有效的网址!
H. 字符串长度校验器:
username
10
1
长度必须在 1-10 之间!
I. 正则表达式校验器:
username
false
请填写正确格式的用户名!
注:在这个校验器中 caseSensitive表示: 在做效验的时候是否区分大小写,默认为 true,区分大小写!
在程序中验证:
重写父类的validate 方法,如果在一个action 中,存在多个业务逻辑的处理方法,那么就要为其提供 validateXxx() 方法;如果使这种情况的话,建议不要在出现父类的 validate() 方法,以为如果有父类的validate()时,struts2 的验证顺序为类型转换 validateXxx() ,validate() ;
在程序中使用 ActionError,如果使用了 ActionError 的话,建议将form的 theme 属性设置为 simple;在页面上使用
值得注意的是ActionError在底层时放入到 List 中,而FieldError 时放入到 Map 中的!
一般情况下如果效验不是太复杂的话,我们都是配置文件的方式完成输入效验!但是对于配置文件难以解决校验我们重写 ActionSupport 类的 validate() 方法! 但是配置文件和 重写父类的validate() 方法建议不要同时使用!
2. Struts2 核心拦截器
A. struts2 的拦截器是根据 aop的思想设计的,实现aop有两种方式 dynamic prox 和 cglib; 拦截器的出现满足了我们对 dry 的实现!
关于动态代理的一段关键代码:
Proxy.newProxyInstance(UserAction.class.getClassLoader(),
newClass[] { IAction.class }, hander);
public Object invoke(Object proxy,Method method, Object[] args)
throwsThrowable {
Objectobj=null;
if("execute".equals(method.getName())) {
doService.Inteceptor();
obj= method.invoke(actionService, args);
doService.Inteceptor();
}else{
obj=method.invoke(actionService,args);
}
returnobj;
}
B. 在struts2 中实现一个拦截器的几种方式:
实现 Interceptor 接口;
继承 DefaultInterceptor 类;
继承MethodFilterInterceptor 类(方法过滤拦截器);
C. 拦截器在struts.xml 中的配置:
首先在 struts.xml 中注册拦截器:
拦截器栈和拦截器在struts.xml 中没有太大的区别 (从宏观角度上看!)
然后在Action中引用:
userlogin
十、Spring 技术应用:
1. Spring 的配置文件:
配置文件的名称可以为多个,并且名称随便给! 最后通过ClassPathXmlApplicationContext的构造函数传入配置文件的路径;
为了减少配置文件的字节,一般可采取两种方案: 使用通配符或者写多个配置文件,最后通过如上方式引入!但是在多个配置文件中应注意的是:不能出现相同的Id名称!
按名称自动装载,或按类型自动装载!
使用
2. 构造注入:
高江涛
男
18
泾阳
770212507
使用构造器注入时,使用 index(参数索引为 Spring 官方推荐的构造其注入用法);
3. 普通属性注入:
list1
list2
list3
set1
set2
set3
array1
array2
array3
以上是几种常见的集合的注入!
5. 属性编辑器:
首先定义属性编辑器后台类,继承PropertyEditorSupport, Java.beans 包下的;重写它的 setAsText()方法,在方法中类型转换完成之后,通过 this.setValue()方法保存;
然后在 Spring 配置文件中注册:
通过以上的注册,Spring就会知道把相应的类型进行转换!
6. 几种初始化 Ioc 容器的方式:
ClassPathResourceresource=new ClassPathResource("applicationContext.xml");
BeanFactoryfactory=new XmlBeanFactory(resource);
Resourceresource=new FileSystemResource("E:\\applicationContext.xml");
BeanFactoryfactory=new XmlBeanFactory(resource);
ApplicationContextact=new ClassPathXmlApplicationContext("applicationContext.xml");
静态工厂方法:
要求createUser方法必须为静态的!
实例工厂方法:
8. 名称自动装备 和 类型自动装备:
名称自动装备就是:如果一个类中的一个属性为 user时, 在配置文件中,我们没有为这个user属性设置它的引用! 那么 Spring就会自动在所有的Id中找 Id 为user的
类型自动装备就是,Spring容器会在配置文件中找 Spring 为 user 对应的类型,
找到了会自动添加其引用 !(default-autowire="byType")
9. 采用 aspectJ 的 annocaton 方式实现aop:
a) spring依赖库
* SPRING_HOME/dist/spring.jar
* SPRING_HOME/lib/jakarta-commons/commons-logging.jar
* SPRING_HOME/lib/log4j/log4j-1.2.14.jar
* SPRING_HOME/lib/aspectj/*.jar
b) 采用Aspect定义切面
c) 在Aspect定义Pointcut和Advice
d) 启用AspectJ对Annotation的支持并且将Aspect类和目标对象配置到Ioc容器中
e) 注意:在这种方法定义中,切入点的方法是不被执行的,它存在的目的仅仅是为了重用切入点
即Advice中通过方法名引用这个切人点
10. 采用静态文件实现 aop:
首先,定义切面类!然后在配置文件中注册配置的切面类!
注意:
Aspect默认情况下不用实现接口,但对于目标对象,在默认情况下必须实现接口
如果没有实现接口必须引入CGLIB库!
我们可以通过Advice中添加一个JoinPoint参数,这个值会由spring自动传入,从JoinPoint中可以取得参数值、方法名等等!
11. Java的动态代理,以及 CGLIB对aspectj 实现 aop 的支持:
如果目标对象实现了接口,默认情况下会采用JDK的动态代理实现AOP
如果目标对象实现了接口,可以强制使用CGLIB实现AOP
如果目标对象没有实现了接口,必须采用CGLIB库,spring会自动在JDK动态代理和CGLIB之间转换
如何强制使用CGLIB实现AOP?
添加CGLIB库,SPRING_HOME/cglib/*.jar
在spring配置文件中加入
JDK动态代理和CGLIB字节码生成的区别?
JDK动态代理只能对实现了接口的类生成代理,而不能针对类
CGLIB是针对类实现代理,主要是对指定的类生成一个子类,覆盖其中的方法
因为是继承,所以该类或方法最好不要声明成final
12. SSH集成(第一种集成方案):
原理:在Action中取得BeanFactory对象,然后通过BeanFactory获取业务逻辑对象
1、spring和struts依赖库配置
* 配置struts
--拷贝struts类库和jstl类库
--修改web.xml文件来配置ActionServlet
--提供struts-config.xml文件
--提供国际化资源文件
* 配置spring
--拷贝spring类库
--提供spring配置文件
2、在struts的Action中调用如下代码取得BeanFactory
BeanFactoryfactory =WebApplicationContextUtils.getRequiredWebApplicationContext(request.getSession().getServletContext());
3、通过BeanFactory取得业务对象,调用业务逻辑方法
13. 采用声明式事务:
a、声明式事务配置
* 配置SessionFactory
classpath:hibernate.cfg.xml
* 配置事务管理器
* 配置事务的传播特性
* 配置那些类那些方法使用事务
b、编写业务逻辑方法
* 继承HibernateDaoSupport类,使用HibernateTemplate来持久化,HibernateTemplate是
Hibernate Session的轻量级封装
* 默认情况下运行期异常才会回滚(包括继承了RuntimeException子类),普通异常是不会滚的
* 编写业务逻辑方法时,最好将异常一直向上抛出,在表示层(struts)处理
* 关于事务边界的设置,通常设置到业务层,不要添加到Dao上
c、了解事务的几种传播特性
1. PROPAGATION_REQUIRED:如果存在一个事务,则支持当前事务。如果没有事务则开启
2. PROPAGATION_SUPPORTS:如果存在一个事务,支持当前事务。如果没有事务,则非事务的执行
3. PROPAGATION_MANDATORY:如果已经存在一个事务,支持当前事务。如果没有一个活动的事务,则抛出异常。
4. PROPAGATION_REQUIRES_NEW:总是开启一个新的事务。如果一个事务已经存在,则将这个存在的事务挂起。
5. PROPAGATION_NOT_SUPPORTED:总是非事务地执行,并挂起任何存在的事务。
6. PROPAGATION_NEVER:总是非事务地执行,如果存在一个活动事务,则抛出异常
7. PROPAGATION_NESTED:如果一个活动的事务存在,则运行在一个嵌套的事务中. 如果没有活动事务,
则按TransactionDefinition.PROPAGATION_REQUIRED属性执行
d、Spring事务的隔离级别
1. ISOLATION_DEFAULT: 这是一个PlatfromTransactionManager默认的隔离级别,使用数据库默认的事务隔离级别.
另外四个与JDBC的隔离级别相对应
2. ISOLATION_READ_UNCOMMITTED: 这是事务最低的隔离级别,它充许令外一个事务可以看到这个事务未提交的数据。
这种隔离级别会产生脏读,不可重复读和幻像读。
3. ISOLATION_READ_COMMITTED: 保证一个事务修改的数据提交后才能被另外一个事务读取。另外一个事务不能读取该事务未提交的数据
4. ISOLATION_REPEATABLE_READ: 这种事务隔离级别可以防止脏读,不可重复读。但是可能出现幻像读。
它除了保证一个事务不能读取另一个事务未提交的数据外,还保证了避免下面的情况产生(不可重复读)。
5. ISOLATION_SERIALIZABLE这是花费最高代价但是最可靠的事务隔离级别。事务被处理为顺序执行。
除了防止脏读,不可重复读外,还避免了幻像读。
14. Spring中的任务调度:
a) Java Timer 调度器:
需继承 TimerTask 类,重写 run() 方法;
10000 //间隔时间
2000 //懒执行的时间 (都是以毫秒为单位)
b) Quartz(opensymphon) 调度器:
继承QuartzJobBean,必须要 quartz-1.5.2.jar ! 重写它的 executeInternal 方法!
//任务的详细信息
org.rongxin.springtest.time.Task.QuartzJob
//间隔多少时间执行任务
//到什么时间执行任务
** * * * ? //? 是星期天不必设置! * 代表任意
一般应用中常用到五个接口
1.configaction
通过这个接口的实例来找到映射配置文件的信息,然后根据里面的映射信息创建sessionFactory对象
2.session
管理增删改差五个方法
一个应用程序中可以有多个session实例,可以随时销毁,因为它占用资源小,被称为第一插件
3.sessionFactory
线程是安全的,它的同一个实例可以给多个线程调用
它的实例是重量级的,不能随意销毁
负责实力所有的session对象,一般一个应用程序中只能有一个SESSIONFACTORY,因为它占用的系统资源过大!
称为hibernate的第二插件
4.query和criteria
执行hibernate查询方法的接口,它包装了一个HQL查询语句,criteria完全封装了字符串形式的查询语句,比QUERY更加面向对象,一般用于动态查询。他们功能比session中的find()方法强大许多,因为find()方法只能执行一些简单的,单一对象的查询
5.Transaction
管理事务接口
十二、 SSH 集成:
第一种集成方案:
原理:在Action中取得BeanFactory对象,然后通过BeanFactory获取业务逻辑对象
a、spring和struts依赖库配置
* 配置struts
--拷贝struts类库和jstl类库
--修改web.xml文件来配置ActionServlet
--提供struts-config.xml文件
--提供国际化资源文件
* 配置spring
--拷贝spring类库
--提供spring配置文件
b、在struts的Action中调用如下代码取得BeanFactory
BeanFactoryfactory =WebApplicationContextUtils.getRequiredWebApplicationContext(request.getSession().getServletContext());
(第二种集成方案):
原理:将业务逻辑对象通过spring注入到Action中,从而避免了在Action类中的直接代码查询
a、spring和struts依赖库配置
* 配置struts
--拷贝struts类库和jstl类库
--修改web.xml文件来配置ActionServlet
contextConfigLocation
classpath*:applicationContext-*.xml
org.springframework.web.context.ContextLoaderListener
--提供struts-config.xml文件
--提供国际化资源文件
* 配置spring
--拷贝spring类库
--提供spring配置文件
b、因为Action需要调用业务逻辑方法,所以需要在Action中提供setter方法,让spring将业务逻辑对象注入过来
c、在struts-config.xml文件中配置Action
*
DelegatingActionProxy是一个Action,主要作用是取得BeanFactory,然后根据
到IoC容器中取得本次请求对应的Action
d、在spring配置文件中需要定义struts的Action如:
* 必须使用name属性,name属性值必须和struts-config.xml文件中
* 必须注入业务逻辑对象
* 建议将scope设置为prototype,这样就避免了struts Action的线程安全问题
Srping 中声明式事务的配置:
classpath:hibernate.cfg.xml