struts2标签

struts2.0里的标签没有分类,只用在jsp头文件加上<%@taglib prefix="s" uri="/struts-tags" %>就能使用struts2.0的标签库

A:
-----超链接,类似于html里的
-----执行一个view里面的一个action
-----如果action的errors有值那么显示出来
-----如果action的message有值那么显示出来
-----添加一个值到list,类似于list.add();
-----自动完成标签的内容,这个是ajax
 
                                            loadOnTextChange="true" loadMinimumCount="1" indicator="indicator"
                        autoComplete="false" showDownArrow="false" />

B:
-----类似于struts1.x中的,JavaBean的值

C:
-----复选框
-----多选框
-----下拉框
-----图像符号

D:
-----获取日期格式
 
-----日期输入框
-----显示错误信息
-----表示一个块,类似于html的


-----双下拉框

E:


-----这3个标签一起使用,表示条件判断

F:
-----显示文件错误信息
-----文件上传
-----获取相应form的值

G:
----和标签一起使用

H:
-----在里使用,表示头文件结束
-----隐藏值

I:
-----加载资源包到值堆栈
-----包含一个输出,servlet或jsp页面
-----获取form的一个输入
-----用于遍历集合

L:
-----只读的标签

M:
-----合并遍历集合出来的值

O:
-----获取标签组
-----左右选择框

P:
-----为其他标签提供参数
-----密码输入框
-----得到'value'的属性
-----value的值push到栈中,从而使property标签的能够获取value的属性

R:
-----单选按钮
-----重置按钮

S:
-----单选框
-----赋予变量一个特定范围内的值
-----通过属性给list分类
-----提交按钮
-----为遍历集合输出子集

T:
-----表格框
-----表格
-----I18n文本信息
-----文本域输入框
-----文本输入框
-----拦截器
-----树
-----树的结构

U:
-----多选择框
-----创建url
http://localhost:8080/demo/index.jsp?flag=kkkk  
 

http://localhost:8080/demo/index.jsp?flag=kkkk

这里有三种方法
Xml代码
or  
or  
 

or
or

从上面的答案我们可以推测到request,session ,application中的属性值也可以用同样的方法获取
如:
Xml代码
  request.----> 
or  
or  
 
session----> 
or  
or  
 
application---> 
or  
or  
 


${fn:substring("你要截取的字符串"),beginIndex,endIndex}    
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %> 
函数名 函数说明 使用举例  
fn:contains 判定字符串是否包含另外一个字符串  
fn:containsIgnoreCase 判定字符串是否包含另外一个字符串(大小写无关)  
fn:endsWith 判定字符串是否以另外字符串结束  
fn:escapeXml 把一些字符转成XML表示,例如 <字符应该转为< ${fn:escapeXml(param:info)}  
fn:indexOf 子字符串在母字符串中出现的位置 ${fn:indexOf(name, "-")}  
fn:join 将数组中的数据联合成一个新字符串,并使用指定字符格开 ${fn:join(array, ";")}  
fn:length 获取字符串的长度,或者数组的大小 ${fn:length(shoppingCart.products)}  
fn:replace 替换字符串中指定的字符 ${fn:replace(text, "-", "?")}  
fn:split 把字符串按照指定字符切分 ${fn:split(customerNames, ";")}  
fn:startsWith 判定字符串是否以某个子串开始  
fn:substring 获取子串 ${fn:substring(zip, 6, -1)}  
fn:substringAfter 获取从某个字符所在位置开始的子串  
${fn:substringAfter(zip, "-")}  
fn:substringBefore 获取从开始到某个字符所在位置的子串 ${fn:substringBefore(zip, "-")}  
fn:toLowerCase 转为小写 ${fn.toLowerCase(product.name)}  
fn:toUpperCase 转为大写字符 ${fn.UpperCase(product.name)}  
fn:trim 去除字符串前后的空格 ${fn.trim(name)}  
 
 
函数  
描述  
 
fn:contains(string, substring)  
假如参数string中包含参数substring,返回true  
 
fn:containsIgnoreCase(string, substring)  
假如参数string中包含参数substring(忽略大小写),返回true  
 
fn:endsWith(string, suffix)  
假如参数 string 以参数suffix结尾,返回true  
 
fn:escapeXml(string)  
将有非凡意义的XML (和HTML)转换为对应的XML character entity code,并返回  
 
fn:indexOf(string, substring)  
返回参数substring在参数string中第一次出现的位置  
 
fn:join(array, separator)  
将一个给定的数组array用给定的间隔符separator串在一起,组成一个新的字符串并返回。  
 
fn:length(item)  
返回参数item中包含元素的数量。参数Item类型是数组、collection或者String。假如是String类型,返回值是String中的字符数。  
 
fn:replace(string, before, after)  
返回一个String对象。用参数after字符串替换参数string中所有出现参数before字符串的地方,并返回替换后的结果  
 
fn:split(string, separator)  
返回一个数组,以参数separator 为分割符分割参数string,分割后的每一部分就是数组的一个元素  
 
fn:startsWith(string, prefix)  
假如参数string以参数prefix开头,返回true  
 
fn:substring(string, begin, end)  
返回参数string部分字符串, 从参数begin开始到参数end位置,包括end位置的字符  
 
fn:substringAfter(string, substring)  
返回参数substring在参数string中后面的那一部分字符串  
 
fn:substringBefore(string, substring)  
返回参数substring在参数string中前面的那一部分字符串  
 
fn:toLowerCase(string)  
将参数string所有的字符变为小写,并将其返回  
 
fn:toUpperCase(string)  
将参数string所有的字符变为大写,并将其返回  
 
fn:trim(string)  
去除参数string 首尾的空格,并将其返回 

一、ActionContext

Action环境(com.opensymphony.xwork2.ActionContext),通过我们之前所学的内容。我们知道Context缓存中保存了XXX环境中所需要使用到的重要对象。Struts2中的ActionContext中就保存了Struts2中使用到的重点对象contextMap和valueStack。

 

老张搞了一个经典的关系图:

ActionContext ac = ActionContext.getContext();
ValueStack vs = ac.getValueStack();
Map conMap = ac.getContextMap();
每一个访问线程具有一个ActionContext对象,它是以单例模式存在的。ActionContext为我们提供了操作valueStack和contextMap的便捷方法。例我们的程序可以与ValueStack和ContextMap解耦,比如:ac.put(key, value);、ac.get(key);...。

通过ActionContext使得我们编写的Action不必实现任何接口和继承任何超类,但我们必须在类中使用ActionContext的实例。

二、Struts2中的OGNL
OGNL不是Struts2独创的,而是Struts2中使用OGNL做为操作contextMap和valueStack的方式。OGNL是Object-Graph Navigation Language的缩写,它是一种功能强大的表达式语言(Expression Language,简称为EL),通过它简单一致的表达式语法,可以存取对象的任意属性,调用对象的方法,遍历整个对象的结构图,实现字段类型转化等功能。它使用相同的表达式去存取对象的属性。

OGNLl基本的语法:
可以用#key的形式访问OGNL Context对象中的各个key对应的对象,并可以采用点(.)操作符进行多级导航调用对象的属性和方法,例如,#application、#session.attr1、#key1.sayHello();对于map对象,map.attr不是map.getAttr()方法,而是表示map.get(“attr1”)。
如果要访问根对象的属性或方法,则可以省略#key,直接访问该对象的属性和方法。 struts2修改了OGNL表达式的默认属性访问器,它不是直接访问根对象ValueStack的属性或方法,而是在ValueStack内部的堆栈中所有对象上逐一查找该属性或方法,搜索顺序是从栈顶对象开始寻找,依次往下,直到找到为止,例如,sayHello()表示调用堆栈中某个对象的sayHello()方法。
特例:如果引用名前面没有#,且valueStack中存储的各个对象没有该属性,则把该名称当作Context对象中的某个key来检索对应的对象,但这种方式不支持点(.)操作符。

