Jul 1
  1. SAXReader reader = new SAXReader();
  2. Document doc = reader.read(...);
  3. List childNodes = doc.selectNodes("//Config/Child/ChildNode");
  4. for(Object obj:childNodes) {
  5. Node childNode = (Node)obj;
  6. String name = childNode.valueOf("@name");
  7. String text = childNode.getText();
  8. }
  9. 一.Document对象相关
  10. 1.读取XML文件,获得document对象.
  11. SAXReader reader = new SAXReader();
  12. Document document = reader.read(new File("input.xml"));
  13. 2.解析XML形式的文本,得到document对象.
  14. String text = "<members></members>";
  15. Document document = DocumentHelper.parseText(text);
  16. 3.主动创建document对象.
  17. Document document = DocumentHelper.createDocument();
  18. Element root = document.addElement("members");// 创建根节点
  19. 二.节点相关
  20. 1.获取文档的根节点.
  21. Element rootElm = document.getRootElement();
  22. 2.取得某节点的单个子节点.
  23. Element memberElm=root.element("member");// "member"是节点名
  24. 3.取得节点的文字
  25. String text=memberElm.getText();也可以用:
  26. String text=root.elementText("name");这个是取得根节点下的name字节点的文字.
  27. 4.取得某节点下名为"member"的所有字节点并进行遍历.
  28. List nodes = rootElm.elements("member");
  29. for (Iterator it = nodes.iterator(); it.hasNext();) {
  30. Element elm = (Element) it.next();
  31. // do something
  32. }
  33. 5.对某节点下的所有子节点进行遍历.
  34. for(Iterator it=root.elementIterator();it.hasNext();){
  35. Element element = (Element) it.next();
  36. // do something
  37. }
  38. 6.在某节点下添加子节点.
  39. Element ageElm = newMemberElm.addElement("age");
  40. 7.设置节点文字.
  41. ageElm.setText("29");
  42. 8.删除某节点.
  43. parentElm.remove(childElm);// childElm是待删除的节点,parentElm是其父节点
  44. 9.添加一个CDATA节点.
  45. Element contentElm = infoElm.addElement("content");
  46. contentElm.addCDATA(diary.getContent());
  47. 三.属性相关.
  48. 1.取得某节点下的某属性
  49. Element root=document.getRootElement();
  50. Attribute attribute=root.attribute("size");// 属性名name
  51. 2.取得属性的文字
  52. String text=attribute.getText();也可以用:
  53. String text2=root.element("name").attributeValue("firstname");这个是取得根节点下name字节点的属性firstname的值.
  54. 3.遍历某节点的所有属性
  55. Element root=document.getRootElement();
  56. for(Iterator it=root.attributeIterator();it.hasNext();){
  57. Attribute attribute = (Attribute) it.next();
  58. String text=attribute.getText();
  59. System.out.println(text);
  60. }
  61. 4.设置某节点的属性和文字.
  62. newMemberElm.addAttribute("name", "sitinspring");
  63. 5.设置属性的文字
  64. Attribute attribute=root.attribute("name");
  65. attribute.setText("sitinspring");
  66. 6.删除某属性
  67. Attribute attribute=root.attribute("size");// 属性名name
  68. root.remove(attribute);
  69. 四.将文档写入XML文件.
  70. 1.文档中全为英文,不设置编码,直接写入的形式.
  71. XMLWriter writer = new XMLWriter(new FileWriter("output.xml"));
  72. writer.write(document);
  73. writer.close();
  74. 2.文档中含有中文,设置编码格式写入的形式.
  75. OutputFormat format = OutputFormat.createPrettyPrint();
  76. format.setEncoding("GBK"); // 指定XML编码
  77. XMLWriter writer = new XMLWriter(new FileWriter("output.xml"),format);
  78. writer.write(document);
  79. writer.close();
  80. 五.字符串与XML的转换
  81. 1.将字符串转化为XML
  82. String text = "<members> <member>sitinspring</member> </members>";
  83. Document document = DocumentHelper.parseText(text);
  84. 2.将文档或节点的XML转化为字符串.
  85. SAXReader reader = new SAXReader();
  86. Document document = reader.read(new File("input.xml"));
  87. Element root=document.getRootElement();
  88. String docXmlText=document.asXML();
  89. String rootXmlText=root.asXML();
  90. Element memberElm=root.element("member");
  91. String memberXmlText=memberElm.asXML();
  92. dom4j API 包含一个解析 XML 文档的工具。本文中将使用这个解析器创建一个示例 XML 文档。清单 1 显示了这个示例 XML 文档,catalog.xml。
  93. 清单 1. 示例 XML 文档(catalog.xml)
  94. <?xml version="1.0" encoding="UTF-8"?>
  95. <catalog>
  96. <!--An XML Catalog-->
  97. <?target instruction?>
  98. <journal title="XML Zone"
  99. publisher="IBM developerWorks">
  100. <article level="Intermediate" date="December-2001">
  101. <title>Java configuration with XML Schema</title>
  102. <author>
  103. <firstname>Marcello</firstname>
  104. <lastname>Vitaletti</lastname>
  105. </author>
  106. </article>
  107. </journal>
  108. </catalog>
  109. 然后使用同一个解析器修改 catalog.xml,清单 2 是修改后的 XML 文档,catalog-modified.xml。
  110. 清单 2. 修改后的 XML 文档(catalog-modified.xml)
  111. <?xml version="1.0" encoding="UTF-8"?>
  112. <catalog>
  113. <!--An XML catalog-->
  114. <?target instruction?>
  115. <journal title="XML Zone"
  116. publisher="IBM developerWorks">
  117. <article level="Introductory" date="October-2002">
  118. <title>Create flexible and extensible XML schemas</title>
  119. <author>
  120. <firstname>Ayesha</firstname>
  121. <lastname>Malik</lastname>
  122. </author>
  123. </article>
  124. </journal>
  125. </catalog>
Jun 30
  1. 1、输出session中的值   
  2. a. <s:property value="#session['key']"/>  
  3. b. ${sessionScope.key}   
  4.   
  5. 2、获取session中的值后判断   
  6. <s:if test="#session['key']==null">  
  7.   
  8. 3、输出Action中的属性值   
  9. <s:property value="property"/>  
  10.   
  11. 4、输出国际化文件中的值   
  12. a. <s:text name="key"/>  
  13. b. ${getText("key")}   
  14.   
  15. 5、输出Action中的消息   
  16. <s:actionmessage />  
  17.   
  18. 6、输出Action中的错误   
  19. <s:actionerror/>  
  20.   
  21. 7、迭代输出集合   
  22. <s:iterator id="book" value="books" status="index">  
  23.   
  24.      <!---输出当前元素的属性-->  
  25.      <s:property value="property"/>  
  26.   
  27.      <!---输出当前迭代元素的索引-->  
  28.      <s:property value="#index.index"/>  
  29.   
  30.      <!---输出当前迭代了几个元素-->  
  31.      <s:property value="#index.count"/>   
  32.   
  33.       <!---返回当前迭代元素的索引是否为奇数-->  
  34.      <s:property value="#index.odd"/>   
  35.   
  36.      <!---返回当前迭代元素的索引是否为偶数-->  
  37.      <s:property value="#index.event"/>  
  38.   
  39.      <!---返回当前元素是否为第一个-->  
  40.      <s:property value="#index.first"/>  
  41.   
  42.      <!---返回当前元素是否为最后一个-->  
  43.      <s:property value="#index.last"/>  
  44.   
  45. </s:iterator>  
  46.   
  47. 8、定义页面变量   
  48. <!---将分页Bean的属性放入Stack Context-->  
  49. <s:set name="count" value="%{pager.totalPages}"/>  
  50.   
  51. <!---利用Struts2标签访问-->  
  52. <s:property value="#count"/>  
  53.   
  54. <!---利用OGNL表达式访问-->  
  55. ${pageScope.count }   
  56.   
  57. <!---利用Java代码访问-->  
  58. <%      
  59.       Object obj = pageContext.getAttribute("count");       
  60.       int mycount = Integer.parseInt(obj.toString());   
  61.       for(int i =0;i<mycount;i++){   
  62.             out.print(i+1);   
  63.       }   
  64. %>  
    1. struts2的s:iterator 可以遍历 数据栈里面的任何数组,集合等等 以下几个简单的demo:
      s:iterator 标签有3个属性:
          value:被迭代的集合
          id   :指定集合里面的元素的id
          status 迭代元素的索引

      1:jsp页面定义元素写法 数组或list
      1. <s:iterator value="{'1','2','3','4','5'}" id='number'>
      2.      <s:property value='number'/>A
      3. </s:iterator>
      1. 打印结果为: 1A2A3A4A5A

        2:索引的用法
        如果指定了status,每次的迭代数据都有IteratorStatus的实例,它有以下几个方法
        int getCount()返回当前迭代了几个元素
        int getIndex()返回当前元素索引
        boolean isEven()当然的索引是否偶数
        boolean isFirst()当前是否第一个元素
        boolean isLast()
        boolean isOdd()当前元素索引是否奇数
      1. <s:iterator value="{'a','b','c'}" id='char' status='st'>
      2.      <s:if test="#st.Even">
      3.          现在的索引是奇数为:<s:property value='#st.index'/>
      4.      </s:if>
      5.      当前元素值:<s:property value='char'/>
      6. </s:iterator>
      1. 3:遍历map
        value可以直接定义为:
        1. value="#{"1":"a","2":"b"}"
      2. 每个元素以都好隔开。元素之间的key和value 冒号隔开
        value也可以是数据栈里面的java.util.Map对象
        遍历写法如下:
      1. <s:iterator value="map" id="id" status="st">
      2.       key : <s:property value='key'/>
      3.       value:<s:property vlaue='value'/>
      4. </s:iterator>
      1. 当然key 和value 都可以使java 的 Object

        3:遍历数据栈.简单的List类,
        List<Attr>
        class Attr{String attrName;String getAttrName(){return "123";}}
      1. <s:iterator value="label" id="id">
      2.      <s:property value="#id.attrName" />
      3. </s:iterator>
      1. 当然value 还可以写成 value="%{label}" label可以有.操作
        label的属性List 可以写成value="%{label.list}" 相当于:getLabel().getList();

        4:遍历2个list;
        List<AttrName> attrN {color,size,style}
        List<AttrValue> attrV {red,20,gay}
        这2个list的元素是一一对应的,一个attrN对应一个attrV
      1. <s:iterator value="%{attrN }" id="id"   status="status">
      2. index     is : <s:property value='status.index'/>
      3. attrName is : <s:property value='id'/> or <s:property value='%{id}'/>
      4. attrName is : <s:property value='%{attrV[#status.index]}'/>
      5. </s:iterator>  
    1. <s:iterator value="{'1','2','3','4','5'}" id='number'>
    2.      <s:property value='number'/>A
    3. </s:iterator>
    1. 打印结果为: 1A2A3A4A5A

      2:索引的用法
      如果指定了status,每次的迭代数据都有IteratorStatus的实例,它有以下几个方法
      int getCount()返回当前迭代了几个元素
      int getIndex()返回当前元素索引
      boolean isEven()当然的索引是否偶数
      boolean isFirst()当前是否第一个元素
      boolean isLast()
      boolean isOdd()当前元素索引是否奇数
    1. <s:iterator value="{'a','b','c'}" id='char' status='st'>
    2.      <s:if test="#st.Even">
    3.          现在的索引是奇数为:<s:property value='#st.index'/>
    4.      </s:if>
    5.      当前元素值:<s:property value='char'/>
    6. </s:iterator>
    1. 3:遍历map
      value可以直接定义为:
      1. value="#{"1":"a","2":"b"}"
    2. 每个元素以都好隔开。元素之间的key和value 冒号隔开
      value也可以是数据栈里面的java.util.Map对象
      遍历写法如下:
    1. <s:iterator value="map" id="id" status="st">
    2.       key : <s:property value='key'/>
    3.       value:<s:property vlaue='value'/>
    4. </s:iterator>
    1. 当然key 和value 都可以使java 的 Object

      3:遍历数据栈.简单的List类,
      List<Attr>
      class Attr{String attrName;String getAttrName(){return "123";}}
    1. <s:iterator value="label" id="id">
    2.      <s:property value="#id.attrName" />
    3. </s:iterator>
    1. 当然value 还可以写成 value="%{label}" label可以有.操作
      label的属性List 可以写成value="%{label.list}" 相当于:getLabel().getList();

      4:遍历2个list;
      List<AttrName> attrN {color,size,style}
      List<AttrValue> attrV {red,20,gay}
      这2个list的元素是一一对应的,一个attrN对应一个attrV
    1. <s:iterator value="%{attrN }" id="id"   status="status">
    2. index     is : <s:property value='status.index'/>
    3. attrName is : <s:property value='id'/> or <s:property value='%{id}'/>
    4. attrName is : <s:property value='%{attrV[#status.index]}'/>
    5. </s:iterator>  
  • Jun 29

    使用Criteria进行查询时,不仅仅能组合出SQL中where子句的功能,还可以组合出如排序、统计、分组等的查询功能。这就是Criteria进阶查询。

    排序
    您可以使用Criteria进行查询,并使用org.hibernate.criterion.Order对结果进行排序,例如使用Oder.asc(),指定根据”age”由小到大排序(反之则使用desc()):

    1. Criteria criteria = session.createCriteria(User.class);
    2. criteria.addOrder(Order.asc("age"));
    3. List users = criteria.list();

    注意在加入Order条件时,使用的是addOrder()方法,而不是add()方法,在产生SQL语句时,会使用order by与asc(desc)来进行排序指定:

    Hibernate: select this_.id as id0_0_, this_.name as name0_0_, this_.age as age0_0_ from T_USER this_ order by this_.age asc

    限定查询笔数
    Criteria的setMaxResults()方法可以限定查询回来的笔数,如果配合setFirstResult()设定传回查询结果第一笔资料的位置,就可以实现简单的分页,例如传回第51笔之后的50笔资料(如果有的话):

    1. Criteria criteria = session.createCriteria(User.class);
    2. criteria.setFirstResult(51);
    3. criteria.setMaxResults(50);
    4. List users = criteria.list();

    根据您所指定得资料库,Hibernate将自动产生与资料库相依的限定笔数查询子句,例如在MySQL中,将使用limit产生以下的SQL语句:

    Hibernate: select this_.id as id0_0_, this_.name as name0_0_, this_.age as age0_0_ from T_USER this_ limit ?, ?

    统计动作
    您可以对查询结果进行统计动作,使用 org.hibernate.criterion.Projections的avg()、rowCount()、count()、max()、min ()、 countDistinct()等方法,再搭配Criteria的setProjection()方法加入条件设定,例如对查询结果的"age"作平均:

    1. Criteria criteria = session.createCriteria(User.class);
    2. criteria.setProjection(Projections.avg("age"));
    3. List users = criteria.list();

    上面的程式将由Hibernate自动产生SQL的avg函数进行平均计算:

    Hibernate: select avg(this_.age) as y0_ from T_USER this_

    分组
    还可以配合Projections的groupProperty()来对结果进行分组,例如以"age"进行分组,也就是如果资料中"age"如果有 20、20、25、30,则以下会显示20、25、30:

    1. Criteria criteria = session.createCriteria(User.class);
    2. criteria.setProjection(Projections.groupProperty("age"));
    3. List users = criteria.list();

    上面的程式将由Hibernate自动产生SQL的group by子句进行分组计算:

    Hibernate: select this_.age as y0_ from T_USER this_ group by this_.age

    如果想同时结合统计与分组功能,则可以使用org.hibernate.criterion.ProjectionList,例如下面的程式会计算每个年龄各有多少个人:

    1. ProjectionList projectionList = Projections.projectionList();
    2. projectionList.add(Projections.groupProperty("age"));
    3. projectionList.add(Projections.rowCount());
    4. Criteria criteria = session.createCriteria(User.class);
    5. criteria.setProjection(projectionList);
    6. List users = criteria.list();

    观察所产生的SQL语句,将使用group by先进行分组,再针对每个分组进行count函数的计数,

    Hibernate: select this_.age as y0_, count(*) as y1_ from T_USER this_ group by this_.age

    根据已知物件进行查询
    设定查询条件并非一定要使用Restrictions,如果属性条件很多,使用Restrictions也不方便,如果有一个已知的物件,则可以根据这个物件作为查询的依据,看看是否有属性与之类似的物件,例如:

    1. User user = new User();
    2. user.setAge(new Integer(30));
    3. Criteria criteria = session.createCriteria(User.class);
    4. criteria.add(Example.create(user));
    5. List users = criteria.list();

    Criteria进阶查询中,您可以透过 org.hibernate.criterion.Example的create()方法来建立Example实例,Example实作了 Criteria介面,因此可以使用add()方法加入至Criteria条件设定之中,Hibernate将自动过滤掉空属性,根据已知物件上已设定的属性,判定是否产生于where子句之中:

    Hibernate: select this_.id as id0_0_, this_.name as name0_0_, this_.age as age0_0_ from T_USER this_ where (this_.age=?)

    设定SQL范本
    如果您了解如何撰写SQL语句,想要设定一些Hibernate产生SQL时的范本,您也可以使用Restrictions的sqlRestriction()方法,提供SQL语法范本作限定查询,例如查询name以cater开头的资料:

    1. Criteria criteria = session.createCriteria(User.class);
    2. criteria.add(Restrictions.sqlRestriction(
    3. "{alias}.name LIKE (?)", "cater%", Hibernate.STRING));
    4. List users = criteria.list();

    其中alias将被替换为与User类别相关的名称,而? 将被替换为cater%,也就是第二个参数所提供的值,sqlRestriction()方法第一个参数所设定的是where子句的部份,所以在SQL撰写时,不必再写where,观察所产生的SQL语句,将使用您所设定的SQL范本作为基础,来完成SQL的条件查询:

    Hibernate: select this_.id as id0_0_, this_.name as name0_0_, this_.age as age0_0_ from T_USER this_ where this_.name LIKE (?)

    如果有多个查询条件,例如between子句的查询,则可以如下:

    1. Criteria criteria = session.createCriteria(User.class);
    2. Integer[] ages = {new Integer(20), new Integer(40)};
    3. Type[] types = {Hibernate.INTEGER, Hibernate.INTEGER};
    4. criteria.add(Restrictions.sqlRestriction(
    5. "{alias}.age BETWEEN (?) AND (?)", ages, types));
    6. List users = criteria.list();

    观察所产生的SQL语句如下:

    Hibernate: select this_.id as id0_0_, this_.name as name0_0_, this_.age as age0_0_ from T_USER this_ where this_.age BETWEEN (?) AND (?)

    Criteria进阶查询就介绍到这里。

    Jun 29
    最近在项目中使用 Spring 和 Hibernate 进行开发,有感于 Criteria 比较好用,在查询方法
    
    设计上可以灵活的根据 Criteria 的特点来方便地进行查询条件的组装。现在对 Hibernate的Criteria 的用法进行总结:
       Hibernate 设计了 CriteriaSpecification 作为 Criteria 的父接口,下面提供了 Criteria和DetachedCriteria
       Criteria 和 DetachedCriteria 的主要区别在于创建的形式不一样, Criteria 是在线的,所
    以它是由 Hibernate Session 进行创建的;而 DetachedCriteria 是离线的,创建时无需
    Session,DetachedCriteria 提供了 2 个静态方法 forClass(Class) 或 forEntityName(Name)
    进行DetachedCriteria 实例的创建。 Spring 的框架提供了getHibernateTemplate
    ().findByCriteria(detachedCriteria) 方法可以很方便地根据DetachedCriteria 来返回查询结
    果。
       Criteria 和 DetachedCriteria 均可使用 Criterion 和 Projection 设置查询条件。可以设

    置 FetchMode( 联合查询抓取的模式 ) ,设置排序方式。对于 Criteria 还可以设置 FlushModel
    (冲刷 Session 的方式)和 LockMode (数据库锁模式)。
    下面对 Criterion 和 Projection 进行详细说明。
         Criterion 是 Criteria 的查询条件。Criteria 提供了 add(Criterion criterion) 方法来
    添加查询条件。
         Criterion 接口的主要实现包括: Example 、 Junction 和 SimpleExpression 。而

    Junction 的实际使用是它的两个子类 conjunction 和 disjunction ,分别是使用 AND 和 OR 操
    作符进行来联结查询条件集合。
         Criterion 的实例可以通过 Restrictions 工具类来创建,Restrictions 提供了大量的静态

    方法,如 eq (等于)、 ge (大于等于)、 between 等来方法的创建 Criterion 查询条件
    (SimpleExpression 实例)。除此之外, Restrictions 还提供了方法来创建 conjunction 和
    disjunction 实例,通过往该实例的 add(Criteria) 方法来增加查询条件形成一个查询条件集合

         至于 Example 的创建有所不同, Example 本身提供了一个静态方法 create(Object

    entity) ,即根据一个对象(实际使用中一般是映射到数据库的对象)来创建。然后可以设置一些
    过滤条件:
    Example exampleUser =Example.create(u)
    .ignoreCase() // 忽略大小写
    .enableLike(MatchMode.ANYWHERE);
    // 对 String 类型的属性,无论在那里值在那里都匹配。相当于 %value%

      Project 主要是让 Criteria 能够进行报表查询,并可以实现分组。 Project 主要有
    SimpleProjection 、 ProjectionList 和 Property 三个实现。其中 SimpleProjection 和
    ProjectionList 的实例化是由内建的 Projections 来完成,如提供的 avg 、 count 、 max 、
    min 、 sum 可以让开发者很容易对某个字段进行统计查询。
           Property 是对某个字段进行查询条件的设置,如通过Porperty.forName(“color”).in

    (new String[]{“black”,”red”,”write”}); 则可以创建一个 Project 实例。通过
    criteria 的 add(Project) 方法加入到查询条件中去。
        使用 Criteria 进行查询,主要要清晰的是 Hibernate 提供了那些类和方法来满足开发中查
    询条件的创建和组装,下面介绍几种用法:
    1. 创建一个Criteria 实例
    org.hibernate.Criteria接口表示特定持久类的一个查询。Session是 Criteria实例的工厂。
    Criteria crit = sess.createCriteria(Cat.class);
    crit.setMaxResults(50);
    List cats = crit.list();
     
    2. 限制结果集内容
    一个单独的查询条件是org.hibernate.criterion.Criterion 接口的一个实例。


    org.hibernate.criterion.Restrictions类定义了获得某些内置Criterion类型的工厂方法。
    List cats = sess.createCriteria(Cat.class)
        .add( Restrictions.like("name", "Fritz%") )
        .add( Restrictions.between("weight", minWeight, maxWeight) )
        .list();


    约束可以按逻辑分组。
     
    List cats = sess.createCriteria(Cat.class)
        .add( Restrictions.like("name", "Fritz%") )
        .add( Restrictions.or(
            Restrictions.eq( "age", new Integer(0) ),
            Restrictions.isNull("age")
        ) )
        .list();
     
    List cats = sess.createCriteria(Cat.class)
        .add( Restrictions.in( "name", new String[] { "Fritz", "Izi", "Pk" } ) )
        .add( Restrictions.disjunction()
            .add( Restrictions.isNull("age") )
            .add( Restrictions.eq("age", new Integer(0) ) )
            .add( Restrictions.eq("age", new Integer(1) ) )
            .add( Restrictions.eq("age", new Integer(2) ) )
        ) )
        .list();
     
    Hibernate提供了相当多的内置criterion类型(Restrictions 子类), 但是尤其有用的是可以允许


    你直接使用SQL。
     
    List cats = sess.createCriteria(Cat.class)
        .add( Restrictions.sql("lower({alias}.name) like lower(?)", "Fritz%",


    Hibernate.STRING) )
        .list();
     
    {alias}占位符应当被替换为被查询实体的列别名。
    Property实例是获得一个条件的另外一种途径。你可以通过调用Property.forName() 创建一个


    Property。
     
      Property age = Property.forName("age");
    List cats = sess.createCriteria(Cat.class)
        .add( Restrictions.disjunction()
            .add( age.isNull() )
            .add( age.eq( new Integer(0) ) )
            .add( age.eq( new Integer(1) ) )
            .add( age.eq( new Integer(2) ) )
        ) )
        .add( Property.forName("name").in( new String[] { "Fritz", "Izi", "Pk" } ) )
        .list();
     
    3. 结果集排序
    你可以使用org.hibernate.criterion.Order来为查询结果排序。
     
    List cats = sess.createCriteria(Cat.class)
        .add( Restrictions.like("name", "F%")
        .addOrder( Order.asc("name") )
        .addOrder( Order.desc("age") )
        .setMaxResults(50)
        .list();
     
    List cats = sess.createCriteria(Cat.class)
        .add( Property.forName("name").like("F%") )
        .addOrder( Property.forName("name").asc() )
        .addOrder( Property.forName("age").desc() )
        .setMaxResults(50)
        .list();
     
    4. 关联
    你可以使用createCriteria()非常容易的在互相关联的实体间建立 约束。
     
    List cats = sess.createCriteria(Cat.class)
        .add( Restrictions.like("name", "F%")
        .createCriteria("kittens")
            .add( Restrictions.like("name", "F%")
        .list();



    注意第二个 createCriteria()返回一个新的 Criteria实例,该实例引用kittens 集合中的元素。
    接下来,替换形态在某些情况下也是很有用的。
     
    List cats = sess.createCriteria(Cat.class)
        .createAlias("kittens", "kt")
        .createAlias("mate", "mt")
        .add( Restrictions.eqProperty("kt.name", "mt.name") )
        .list();



    (createAlias()并不创建一个新的 Criteria实例。)
    Cat实例所保存的之前两次查询所返回的kittens集合是 没有被条件预过滤的。如果你希望只获得


    符合条件的kittens,你必须使用returnMaps()。
     
    List cats = sess.createCriteria(Cat.class)
        .createCriteria("kittens", "kt")
        .add( Restrictions.eq("name", "F%") )
        .returnMaps()
        .list();
    Iterator iter = cats.iterator();
    while ( iter.hasNext() ) {
        Map map = (Map) iter.next();
        Cat cat = (Cat) map.get(Criteria.ROOT_ALIAS);
        Cat kitten = (Cat) map.get("kt");
    }


    5. 动态关联抓取
    你可以使用setFetchMode()在运行时定义动态关联抓取的语义。
     
    List cats = sess.createCriteria(Cat.class)
        .add( Restrictions.like("name", "Fritz%") )
        .setFetchMode("mate", FetchMode.EAGER)
        .setFetchMode("kittens", FetchMode.EAGER)
        .list();
     
    这个查询可以通过外连接抓取mate和kittens。
     
    6. 查询示例
    org.hibernate.criterion.Example类允许你通过一个给定实例 构建一个条件查询。
     
    Cat cat = new Cat();
    cat.setSex('F');
    cat.setColor(Color.BLACK);
    List results = session.createCriteria(Cat.class)
        .add( Example.create(cat) )
        .list();



    版本属性、标识符和关联被忽略。默认情况下值为null的属性将被排除。
    可以自行调整Example使之更实用。
     
    Example example = Example.create(cat)
        .excludeZeroes()           //exclude zero valued properties
        .excludeProperty("color")  //exclude the property named "color"
        .ignoreCase()              //perform case insensitive string comparisons
        .enableLike();             //use like for string comparisons
    List results = session.createCriteria(Cat.class)
        .add(example)
        .list();



    甚至可以使用examples在关联对象上放置条件。
     
    List results = session.createCriteria(Cat.class)
        .add( Example.create(cat) )
        .createCriteria("mate")
            .add( Example.create( cat.getMate() ) )
        .list();



    7. 投影(Projections)、聚合(aggregation)和分组(grouping)
    org.hibernate.criterion.Projections是 Projection 的实例工厂。我们通过调用


    setProjection()应用投影到一个查询。
     
    List results = session.createCriteria(Cat.class)
        .setProjection( Projections.rowCount() )
        .add( Restrictions.eq("color", Color.BLACK) )
        .list();
     
    List results = session.createCriteria(Cat.class)
        .setProjection( Projections.projectionList()
            .add( Projections.rowCount() )
            .add( Projections.avg("weight") )
            .add( Projections.max("weight") )
            .add( Projections.groupProperty("color") )
        )
        .list();

    


    在一个条件查询中没有必要显式的使用 "group by" 。某些投影类型就是被定义为 分组投影,他


    们也出现在SQL的group by子句中。

    可以选择把一个别名指派给一个投影,这样可以使投影值被约束或排序所引用。下面是两种不同的

    实现方式:
     
    List results = session.createCriteria(Cat.class)
        .setProjection( Projections.alias( Projections.groupProperty("color"), "colr" ) )
        .addOrder( Order.asc("colr") )
        .list();


    

    List results = session.createCriteria(Cat.class)
        .setProjection( Projections.groupProperty("color").as("colr") )
        .addOrder( Order.asc("colr") )
        .list();
     
    alias()和as()方法简便的将一个投影实例包装到另外一个 别名的Projection实例中。简而言之,


    当你添加一个投影到一个投影列表中时你可以为它指定一个别名:
     
    List results = session.createCriteria(Cat.class)
        .setProjection( Projections.projectionList()
            .add( Projections.rowCount(), "catCountByColor" )
            .add( Projections.avg("weight"), "avgWeight" )
            .add( Projections.max("weight"), "maxWeight" )
            .add( Projections.groupProperty("color"), "color" )
        )
        .addOrder( Order.desc("catCountByColor") )
        .addOrder( Order.desc("avgWeight") )
        .list();



    List results = session.createCriteria(Domestic.class, "cat")
        .createAlias("kittens", "kit")
        .setProjection( Projections.projectionList()
            .add( Projections.property("cat.name"), "catName" )
            .add( Projections.property("kit.name"), "kitName" )
        )
        .addOrder( Order.asc("catName") )
        .addOrder( Order.asc("kitName") )
        .list();



    也可以使用Property.forName()来表示投影:
     
    List results = session.createCriteria(Cat.class)
        .setProjection( Property.forName("name") )
        .add( Property.forName("color").eq(Color.BLACK) )
        .list();

    List results = session.createCriteria(Cat.class)
        .setProjection( Projections.projectionList()
            .add( Projections.rowCount().as("catCountByColor") )
            .add( Property.forName("weight").avg().as("avgWeight") )
            .add( Property.forName("weight").max().as("maxWeight") )
            .add( Property.forName("color").group().as("color" )
        )
        .addOrder( Order.desc("catCountByColor") )
        .addOrder( Order.desc("avgWeight") )
        .list();



    8. 离线(detached)查询和子查询
    DetachedCriteria类使你在一个session范围之外创建一个查询,并且可以使用任意的 Session来


    执行它。
     
    DetachedCriteria query = DetachedCriteria.forClass(Cat.class)
        .add( Property.forName("sex").eq('F') );
    //创建一个Session
    Session session = .;
    Transaction txn = session.beginTransaction();
    List results = query.getExecutableCriteria(session).setMaxResults(100).list();
    txn.commit();
    session.close();



    DetachedCriteria也可以用以表示子查询。条件实例包含子查询可以通过 Subqueries或者

    Property获得。
     
    DetachedCriteria avgWeight = DetachedCriteria.forClass(Cat.class)
        .setProjection( Property.forName("weight").avg() );
    session.createCriteria(Cat.class)
        .add( Property.forName("weight).gt(avgWeight) )
        .list();

    DetachedCriteria weights = DetachedCriteria.forClass(Cat.class)
        .setProjection( Property.forName("weight") );
    session.createCriteria(Cat.class)
        .add( Subqueries.geAll("weight", weights) )
        .list();


    相互关联的子查询也是有可能的:
     
    DetachedCriteria avgWeightForSex = DetachedCriteria.forClass(Cat.class, "cat2")
        .setProjection( Property.forName("weight").avg() )
        .add( Property.forName("cat2.sex").eqProperty("cat.sex") );
    session.createCriteria(Cat.class, "cat")
        .add( Property.forName("weight).gt(avgWeightForSex) )
        .list();

    来源:(http://blog.sina.com.cn/s/blog_5c0522dd0100e7hz.html) - Hibernate中Criteria的完整用法_joeytang9118_新浪博客
    Oct 12
    这个乱码问题是最简单的乱码问题。一般新会出现。就是页面编码不一致导致的乱码。
    <%@ page language="java" pageEncoding="UTF-8"%>
    <%@ page contentType="text/html;charset=iso8859-1"%>
    <html>
    <head>
    <title>中文问题</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    </head>
    </head>
    <body>
    我是个好人
    </body>
    </html>
    三个地方的编码。
    第一个地方的编码格式为jsp文件的存储格式。Ecljpse会根据这个编码格式保存文件。并编译jsp文件,包括里面的汉字。
    第 二处编码为解码格式。因为存为UTF-8的文件被解码为iso8859-1,这样 如有中文肯定出乱码。也就是必须一致。而第二处所在的这一行,可以没有。缺省也是使用iso8859-1的编码格式。所以如果没有这一行的话,“我是个好 人”也会出现乱码。必须一致才可以。
    第三处编码为控制浏览器的解码方式。如果前面的解码都一致并且无误的话,这个编码格式没有关系。有的网页出现乱码,就是因为浏览器不能确定使用哪种编码格式。因为页面有时候会嵌入页面,导致浏览器混淆了编码格式。出现了乱码。


    2, 表单使用Post方式提交后接收到的乱码问题
    这 个问题也是一个常见的问题。这个乱码也是tomcat的内部编码格式iso8859-1在捣乱,也就是说post提交时,如果没有设置提交的编码格式,则 会以iso8859-1方式进行提交,接受的jsp却以utf-8的方式接受。导致乱码。既然这样的原因,下面有几种解决方式,并比较。
    A,      接受参数时进行编码转换
    String str = new String(request.getParameter("something").getBytes("ISO-8859-1"),"utf-8") ; 这样的话,每一个参数都必须这样进行转码。很麻烦。但确实可以拿到汉字。
    B,       在请求页面上开始处,执行请求的编码代码, request.setCharacterEncoding("UTF-8"),把提交内容的字符集设为UTF-8。这样的话,接受此参数的页面就不必在转码了。直接使用
    String str = request.getParameter("something");即可得到汉字参数。但每页都需要执行这句话。这个方法也就对post提交的有效 果,对于get提交和上传文件时的enctype="multipart/form-data"是无效的。稍后下面单独对这个两个的乱码情况再进行说明。
    C, 为了避免每页都要写request.setCharacterEncoding("UTF-8"),建议使用过滤器对所有jsp
    进行编码处理。这个网上有很多例子。请大家自己查阅。
    Tags: , ,
    分页: 3/6 第一页 上页 1 2 3 4 5 6 下页 最后页 [ 显示模式: 摘要 | 列表 ]