ValueStack提供了如下一些方法管理其内部的堆栈和关联的Context:
setValue为ognl表达式寻址到的对象设置属性值。
FindValue方法使用OGNL表达式获取结果。
findString方法对findValue方法获取的结果调用转换器转成字符串,如果该对象的类型没有相关转换器,则调用toString方法,并返回结果字符串。一个特殊之处:如果不用#前缀访问ValueStack Context中的对象,则该对象必须是String类型。

三、Struts2中的struts-tags与OGNL详细
要使用struts-tags标签,必须先引入struts-2.1.7.dtd文档类型定义文件。
:用于输出某个OGNL表达式的值,可以认为其内部使用的是ValueStack对象的findString方法。如果没有设置value属性,则输出ValueStack栈顶的对象。
特例:如果采用不加#前缀的方式输出Context中的某个对象,这个对象必须是string类型。
如:获取contextMap中的request对象。

:用于将OGNL表达式的值压入栈顶,当遇到标签时,从栈顶弹出。
如:向栈顶压入了一个字符串——“你好!”。



注意压入的字符串必须被包含在''中,否则会被OGNL当做名称到根对象中查找相应的值。
通过查看标签的帮助,可以知道有一个为top的特殊OGNL表达式,表示栈顶的对象。
如:

:用于实例化一个JavaBean对象,并将其压入栈顶。如果设置了var属性,还会将实例化的对象存储进ValueStack关联的Context中。
如:实例化一个java.util.Date对象,然后将其放入ContextMap中。



:用于将某个值存入指定范围域中,通常用于将一个复杂的ognl表达式用一个简单的变量来进行引用。
如:向request域中添加一个名称为“TestSet”的属性。



scope属性:指定变量被放置的范围,该属性可以接受application、session、request、 page或action。该属性的默认值为action,文档说即表示同时存储进request作用域和OGNL Context中,但实验结果是只存储进了OGNL Context中。
value属性:赋给变量的ognl表达式结果.如果没有设置该属性,则将ValueStack栈顶的值赋给变量。
:等标签用于判断test属性中指定的ognl表达式的结果是否为true,为真则执行标签体重的内容。
如:设置一个VAL,然后判断VAL的值,并显示相应的结果。










:用于迭代一个OGNL集合,并逐一将迭代出来的元素压入栈顶和弹栈。
如:获取request中的所有属性,并且使表格奇数行颜色为#f3c3c3,偶数行颜色为#c3f3f3。






' >




KeyValue

status属性:创建代表当前迭代状态的IteratorStatus对象,并指定将其存储进ValueStack Context中时的key。它与官方给出的帮助文档的说明不同,官方存在错误!

使用这两个标签可以带给我们极大的方便,使用他们的好处有:
使用不用关心web应用程序的路径和Action映射的扩展名。中没有指定namespace属性时,将根据浏览器当前所访问的url地址来推测包名,并与action属性指定的内容一起生成最终的url地址。
可以自动附加jsessionid参数进行url重写。
可以对参数信息进行url编码。 (jstl中的标准标签也有标签的后两个作用。)
直接使用标签可以获得当前地址,只有使用includeParams属性会带上原来的请求参数。大型网站的链接地址总是要带上userid之类的信息。
如:生成一个访问我们昨天编写的HelloWorld请求超连接。
HelloWorld

四、OGNL中的语法细节
1.参看ognl的参考手册
类似EL表达式的JavaBean属性访问和索引访问,例如,可以用”#parameter.id[0]”或”#parameter[‘id’][0]”访问名称为id的请求参数。
支持类静态方法调用和属性访问,表达式的格式为@[类全名(包括包路径)]@[方法名 | 值名],例如:@java.lang.String@format(‘foo %s’, ‘bar’)或@cn.itcast.Constant@APP_NAME;
session.attribute[“foo”]等效于session.getAttribute(“foo”)方法。
在OGNL中可以写很大的整数,例如,,而在java中则不能直接写1111111111111111111111这么大的整数。
对当前值可以进一步操作,,其中.(#this …..)部分相当于定义了一个匿名方法,并调用这个匿名方法,方法的代码就是()里面的内容。
2.Struts2扩展的特殊功能
[n]表示从原来堆栈中截取一个子堆栈并对这个子堆栈进行操作,子堆栈为原始堆栈的栈顶开始的索引号为n的元素一直到栈底,例如,[1].age表示从原始堆栈中的索引号为1的对象(即第二个对象)开始查找age属性,以找到的第一个为准。
top表示ValueStack栈顶的对象,[0].top和top表示同一个对象。
3.集合对象与操作
{}用于创建List集合对象,其中的各个元素之间用逗号分隔:

采用类似Java的语法创建数组:


#{}用于创建Map集合对象,其中的各个元素之间用逗号分隔,元素的key和value之间采用冒号分隔。另外,还可以指定Map实例对象的类型:


in与not in操作符用于判断某个值是否位于某个集合中。




集合伪属性:size/isEmpty/iterator/keys/values/next/hasNext。




4.集合的投影与过滤
投影就是拿着集合中的每个元素去进行运算,各个元素运算的结果组成一个新集合,新集合中的元素个数与原始集合中的元素个数相同。


过滤就是拿着集合中的每个元素去进行布尔运算,运算的结果为true,则将该元素保存到新集合中去。
?:获得所有符合逻辑的元素。

^:获得符合逻辑的第一个元素。

$:获得符合逻辑的最后一个元素。

5.类型转换
转换成boolean类型:
整数0转换为fals
值为0的字符转化为false
Null对象转化为false
投影和选择操作符(e1.{e2} and e1.{?e2})里面的内容会被转换成集合
Map会被转化成其values属性返回的集合
数字会被转换成从0开始到比该数字小1的所有数字的集合。
单个对象被转换成仅仅只含有该对象的集合。


${m.key}

${v }


<%
     List> students = new ArrayList>();
        Map s1 = new HashMap();
        s1.put("name","jim");
        s1.put("age","15");
        students.add(s1);
           Map s2 = new HashMap();
        s2.put("name","lucy");
        s2.put("age","12");
        students.add(s2);
       
       request.setAttribute("students",students);  

 

%> 
 
   


      
       
       
      
      
      
         

         
              
         
         
      
      
   
姓名
       
年龄
       

         

          
         

 

<%@taglib prefix="c" uri=" http://java.sun.com/jsp/jstl/core"%>
然后可以像下面这样遍历(假设你的map的bean名称为:mapBean)

map键名:${item.key}   map键值: ${item.value}


继续追问: 可以根据键值获取value吗? 补充回答: 可以,更简单(中括号里面双引号或单引号均可):
${mapBean["键名"]}

一、request 范围 print_map.jsp

<%@ page contentType="text/html" pageEncoding="UTF-8" import="java.util.*" %>

   
       
        EL输出集合
   
   
        <%
            Map map = new HashMap();        // 实例化 List 接口
            map.put("yc", "雨尘");        // 向集合中增加内容
            map.put("etecha", "www.etecha.com");        // 向集合中增加内容
            map.put("email", "[email protected]");    // 向集合中增加内容
            request.setAttribute("info", map);        // 向 request 集合中保存
        %>
       

key 为  的内容:${info["yc"]}


       

key 为  的内容:${info.etecha}


       

key 为  的内容:${info.email}


   

 

二、session 范围 print_map_session.jsp

<%@ page contentType="text/html" pageEncoding="UTF-8" import="java.util.*" %>

   
       
        EL输出集合
   
   
        <%
            Map map = new HashMap();        // 实例化 List 接口
            map.put("yc", "雨尘");        // 向集合中增加内容
            map.put("etecha", "www.etecha.com");        // 向集合中增加内容
            map.put("email", "[email protected]");    // 向集合中增加内容
            session.setAttribute("info", map);        // 向 request 集合中保存
        %>
       

key 为  的内容:${info["yc"]}


       

key 为  的内容:${info["etecha"]}


       

key 为  的内容:${info.email}


   

 

三、application 范围 print_map_application.jsp

<%@ page contentType="text/html" pageEncoding="UTF-8" import="java.util.*" %>

   
       
        EL输出集合
   
   
        <%
            Map map = new HashMap();        // 实例化 List 接口
            map.put("yc", "雨尘");        // 向集合中增加内容
            map.put("etecha", "www.etecha.com");        // 向集合中增加内容
            map.put("email", "[email protected]");    // 向集合中增加内容
            application.setAttribute("info", map);        // 向 request 集合中保存
        %>
       

key 为  的内容:${info.yc}


       

key 为  的内容:${info["etecha"]}


       

key 为  的内容:${info["email"]}


   

 
EL表达式遍历map的key和value <转>  2010-09-23 23:19:28|  分类: jsp |  标签: |字号大中小 订阅 .

<转>

 

在EL中,方括号运算符用来检索数组和集合的元素。对于实现 java.util.Map 接口的集合,方括号运算符使用关联的键查找存储在映射中的值。


在方括号中指定键,并将相应的值作为表达式的值返回。例如,表达式 ${map['key']} 返回与 map标识符所引用的 Map 中的 "key" 键相关联的值。
当forEach 的items属性中的表达式的值是java.util.Map时,则var中命名的变量的类型就是 java.util.Map.Entry。这时var=entry的话,用表达式${entry.key}取得键名。用表达${entry.value}得到每个entry的值。这是因为java.util.Map.Entry对象有getKey和getValue方法,表达式语言遵守JavaBean的命名约定。
<%
Map map2 = new HashMap();
map2.put("a","hello world");
map2.put("b","this is map");
request.setAttribute("map2",map2);
%>


键值对遍历


${item.key} > ${item.value}


键遍历


${item.key}


值遍历


${item.value}






<%
List list = new ArrayList();
list.add("first");
list.add("second");
List list2 = new ArrayList();
list2.add("aaaaaa");
list2.add("bbbbbb");
Map> map = new HashMap();
map.put("a",list);
map.put("b",list2);
request.setAttribute("map",map);
%>
通过键获得列表值,并遍历列表


${item }




${item }



map中值为列表,直接遍历列表中的每一项



${it }


 

                                                                                                不同方式遍历Map集合

Map是一种以键值对的形式存在的集合,其中每个键映射到一个值,几乎所有通用 Map 都使用哈希映射。位于java.util包中。其子类有HashMap,TreeMap。HashMap缺省的情况下是线程非安全的;当多线程访问时可能需要提供同步机制,key和value的值允许为null,键值允许重复,没有顺序。
          普通JAVA类遍历Map集合
          Map map=new HashMap();
map.put("a", "1");
  map.put("b", "2");
map.put("c", "3");
map.keySet();//键集合
map.values();//值集合
map.entrySet();//键值集合
//遍历键,通过键取值
Set set = map.keySet();
for (Object key : set) {
System.out.println("键:"+key+"  值:"+map.get(key));
}
//遍历键集合
Iterator it=map.keySet().iterator();
while(it.hasNext()){
System.out.println("键:"+it.next());
}
//遍历键值集合
Iterator it2=map.entrySet().iterator();
while(it2.hasNext()){
System.out.println(it2.next());
}
使用EL表达式遍历Map集合
   <%
     Map map=new HashMap();
map.put("a", "1");
map.put("b", "2");
map.put("c", "3");
pageContext.setAttribute("map",map);
     %>
    
     键:${m.key}
     值:${m.value}
    

使用EL表达式遍历Map集合(值存放的是对象)
 <%
    Person p=new Person();
    p.setAddress("aa");
    p.setName("aa");
        Person p2=new Person();
    p2.setAddress("bb");
    p2.setName("bb");
        Person p3=new Person();
    p3.setAddress("cc");
    p3.setName("cc");
    Map map=new HashMap();
map.put("a", p);
map.put("b", p2);
map.put("c", p3);
pageContext.setAttribute("map",map);
     %>
    
     ${m.key}
     ${m.value.name} //m.value取得的是对象的内存地址,所以可以直接用m.value.name(name为Person对象的属性)
    

 
使用struts标签遍历
<%
    List list=new ArrayList();
    list.add("aa");
    list.add("bb");
    list.add("cc");
    Map map=new HashMap();
map.put("a", list);
pageContext.setAttribute("map",map);
     %>
   
     键:${m.key}
     内层标签的name对应的是外层标签的id,一定要加上property="value"
     值:${childm}
    

   

 

jquery
假设

可以用
$("tr[name='abc'])
其它元素的name的取法,你更改 tr 就行了
$("*[name='a']")


$("#idName")取id的jquery对象
$("div") 或者 $("p")取html节点的jquery对象

 

  博客首页 注册 建议与交流 排行榜 加入友情链接   推荐 投诉 搜索:  帮助
IT民工窝棚

 长期从事高难度、高压力、高伤害、耗体力、耗精力、耗时间、低工资、低补助、低趣味、随叫随到的工作
---- 这就是程序员,三高三低三耗
   qbq.cublog.cn  管理博客 发表文章 留言 收藏夹 博客圈 音乐 相册 · MAVEN · tomcat&apache 导入文章 文章 · 马尔代夫 · 日本 · 体育 · 文学收藏 · 图片 · 音乐   }· 日本 · 欧美 · 国产 · 英语 · 原创空间 · 知识宝库 · 电影 · 个人日记 · 关于工作 · 技术收藏   }· Digit · Hardware   }· DIY · Notebook · Software   }· DATABASE   }· 数据库   }· HSQL · MYSQL · ORACLE · SQLSERVER · SQL · English · Microsoft   }· Bat · DotNet   }· CSharp.NET · VB.NET · Excel · Windows · Word · Multimedia   }· AS2 · Flex AS3 · OpenSource   }· amCharts · 面试 · Commet · Eclipse · EL   }· JSTL · Framework · Groovy on Grails · Guice · Hibernate · Ivy · JAVA · JavaScript   }· AJAX   }· DWR · JQuery · Prototype · Ext · JFreeChart · JSP · Linux · Log4J · Maven · OGNL · PHP · Portlet · Python · Seasar-SAStruts   }· S2Dao · Servlet · Spring   }· Spring问题集 · Struts   }· taglib · Struts2 · Tools · URLRewrite · WebServer · WebService · Source Safe · Thinking In Software · Web   }· CSS · HTML 首页  
 
 关于作者  
 
 
 
一个通用的DAO接口及其Hibernate3实现 
import java.io.*;
import java.util.*;

/**
 * 通用DAO,用于对象的持久化、查询(分页)
 *
 * @author SunHui
 *
 */
public interface Dao {
 /**
  * 保存(持久化)一个对象
  *
  * @param object
  * 要保存的对象
  */
 public void save(Object object);

 /**
  * 更新一个对象
  *
  * @param object
  * 要修改的对象
  */
 public void update(Object object);

 /**
  * 用语句更新记录
  *
  * @param queryString
  * 查询语句
  * @param parameters
  * 参数
  */
 public void updateByQuery(final String queryString,
   final Object[] parameters);

 /**
  * 删除一个对象
  *
  * @param object
  * 要删除的对象
  */
 public void delete(Object object);

 /**
  * 根据类型和对象id删除一个对象
  *
  * @param clazz
  * 类型
  * @param id
  * 对象id
  */
 public void delete(Class clazz, Serializable id);

 /**
  * 根据类型删除全部对象
  *
  * @param clazz
  * 类型
  * @return Integer
  */
 public Integer deleteAll(final Class clazz);

 /**
  * 根据查询和参数删除全部对象
  *
  * @param queryString
  * 查询语句
  * @param parameters
  * 参数
  * @return Integer
  */
 public Integer deleteByQuery(final String queryString,
   final Object[] parameters);

 /**
  * 获得某个类型的全部对象列表
  *
  * @param clazz
  * 类型
  * @return 对象集合
  */
 public List findAll(Class clazz);

 /**
  * 根据类型和对象id载入一个对象
  *
  * @param clazz
  * 类型
  * @param id
  * 对象id
  * @return 目标对象
  */
 public Object load(Class clazz, Serializable id);

 /**
  * 根据类型和对象id从数据库取得一个对象
  *
  * @param clazz
  * 类
  * @param id
  * 对象id
  * @return 目标对象
  */
 public Object get(Class clazz, Serializable id);

 /**
  * 根据查询语句和查询参数从数据库取得一个对象
  *
  * @param queryString
  * 查询语句
  * @param parameters
  * 参数
  * @return Object 单个对象
  */
 public Object get(final String queryString, final Object[] parameters);

 /**
  * 命名查询
  *
  * @param queryName
  * 命名查询语句
  * @return 对象列表
  */
 public List findByNamedQuery(final String queryName);

 /**
  * 依据单个参数做命名查询
  *
  * @param query
  * 命名查询语句
  * @param parameter
  * 单个查询参数
  * @return 对象列表
  */
 public List findByNamedQuery(final String queryString,
   final Object parameter);

 /**
  * 依据参数数组做命名查询
  *
  * @param query
  * 命名查询语句
  * @param parameters
  * 查询参数数组
  * @return 对象列表
  */
 public List findByNamedQuery(final String queryString,
   final Object[] parameters);

 /**
  * 查询全部
  *
  * @param query
  * 查询语句
  * @return 对象列表
  */
 public List find(final String queryString);

 /**
  * 带参数查询全部
  *
  * @param queryString
  * 查询语句
  * @param parameters
  * 查询参数
  * @return 对象列表
  */
 public List find(final String queryString, final Object[] parameters);

 /**
  * 分页查询
  *
  * @param queryString
  * 查询语句
  * @param parameters
  * 参数
  * @param pageInfo
  * 分页信息
  * @return List 对象列表
  */
 public List findPageByQuery(final String queryString,
   final Object[] parameters, final PageInfo pageInfo);

}

以下为Dao的Hibernate3实现

import java.io.*;
import java.util.*;

import org.hibernate.*;
import org.springframework.orm.hibernate3.*;
import org.springframework.orm.hibernate3.support.*;

/**
 * 通用DAO的Hibernate实现
 *
 * @author SunHui
 *
 */
public class DaoImpl extends HibernateDaoSupport implements Dao {

 public void save(Object object) {
  getHibernateTemplate().save(object);
 }

 public void update(Object object) {
  getHibernateTemplate().update(object);
 }

 public void updateByQuery(final String queryString, final Object[] parameters) {
  getHibernateTemplate().execute(new HibernateCallback() {
   public Object doInHibernate(Session session) {
    Query query = session.createQuery(queryString);
    if (parameters != null) {
     for (int i = 0; i < parameters.length; i++) {
      query.setParameter(i, parameters[i]);
     }
    }
    query.executeUpdate();
    return null;
   }
  });
 }

 public void delete(Object object) {
  getHibernateTemplate().delete(object);
 }

 public void delete(Class clazz, Serializable id) {
  getHibernateTemplate().delete(load(clazz, id));
 }

 public Integer deleteAll(final Class clazz) {
  return (Integer) getHibernateTemplate().execute(
    new HibernateCallback() {
     public Object doInHibernate(Session session) {
      Query query = session.createQuery("delete "
        + clazz.getName());
      return new Integer(query.executeUpdate());
     }
    });
 }

 public List findAll(Class clazz) {
  return getHibernateTemplate().find("from " + clazz.getName());
 }

 public Object load(Class clazz, Serializable id) {
  return getHibernateTemplate().load(clazz, id);
 }

 public Object get(Class clazz, Serializable id) {
  return getHibernateTemplate().get(clazz, id);
 }

 public List findByNamedQuery(final String queryName) {
  return getHibernateTemplate().findByNamedQuery(queryName);
 }

 public List findByNamedQuery(final String queryName, final Object parameter) {
  return getHibernateTemplate().findByNamedQuery(queryName, parameter);
 }

 public List findByNamedQuery(final String queryName, final Object[] parameters) {
  return getHibernateTemplate().findByNamedQuery(queryName, parameters);
 }

 public List find(final String queryString) {
  return getHibernateTemplate().find(queryString);
 }

 public List find(final String queryString, final Object[] parameters) {
  return getHibernateTemplate().find(queryString, parameters);
 }

 public List findPageByQuery(final String queryString, final Object[] parameters,
   final PageInfo pageInfo) {
  return (List) getHibernateTemplate().execute(new HibernateCallback() {
   public Object doInHibernate(Session session)
     throws HibernateException {
    Query query = session.createQuery(queryString);
    if (parameters != null) {
     for (int i = 0; i < parameters.length; i++) {
      query.setParameter(i, parameters[i]);
     }
    }
    ScrollableResults sr = query.scroll();
    sr.last();
    int totalCount = sr.getRowNumber();
    int startIndex = (pageInfo.getPageIndex() - 1) * pageInfo.getPageSize();
    query.setMaxResults(pageInfo.getPageSize());
    query.setFirstResult(startIndex);
    int totalRec = totalCount + 1;
    pageInfo.setTotalRec(totalRec);
    int totalPage = (totalRec % pageInfo.getPageSize() == 0) ? (totalRec / pageInfo.getPageSize())
      : (totalRec / pageInfo.getPageSize()) + 1;
    int[] pageNumbers = new int[totalPage];
    for (int i = 0; i < totalPage; i++) {
     pageNumbers[i] = (i + 1);
    }
    pageInfo.setPageNumbers(pageNumbers);
    pageInfo.setTotalPage(totalPage);
    pageInfo.setPageSize(pageInfo.getPageSize());
    pageInfo.setPageIndex(pageInfo.getPageIndex());
    pageInfo.setPrePage(pageInfo.getPageIndex() - 1);
    pageInfo.setNextPage(pageInfo.getPageIndex() + 1);
    return query.list();
   }
  }, true);
 }

 public Integer deleteByQuery(final String queryString, final Object[] parameters) {
  return (Integer) getHibernateTemplate().execute(
    new HibernateCallback() {
     public Object doInHibernate(Session session) {
      Query query = session.createQuery(queryString);
      if (parameters != null) {
       for (int i = 0; i < parameters.length; i++) {
        query.setParameter(i, parameters[i]);
       }
      }
      return new Integer(query.executeUpdate());
     }
    });
 }

 public Object get(final String queryString, final Object[] parameters) {
  List list = getHibernateTemplate().find(queryString, parameters);
  if (list != null && !list.isEmpty()) {
   return list.get(0);
  }
  return null;
 }
}


/**
 * 通用分页信息类,用于承载分页信息
 *
 * @author SunHui
 *
 */
public class PageInfo {
 /**
  * 总页数
  */
 private int totalPage = 1;

 /**
  * 前一页
  */
 private int prePage = 1;

 /**
  * 下一页
  */
 private int nextPage = 1;

 /**
  * 总记录数
  */
 private int totalRec = 0;

 /**
  * 默认每页记录数
  */
 private final int defaultPageSize = 10;

 /**
  * 每页记录数
  */
 private int pageSize = defaultPageSize;

 /**
  * 当前页码
  */
 private int pageIndex = 1;

 /**
  * 全部页码,从1开始
  */
 private int[] pageNumbers;

 public int getPageIndex() {
  return pageIndex;
 }

 public void setPageIndex(int pageIndex) {
  this.pageIndex = pageIndex > 0 ? pageIndex : 1;
 }

 public int getNextPage() {
  return nextPage;
 }

 public void setNextPage(int nextPage) {
  this.nextPage = nextPage > this.totalPage ? this.totalPage : nextPage;
 }

 public int getPageSize() {
  return pageSize;
 }

 public void setPageSize(int pageSize) {
  this.pageSize = pageSize > 0 ? pageSize : 10;
 }

 public int getPrePage() {
  return prePage;
 }

 public void setPrePage(int prePage) {
  this.prePage = prePage < 1 ? 1 : prePage;
 }

 public int getTotalPage() {
  return totalPage;
 }

 public void setTotalPage(int totalPage) {
  this.totalPage = totalPage > 0 ? totalPage : 1;
 }

 public int getTotalRec() {
  return totalRec;
 }

 public void setTotalRec(int totalRec) {
  this.totalRec = totalRec > -1 ? totalRec : 0;
 }

 public int[] getPageNumbers() {
  return pageNumbers;
 }

 public void setPageNumbers(int[] pageNumbers) {
  this.pageNumbers = pageNumbers;
 }
}

 gethibernatetemplate find条件查询方法
Spring中常用的hql查询方法(getHibernateTemplate())

 

---------------------------------

一、find(String queryString);

     示例:this.getHibernateTemplate().find("from bean.User");

     返回所有User对象

 

二、find(String queryString , Object value);

     示例:this.getHibernateTemplate().find("from bean.User u where u.name=?", "test");

     或模糊查询:this.getHibernateTemplate().find("from bean.User u where u.name like ?", "%test%");

     返回name属性值为test的对象(模糊查询,返回name属性值包含test的对象)

 

三、find(String queryString, Object[] values);

     示例:String hql= "from bean.User u where u.name=? and u.password=?"

               this.getHibernateTemplate().find(hql, new String[]{"test", "123"});

     返回用户名为test并且密码为123的所有User对象

 

---------------------------------

四、findByExample(Object exampleEntity)

     示例:

            User u=new User();   

            u.setPassword("123");//必须 符合的条件但是这两个条件时并列的(象当于sql中的and)   

            u.setName("bb");   

            list=this.getHibernateTemplate().findByExample(u,start,max); 

     返回:用户名为bb密码为123的对象

 

五、findByExample(Object exampleEntity, int firstResult, int maxResults)

     示例:

           User u=new User();   

           u.setPassword("123");//必须 符合的条件但是这两个条件时并列的(象当于sql中的and)   

           u.setName("bb");   

           list=this.getHibernateTemplate().findByExample(u,start,max);   

     返回:满足用户名为bb密码为123,自start起共max个User对象。(对象从0开始计数)

 

---------------------------------------------------

六、findByNamedParam(String queryString , String paramName , Object value)

 

   使用以下语句查询:

        String queryString = "select count(*) from bean.User u where u.name=:myName";

        String paramName= "myName";

        String value= "xiyue";

        this.getHibernateTemplate().findByNamedParam(queryString, paramName, value);

        System.out.println(list.get(0));

    返回name为xiyue的User对象的条数

 

七、findByNamedParam(String queryString , String[] paramName , Object[] value)

     示例:

        String queryString = "select count(*) from bean.User u where u.name=:myName and u.password=:myPassword";

        String[] paramName= new String[]{"myName", "myPassword"};

        String[] value= new String[]{"xiyue", "123"};

        this.getHibernateTemplate().findByNamedParam(queryString, paramName, value);

        返回用户名为xiyue密码为123的User对象

 

八、findByNamedQuery(String queryName)

     示例:

       1、首先需要在User.hbm.xml中定义命名查询

           

                 ......

                

                     

                           from bean.User

                       ]]>

                

           

        2、如下使用查询:

            this.getHibernateTemplate().findByNamedQuery("queryAllUser");

 

九、findByNamedQuery(String queryName, Object value)

     示例:

       1、首先需要在User.hbm.xml中定义命名查询

           

                 ......

                

                     

                           from bean.User u where u.name = ?

                       ]]>

                

           

        2、如下使用查询:

            this.getHibernateTemplate().findByNamedQuery("queryByName", "test");

 

十、findByNamedQuery(String queryName, Object[] value)

     示例:

       1、首先需要在User.hbm.xml中定义命名查询

           

                 ......

                

                     

                           from bean.User u where u.name =? and u.password =?

                       ]]>

                

           

        2、如下使用查询:

            String[] values= new String[]{"test", "123"};

            this.getHibernateTemplate().findByNamedQuery("queryByNameAndPassword" , values);

 

十一、findByNamedQueryAndNamedParam(String queryName, String paramName, Object value)

示例:

       1、首先需要在User.hbm.xml中定义命名查询

           

                 ......

                

                     

                           from bean.User u where u.name =:myName

                       ]]>

                

           

        2、如下使用查询:

            this.getHibernateTemplate().findByNamedQuery("queryByName" , "myName", "test");

 

十二、findByNamedQueryAndNamedParam(String queryName, String[] paramName, Object[] value)

示例:

       1、首先需要在User.hbm.xml中定义命名查询

           

                 ......

                

                     

                           from bean.User u where u.name =:myName and u.password=:myPassword

                       ]]>

                

           

        2、如下使用查询:

            String[] names= new String[]{"myName", "myPassword"};

            String[] values= new String[]{"test", "123"};

 

            this.getHibernateTemplate().findByNamedQuery("queryByNameAndPassword" , names, values);

 

十三、findByValueBean(String queryString , Object value);

示例:

     1、定义一个ValueBean,属性名必须和HSQL语句中的:后面的变量名同名,此处必须至少有两个属性,分别为myName和myPassword,使用setter方法设置属性值后

         ValueBean valueBean= new ValueBean();

         valueBean.setMyName("test");

         valueBean.setMyPasswrod("123");

     2、

         String queryString= "from bean.User u where u.name=:myName and u.password=:myPassword";
         this.getHibernateTemplate().findByValueBean(queryString , valueBean);
十四、findByNamedQueryAndValueBean(String queryName , Object value);
示例:
      1、首先需要在User.hbm.xml中定义命名查询
           
                 ......
                
                                                 from bean.User u where u.name =:myName and u.password=:myPassword
                       ]]>
                

           

     2、定义一个ValueBean,属性名必须和User.hbm.xml命名查询语句中的:后面的变量名同名,此处必须至少有两个属性,分别为myName和myPassword,使用setter方法设置属性值后
         ValueBean valueBean= new ValueBean();
         valueBean.setMyName("test");
         valueBean.setMyPasswrod("123");
     3、
         String queryString= "from bean.User u where u.name=:myName and u.password=:myPassword";

         this.getHibernateTemplate().findByNamedQueryAndValueBean("queryByNameAndPassword", valueBean);

 编写Spring+Hibernate框架下的应用,总是离不了编写一个通用的泛型GenericHibernateDao。查阅了网上不少的GenericHibernateDao实现,归纳整理为如下实现,供后续编码参考。


-------------------- HSQL ----------------------------------------------
// 使用HSQL语句直接增加、更新、删除实体
public int bulkUpdate(String queryString);
// 使用带参数的HSQL语句增加、更新、删除实体
public int bulkUpdate(String queryString, Object[] values);
// 使用HSQL语句检索数据
public List find(String queryString);
// 使用带参数的HSQL语句检索数据
public List find(String queryString, Object[] values);
// 使用带命名的参数的HSQL语句检索数据
public List findByNamedParam(String queryString, String[] paramNames, Object[] values);
// 使用命名的HSQL语句检索数据
public List findByNamedQuery(String queryName);
// 使用带参数的命名HSQL语句检索数据
public List findByNamedQuery(String queryName, Object[] values);
// 使用带命名参数的命名HSQL语句检索数据
public List findByNamedQueryAndNamedParam(String queryName, String[] paramNames, Object[] values);
// 使用HSQL语句检索数据,返回
Iterator public Iterator iterate(String queryString);
 // 使用带参数HSQL语句检索数据,返回
 Iterator public Iterator iterate(String queryString, Object[] values);
 // 关闭检索返回的
 Iterator public void closeIterator(Iterator it);
 // -------------------------------- Criteria ------------------------------
 // 创建与会话无关的检索标准对象
 public DetachedCriteria createDetachedCriteria();
 // 创建与会话绑定的检索标准对象
 public Criteria createCriteria();
 // 使用指定的检索标准检索数据
 public List findByCriteria(DetachedCriteria criteria);
 // 使用指定的检索标准检索数据,返回部分记录
 public List findByCriteria(DetachedCriteria criteria, int firstResult, int maxResults);
 // 使用指定的实体及属性检索(满足除主键外属性=实体值)数据
 public List findEqualByEntity(T entity, String[] propertyNames);
 // 使用指定的实体及属性(非主键)检索(满足属性 like 串实体值)数据
 public List findLikeByEntity(T entity, String[] propertyNames);
 // 使用指定的检索标准检索数据,返回指定范围的记录
 public Integer getRowCount(DetachedCriteria criteria);
 // 使用指定的检索标准检索数据,返回指定统计值
 public Object getStatValue(DetachedCriteria criteria, String propertyName, String StatName);
 // -------------------------------- Others --------------------------------
 // 加锁指定的实体
 public void lock(T entity, LockMode lockMode);
 // 强制初始化指定的实体
 public void initialize(Object proxy);
 // 强制立即更新缓冲数据到数据库(否则仅在事务提交时才更新)
 public void flush(); }
 实现GenericDao接口的Hibernate的实现类 GenericHibernateDao package com.th.huz; import java.io.Serializable; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.Collection; import java.util.Iterator; import java.util.List; import org.apache.commons.beanutils.PropertyUtils; import org.hibernate.Criteria; import org.hibernate.LockMode; import org.hibernate.criterion.DetachedCriteria; import org.hibernate.criterion.Example; import org.hibernate.criterion.MatchMode; import org.hibernate.criterion.Order; import org.hibernate.criterion.Projections; import org.hibernate.criterion.Restrictions; import org.springframework.orm.hibernate3.support.Hiberna teDaoSupport;
 /** * GenericHibernateDao 继承 HibernateDao,简单封装 HibernateTemplate 各项功能, * 简化基于Hibernate Dao 的编写。 * * @author lny */ @SuppressWarnings("unchecked")
 public class GenericHibernateDao extends HibernateDaoSupport implements GenericDao {
 // 实体类类型(由构造方法自动赋值)
 private Class entityClass;
 // 构造方法,根据实例类自动获取实体类类型
 public GenericHibernateDao() { this.entityClass = null; Class c = getClass(); Type t = c.getGenericSuperclass(); if (t instanceof ParameterizedType) { Type[] p = ((ParameterizedType) t).getActualTypeArguments(); this.entityClass = (Class) p[0]; } }
 // -------------------- 基本检索、增加、修改、删除操作 --------------------
 // 根据主键获取实体。如果没有相应的实体,返回 null。
 public T get(PK id) { return (T) getHibernateTemplate().get(entityClass, id); }
 // 根据主键获取实体并加锁。如果没有相应的实体,返回 null。
 public T getWithLock(PK id, LockMode lock) { T t = (T) getHibernateTemplate().get(entityClass, id, lock);
 if (t != null) { this.flush(); // 立即刷新,否则锁不会生效。 } return t; }
 // 根据主键获取实体。如果没有相应的实体,抛出异常。
 public T load(PK id) { return (T) getHibernateTemplate().load(entityClass, id); }
 // 根据主键获取实体并加锁。如果没有相应的实体,抛出异常。
 public T loadWithLock(PK id, LockMode lock) { T t = (T) getHibernateTemplate().load(entityClass, id, lock);
 if (t != null) { this.flush(); // 立即刷新,否则锁不会生效。 } return t; }
 // 获取全部实体。 public List loadAll() { return (List) getHibernateTemplate().loadAll(entityClass); }
 // loadAllWithLock() ? // 更新实体
 public void update(T entity) { getHibernateTemplate().update(entity); }
 // 更新实体并加锁 public void updateWithLock(T entity, LockMode lock) {
 getHibernateTemplate().update(entity, lock); this.flush();
 // 立即刷新,否则锁不会生效。 }
 // 存储实体到数据库
 public void save(T entity) { getHibernateTemplate().save(entity); } // saveWithLock()?
  // 增加或更新实体
  public void saveOrUpdate(T entity) { getHibernateTemplate().saveOrUpdate(entity); }
  // 增加或更新集合中的全部实体
 public void saveOrUpdateAll(Collection entities) { getHibernateTemplate().saveOrUpdateAll(entities); }
 // 删除指定的实体
 public void delete(T entity) { getHibernateTemplate().delete(entity); }
 // 加锁并删除指定的实体
 public void deleteWithLock(T entity, LockMode lock) {
 getHibernateTemplate().delete(entity, lock); this.flush();
 // 立即刷新,否则锁不会生效。 }
 // 根据主键删除指定实体 public void deleteByKey(PK id) { this.delete(this.load(id)); }
  // 根据主键加锁并删除指定的实体
  public void deleteByKeyWithLock(PK id, LockMode lock) { this.deleteWithLock(this.load(id), lock); }
  // 删除集合中的全部实体
public void deleteAll(Collection entities) { getHibernateTemplate().deleteAll(entities); }
// -------------------- HSQL ----------------------------------------------
// 使用HSQL语句直接增加、更新、删除实体
public int bulkUpdate(String queryString) { return getHibernateTemplate().bulkUpdate(queryString); }
// 使用带参数的HSQL语句增加、更新、删除实体
public int bulkUpdate(String queryString, Object[] values) {
return getHibernateTemplate().bulkUpdate(queryString, values); }
// 使用HSQL语句检索数据
public List find(String queryString) { return getHibernateTemplate().find(queryString); }
// 使用带参数的HSQL语句检索数据
public List find(String queryString, Object[] values) {
return getHibernateTemplate().find(queryString, values); } // 使用带命名的参数的HSQL语句检索数据 public List findByNamedParam(String queryString, String[] paramNames, Object[] values) { return getHibernateTemplate().findByNamedParam(queryStrin g, paramNames, values); } // 使用命名的HSQL语句检索数据 public List findByNamedQuery(String queryName) { return getHibernateTemplate().findByNamedQuery(queryName) ; } // 使用带参数的命名HSQL语句检索数据 public List findByNamedQuery(String queryName, Object[] values) { return getHibernateTemplate().findByNamedQuery(queryName, values); } // 使用带命名参数的命名HSQL语句检索数据 public List findByNamedQueryAndNamedParam(String queryName, String[] paramNames, Object[] values) { return getHibernateTemplate().findByNamedQueryAndNamedPar am(queryName, paramNames, values); } // 使用HSQL语句检索数据,返回 Iterator public Iterator iterate(String queryString) { return getHibernateTemplate().iterate(queryString); } // 使用带参数HSQL语句检索数据,返回 Iterator public Iterator iterate(String queryString, Object[] values) { return getHibernateTemplate().iterate(queryString, values); } // 关闭检索返回的 Iterator public void closeIterator(Iterator it) { getHibernateTemplate().closeIterator(it); } // -------------------------------- Criteria ------------------------------ // 创建与会话无关的检索标准 public DetachedCriteria createDetachedCriteria() { return DetachedCriteria.forClass(this.entityClass); } // 创建与会话绑定的检索标准 public Criteria createCriteria() { return this.createDetachedCriteria().getExecutableCriteri a( this.getSession()); } // 检索满足标准的数据 public List findByCriteria(DetachedCriteria criteria) { return getHibernateTemplate().findByCriteria(criteria); } // 检索满足标准的数据,返回指定范围的记录 public List findByCriteria(DetachedCriteria criteria, int firstResult, int maxResults) { return getHibernateTemplate().findByCriteria(criteria, firstResult, maxResults); } // 使用指定的实体及属性检索(满足除主键外属性=实体值)数据
 public List findEqualByEntity(T entity, String[] propertyNames) {
 Criteria criteria = this.createCriteria();
 Example exam = Example.create(entity);
 exam.excludeZeroes();
 String[] defPropertys = getSessionFactory().getClassMetadata( entityClass).getPropertyNames();
 for (String defProperty : defPropertys) {
 int ii = 0; for (ii = 0; ii < propertyNames.length; ++ii) { if (defProperty.equals(propertyNames[ii])) { criteria.addOrder(Order.asc(defProperty)); break; } } if (ii == propertyNames.length) { exam.excludeProperty(defProperty); } } criteria.add(exam); return (List) criteria.list(); }
 // 使用指定的实体及属性检索(满足属性 like 串实体值)数据 public List findLikeByEntity(T entity, String[] propertyNames) { Criteria criteria = this.createCriteria();
  for (String property : propertyNames) { try { Object value = http://blog.soso.com/qz.q/PropertyUtils.getProperty(entity, property); if (value instanceof String) { criteria.add(Restrictions.like(property, (String) value, MatchMode.ANYWHERE)); criteria.addOrder(Order.asc(property)); } else { criteria.add(Restrictions.eq(property, value)); criteria.addOrder(Order.asc(property)); } } catch (Exception ex) {
  // 忽略无效的检索参考数据。 } } return (List) criteria.list(); } // 使用指定的检索标准获取满足标准的记录数 public Integer getRowCount(DetachedCriteria criteria) { criteria.setProjection(Projections.rowCount()); List list = this.findByCriteria(criteria, 0, 1); return (Integer) list.get(0); } // 使用指定的检索标准检索数据,返回指定统计值(max,min,avg,sum) public Object getStatValue(DetachedCriteria criteria, String propertyName, String StatName) { if (StatName.toLowerCase().equals("max")) criteria.setProjection(Projections.max(propertyNam e)); else if (StatName.toLowerCase().equals("min")) criteria.setProjection(Projections.min(propertyNam e)); else if (StatName.toLowerCase().equals("avg")) criteria.setProjection(Projections.avg(propertyNam e)); else if (StatName.toLowerCase().equals("sum")) criteria.setProjection(Projections.sum(propertyNam e)); else return null; List list = this.findByCriteria(criteria, 0, 1); return list.get(0); } // -------------------------------- Others -------------------------------- // 加锁指定的实体 public void lock(T entity, LockMode lock) { getHibernateTemplate().lock(entity, lock); } // 强制初始化指定的实体 public void initialize(Object proxy) { getHibernateTemplate().initialize(proxy); } // 强制立即更新缓冲数据到数据库(否则仅在事务提交时才更新) public void flush() { getHibernateTemplate().flush(); } } //以上代码来自网上收集

內连接仅选出两张表中互相匹配的记录.因此,这会导致有时我们需要的记录没有包含进来。

  为更好的理解这个概念,我们介绍两个表作演示。苏格兰议会中的政党表(party)和议员表(msp)。

party(Code,Name,Leader)
Code: 政党代码
Name: 政党名称
Leader: 政党领袖

msp(Name,Party,Constituency)
Name: 议员名
Party: 议员所在政党代码
Constituency: 选区

  在介绍左连接、右连接和全连接前,有一个数据库中重要的概念要介绍一下,即空值(NULL)。

  有时表中,更确切的说是某些字段值,可能会出现空值, 这是因为这个数据不知道是什么值或根本就不存在。

  空值不等同于字符串中的空格,也不是数字类型的0。因此,判断某个字段值是否为空值时不能使用=,<>这些判断符。必需有专用的短语:IS NULL 来选出有空值字段的记录,同理,可用 IS NOT NULL 选出不包含空值的记录。

  例如:下面的语句选出了没有领导者的政党。(不要奇怪,苏格兰议会中确实存在这样的政党)

SELECT code, name FROM party
WHERE leader IS NULL

  又如:一个议员被开除出党,看看他是谁。(即该议员的政党为空值)

SELECT name FROM msp
WHERE party IS NULL

  好了,让我们言归正传,看看什么叫左连接、右连接和全连接。

  A left join(左连接)包含所有的左边表中的记录甚至是右边表中没有和它匹配的记录。

  同理,也存在着相同道理的 right join(右连接),即包含所有的右边表中的记录甚至是左边表中没有和它匹配的记录。
而full join(全连接)顾名思义,左右表中所有记录都会选出来。

  讲到这里,有人可能要问,到底什么叫:包含所有的左边表中的记录甚至是右边表中没有和它匹配的记录。

  我们来看一个实例:

SELECT msp.name, party.name
FROM msp JOIN party ON party=code

  这个是我们上一节所学的Join(注意:也叫inner join),这个语句的本意是列出所有议员的名字和他所属政党。

  很遗憾,我们发现该查询的结果少了两个议员:Canavan MSP, Dennis。为什么,因为这两个议员不属于任何政党,即他们的政党字段(Party)为空值。那么为什么不属于任何政党就查不出来了?这是因为空值在作怪。因为议员表中政党字段(Party)的空值在政党表中找不到对应的记录作匹配,即FROM msp JOIN party ON party=code 没有把该记录连接起来,而是过滤出去了。

  在该短语中,msp在Join的左边,所有称为左表。party在Join的右边,所有称为右表。

  现在再看看这句话,“包含所有的左边表中的记录甚至是右边表中没有和它匹配的记录”,意思应该很明白了吧。执行下面这个语句,那两个没有政党的议员就漏不了了。

SELECT msp.name, party.name
FROM msp LEFT JOIN party ON party=code

  关于右连接,看看这个查询就明白了:

SELECT msp.name, party.name
FROM msp RIGHT JOIN party ON msp.party=party.code

  这个查询的结果列出所有的议员和政党,包含没有议员的政党,但不包含没有政党的议员。 那么既要包含没有议员的政党,又要包含没有政党的议员该怎么办呢,对了,全连接(full join)。

SELECT msp.name, party.name
FROM msp FULL JOIN party ON msp.party=party.code

System.out.println("action->admin.getName()="+admin.getName());
System.out.println("开始转码@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); System.out.println(new String(admin.getName().getBytes("ISO-8859-1"),"UTF-8"));
System.out.println(new String(admin.getName().getBytes("UTF8"),"UTF-8"));
System.out.println(new String(admin.getName().getBytes("GB2312"),"UTF-8"));
System.out.println(new String(admin.getName().getBytes("GBK"),"UTF-8"));
System.out.println(new String(admin.getName().getBytes("BIG5"),"UTF-8"));
System.out.println(URLEncoder.encode(admin.getName(),"UTF-8"));
System.out.println(URLDecoder.decode(admin.getName(),"UTF-8"));


1.OGNL表达式语言
OGNL是Object Graphic Navigation Language(对象图导航语言)的缩写,它是一个开源项目。 Struts 2框架使用OGNL作为默认的表达式语言。

相对EL表达式,它提供了平时我们需要的一些功能,如:
支持对象方法调用,如xxx.sayHello();
支持类静态方法调用和值访问,表达式的格式为@[类全名(包括包路径)]@[方法名 | 值名],例如:@java.lang.String@format('foo %s', 'bar')或@cn.itcast.Constant@APP_NAME;
操作集合对象。

Ognl 有一个上下文(Context)概念,说白了上下文就是一个MAP结构,它实现了java.utils.Map接口,在Struts2中上下文(Context)的实现为ActionContext,下面是上下文(Context)的结构示意图


2.访问上下文(Context)中的对象需要使用#符号标注命名空间,如#application、#session

另外OGNL会设定一个根对象(root对象),在Struts2中根对象就是ValueStack(值栈) 。如果要访问根对象(即ValueStack)中对象的属性,则可以省略#命名空间,直接访问该对象的属性即可。

在struts2中,根对象ValueStack的实现类为OgnlValueStack,该对象不是我们想像的只存放单个值,而是存放一组对象。在OgnlValueStack类里有一个List类型的root变量,就是使用他存放一组对象
|--request  
|--application  
context ------|--OgnlValueStack root变量[action, OgnlUtil, ... ]  
|--session  
|--attr  
|--parameters

在root变量中处于第一位的对象叫栈顶对象。通常我们在OGNL表达式里直接写上属性的名称即可访问root变量里对象的属性,搜索顺序是从栈顶对象开始寻找,如果栈顶对象不存在该属性,就会从第二个对象寻找,如果没有找到就从第三个对象寻找,依次往下访问,直到找到为止。
大家注意: Struts2中,OGNL表达式需要配合Struts标签才可以使用。如:

3.由于ValueStack(值栈)是Struts 2中OGNL的根对象,如果用户需要访问值栈中的对象,在JSP页面可以直接通过下面的EL表达式访问ValueStack(值栈)中对象的属性:
${foo} //获得值栈中某个对象的foo属性

如果访问其他Context中的对象,由于他们不是根对象,所以在访问时,需要添加#前缀。
application对象:用于访问ServletContext,例如#application.userName或者#application['userName'],相当于调用ServletContext的getAttribute("username")。

session对象:用来访问HttpSession,例如#session.userName或者#session['userName'],相当于调用session.getAttribute("userName")。

request对象:用来访问HttpServletRequest属性(attribute)的Map,例如#request.userName或者#request['userName'],相当于调用request.getAttribute("userName")。

parameters对象:用于访问HTTP的请求参数,例如#parameters.userName或者#parameters['userName'],相当于调用request.getParameter("username")。

attr对象:用于按page->request->session->application顺序访问其属性。

4.为何使用EL表达式能够访问valueStack中对象的属性

原因是Struts2对HttpServletRequest作了进一步的封装。简略代码如下:

public class StrutsRequestWrapper extends HttpServletRequestWrapper {
public StrutsRequestWrapper(HttpServletRequest req) {
super(req);
}
public Object getAttribute(String s) {
......
ActionContext ctx = ActionContext.getContext();
Object attribute = super.getAttribute(s);//先从request范围获取属性值
if (ctx != null) {
if (attribute == null) {//如果从request范围没有找到属性值,即从ValueStack中查找对象的属性值
......
ValueStack stack = ctx.getValueStack();
attribute = stack.findValue(s);
......
}
}
return attribute;
}
}

5.采用OGNL表达式创建List/Map集合对象

如果需要一个集合元素的时候(例如List对象或者Map对象),可以使用OGNL中同集合相关的表达式。
使用如下代码直接生成一个List对象:




生成一个Map对象:


=

Set标签用于将某个值放入指定范围。
scope:指定变量被放置的范围,该属性可以接受application、session、request、 page或action。如果没有设置该属性,则默认放置在OGNL Context中。
value:赋给变量的值.如果没有设置该属性,则将ValueStack栈顶的值赋给变量。


6.采用OGNL表达式判断对象是否存在于集合中
对于集合类型,OGNL表达式可以使用in和not in两个元素符号。其中,in表达式用来判断某个元素是否在指定的集合对象中;not in判断某个元素是否不在指定的集合对象中,如下所示。
in表达式:




不在

not in表达式:

不在



7.OGNL表达式的投影功能
除了in和not in之外,OGNL还允许使用某个规则获得集合对象的子集,常用的有以下3个相关操作符。
?:获得所有符合逻辑的元素。
^:获得符合逻辑的第一个元素。
$:获得符合逻辑的最后一个元素。
例如代码:

- $


在上面代码中,直接在集合后紧跟.{}运算符表明用于取出该集合的子集,{}内的表达式用于获取符合条件的元素,this指的是为了从大集合books筛选数据到小集合,需要对大集合books进行迭代,this代表当前迭代的元素。本例的表达式用于获取集合中价格大于35的书集合。
public class BookAction extends ActionSupport {
private List books;
....
@Override
public String execute() {
books = new LinkedList();
books.add(new Book("A735619678", "spring", 67));
books.add(new Book("B435555322", "ejb3.0",15));
}
}

8.property标签
property标签用于输出指定值:


default:可选属性,如果需要输出的属性值为null,则显示该属性指定的值
escape:可选属性,指定是否格式化HTML代码。
value:可选属性,指定需要输出的属性值,如果没有指定该属性,则默认输出ValueStack栈顶的值。
id:可选属性,指定该元素的标识


9. iterator标签
iterator标签用于对集合进行迭代,这里的集合包含List、Set和数组。


redblue>



value:可选属性,指定被迭代的集合,如果没有设置该属性,则使用ValueStack栈顶的集合。
id:可选属性,指定集合里元素的id。
status:可选属性,该属性指定迭代时的IteratorStatus实例。该实例包含如下几个方法:
int getCount(),返回当前迭代了几个元素。
int getIndex(),返回当前迭代元素的索引。
boolean isEven(),返回当前被迭代元素的索引是否是偶数
boolean isOdd(),返回当前被迭代元素的索引是否是奇数
boolean isFirst(),返回当前被迭代元素是否是第一个元素。
boolean isLast(),返回当前被迭代元素是否是最后一个元素。

10.if/elseif/else标签


23


21


都不等

10.url标签


生成类似如下路径:
/struts/test/helloworld_add.action?personid=23
红色部分为内容路径。

当标签的属性值作为字符串类型处理时, “%”符号的用途是计算OGNL表达式的值。




输出结果:
#myurl
http://www.foshanshop.net


11.表单标签_checkboxlist复选框

如果集合为list

生成如下html代码:



如果集合为MAP

生成如下html代码:




12. 表单标签_checkboxlist复选框
如果集合里存放的是javabean
<%
Person person1 = new Person(1,"第一个");
Person person2 = new Person(2,"第二个");
List list = new ArrayList();
list.add(person1);
list.add(person2);
request.setAttribute("persons",list);
%>

Personid和name为Person的属性

生成如下html代码:

13.表单标签_radio单选框
该标签的使用和checkboxlist复选框相同。
如果集合里存放的是javabean(personid和name为Person的属性)
< s:radio name="beans" list="#request.persons" listKey="personid" listValue="name"/>
生成如下html代码:


如果集合为MAP

生成如下html代码:




如果集合为list

生成如下html代码:

14.表单标签_select下拉选择框





你可能感兴趣的:(struts2标签)