Struts2 doubleselect标签中select框缺省selected实现

    在项目中,省市下拉框联动采用的是Struts2的doubleselect标签,需要根据业务需求实现两个下拉框动态的缺省值(selected)。

业务场景:

    在代理商管理中,增加代理商时候选择代理商所属的省市,然后增加代理商的销售人员,但代理商销售人员销售产品,如果客户在客户库中没有相关信息,需要增加客户,此时侯应当缺省根据代理商所属的省市信息,在增加客户时候,客户所在省市的缺省selected的值应当为代理商所在的省市信息。

 

主要实现逻辑如下:

    采用doubleselect标签的value和doublevalue属性,在action中定义两个select框缺省值参数(例子中是defaultItem、doubleDefaultItem)的get、set方法,在action方法中根据业务逻辑(在增加客户时候,客户所在省市缺省为销售员所在省市)调用set方法设定两个select框的缺省值,然后在页面通过value和doublevalue方法获取设定的缺省值。

实现样例如下:

1. Action

package com.mobilesoft.esales.webapp.action;

import java.util.ArrayList;

import java.util.HashMap;

import java.util.Map;

import org.apache.log4j.Logger;

public class DoubleListAction extends BaseAction {

private static final Logger logger = Logger.getLogger(DoubleListAction.class);

private String defaultItem;

private String doubleDefaultItem;

public String execute() {

return SUCCESS;

    }

public String doubleSelectTest(){

       Map map=new HashMap();

       ArrayList list1=new ArrayList();

       list1.add(”11″);

       list1.add(”12″);

       list1.add(”13″);

       map.put(”1″, list1);

       ArrayList list2=new ArrayList();

       list2.add(”21″);

       list2.add(”22″);

       list2.add(”23″);

       map.put(”2″, list2);

       ArrayList list3=new ArrayList();

       list3.add(”31″);

       list3.add(”32″);

       list3.add(”33″);

       map.put(”3″, list3);

       setDefaultItem(”2″);

       setDoubleDefaultItem(”23″);

       getRequest().setAttribute(”defaultItem”, getDefaultItem());

       getRequest().setAttribute(”doubleDefaultItem”, getDoubleDefaultItem());

       getRequest().setAttribute(”map”, map);

return SUCCESS;

    }

public String getDefaultItem() {

return defaultItem;

    }

public void setDefaultItem(String defaultItem) {

this.defaultItem = defaultItem;

    }

public String getDoubleDefaultItem() {

return doubleDefaultItem;

    }

public void setDoubleDefaultItem(String doubleDefaultItem) {

this.doubleDefaultItem = doubleDefaultItem;

    }

}

2. doubleselect.jsp

<%@ taglib prefix=”s” uri=”/struts-tags” %>

<%@ page language=”java” errorPage=”/error.jsp” pageEncoding=”GBK” contentType=”text/html;charset=GBK” %>

<html>

<head>

<title>Struts 2 Cool Tags - &lt;s:doubeselect/ &gt;</title>

<s:head />

</head>

<body>

<h2>Doubleselect 缺省值selected使用数据演示:</h2>

<s:form name=”form1″>

<s:doubleselect label=”缺省值测试”

    list=”#request.map.keySet()”        doubleList=”#request.map[top]”

name=”doubleselect1″                doubleName=”doubleselect2″

value=”#request.defaultItem”       doubleValue=”#request.doubleDefaultItem”

    formName=”form1″

/>

</s:form>

</body>

</html>

3. struts.xml

<action name=”doubleSelectTest” method=”doubleSelectTest” class=”com.mobilesoft.esales.webapp.action.DoubleListAction”>

<result name=”success”>test/doubleselect.jsp</result>

</action>

 

Technorati 标签: ,,,

在jmesa中使用hsql支持复杂的hsql查询

在目前的框架中,使用的是Hibernate Criteria来实现复杂的分页、排序、过滤等操作,基本上能够完成大部分复杂的查询分页、排序处理,但对于统计分析这样的复杂查询,Criteria实现还是有点力不从心,比较麻烦,尤其是在多表查询的情况下。

由于对于整型字段在目前在列表的输入框中输入过滤条件,会由于HttpServletRequest为String类型,而Hibernate为整型字段,导致对于在数据库中非String类型的字段过滤报错,因此暂时去除对过滤的支持功能,后续有空再研究解决方案,方法如下:

       HtmlRow row = table.getRow();

       row.setFilterable(false);

这样处理后,意味着我们在jmesa中实际上只需要处理分页、排序操作(导出为txt、excel、pdf等与此关系不大),因此对jmesa增加对hsql语句查询的支持,而不采用Criteria的方式,方法如下:

1. 对排序类HibernateSort

package com.mobilesoft.esales.dao.hibernate;

import java.util.ArrayList;

import java.util.List;

import org.hibernate.Criteria;

import org.hibernate.criterion.Order;

public class HibernateSort implements CriteriaCommand {

    List<Sort> sorts = new ArrayList<Sort>();

    public void addSort(String property, String order) {

        sorts.add(new Sort(property, order));

    }

    public Criteria execute(Criteria criteria) {

        for (Sort sort : sorts) {

            buildCriteria(criteria, sort.getProperty(), sort.getOrder());

        }

        return criteria;

    }

    public List getSortList(){

        return this.sorts;

    }

    private void buildCriteria(Criteria criteria, String property, String order) {

        if (order.equals(Sort.ASC)) {

            criteria.addOrder(Order.asc(property));

        } else if (order.equals(Sort.DESC)) {

            criteria.addOrder(Order.desc(property));

        }

    }

    public static class Sort {

        public final static String ASC = “asc”;

        public final static String DESC = “desc”;

        private final String property;

        private final String order;

        public Sort(String property, String order) {

            this.property = property;

            this.order = order;

        }

        public String getProperty() {

            return property;

        }

        public String getOrder() {

            return order;

        }

    }

}

2. 对DAO类PersonDAO

增加getPersonWithFilterAndSort2和getPersonCountWithFilter2:

public int getPersonCountWithFilter(final HibernateFilter filter) {

        Integer count = (Integer) getHibernateTemplate().execute(new HibernateCallback() {

public Object doInHibernate(Session session)

throws HibernateException, SQLException {

                Criteria criteria = session.createCriteria(Person.class);

                criteria = filter.execute(criteria);

                criteria.setProjection(Projections.rowCount()).uniqueResult();

return criteria.uniqueResult();

            }

        });

return count.intValue();

    }

public int getPersonCountWithFilter2(final HibernateFilter filter) {

        Long count = (Long) getHibernateTemplate().execute(new HibernateCallback() {

public Object doInHibernate(Session session)

throws HibernateException, SQLException {

              StringBuffer querySql=new StringBuffer(”select count(person) from Person as person “);

                  Query query  =  session.createQuery(querySql.toString());

                List list  =  query.list();

return list.get(0);

            }

        });

return count.intValue();

    }

public List<Person> getPersonWithFilterAndSort(final HibernateFilter filter, final HibernateSort sort, final int rowStart, final int rowEnd) {

        List applications = (List) getHibernateTemplate().execute(new HibernateCallback() {

public Object doInHibernate(Session session)

throws HibernateException, SQLException {

                Criteria criteria = session.createCriteria(Person.class);

                criteria = filter.execute(criteria);

                criteria = sort.execute(criteria);

                criteria.setFirstResult(rowStart);

                criteria.setMaxResults(rowEnd - rowStart);

return criteria.list();

            }

        });

return applications;

    }   

public List<Person> getPersonWithFilterAndSort2(final HibernateFilter filter, final HibernateSort sort, final int rowStart, final int rowEnd) {

            List applications = (List) getHibernateTemplate().execute(new HibernateCallback() {

public Object doInHibernate(Session session)

throws HibernateException, SQLException {

                  List sorts =sort.getSortList();

                  Iterator iterator=sorts.iterator();

                  StringBuffer sortSql=new StringBuffer(” “);

int i=1;

while(iterator.hasNext()){

                      HibernateSort.Sort field=(HibernateSort.Sort)iterator.next();

                      String property=field.getProperty();

                      String order=field.getOrder();

if(i>1)

                         sortSql.append(” , “);

else

                         sortSql.append(” order by “);

                      sortSql.append(property);

                      sortSql.append(” “);

                      sortSql.append(order);

                      i++;

                  }

                  StringBuffer querySql=new StringBuffer(”select person from Person as person “);

                  querySql.append(sortSql);

                  Query query  =  session.createQuery(querySql.toString());

logger.fatal(”$HibernateCallback.doInHibernate(Session) “+querySql.toString()); //$NON-NLS-1$

                    query.setFirstResult(rowStart);                   

                    query.setMaxResults(rowEnd-rowStart);

                    List list  =  query.list();

return  list;

                }

            });

return applications;

    }

3. PersonService及PersonServiceImpl

在PersonService中增加接口声明

public int getPersonCountWithFilter2(HibernateFilter filter);

public Collection<Person> getPersonWithFilterAndSort2(HibernateFilter filter, HibernateSort sort, int rowStart, int rowEnd);

在PersonServiceImpl增加实现:

public int getPersonCountWithFilter2(HibernateFilter filter) {

return personDAO.getPersonCountWithFilter2(filter);

    }

public Collection<Person> getPersonWithFilterAndSort2(HibernateFilter filter, HibernateSort sort, int rowStart, int rowEnd) {

return personDAO.getPersonWithFilterAndSort2(filter, sort, rowStart, rowEnd);


4. PersonAction

将获取数据修改为调用getPersonWithFilterAndSort2,获取总数修改为getPersonCountWithFilter2

if (!limit.isComplete()) {

// deal with Criteria

//int totalRows = personService.getPersonCountWithFilter(hibernateFilter);

// deal with hsql

int totalRows = personService.getPersonCountWithFilter2(hibernateFilter);

            tableFacade.setTotalRows(totalRows);

        }

        HibernateSort hibernateSort = getHibernateSort(limit);

int rowStart = limit.getRowSelect().getRowStart();

int rowEnd = limit.getRowSelect().getRowEnd();

// deal with Criteria

//Collection<Person> items = personService.getPersonWithFilterAndSort(hibernateFilter, hibernateSort, rowStart, rowEnd);

// deal with hsql

        Collection<Person> items = personService.getPersonWithFilterAndSort2(hibernateFilter, hibernateSort, rowStart, rowEnd);

        tableFacade.setItems(items); // Do not forget to set the items back on the tableFacade.

 

5、参考

http://code.google.com/p/jmesa/wiki/LimitExample

 

用UrlRewriteFilter实现不同WebContext间的url rewrite

    在新平台中,由于需要保持与原有CP、SP的接口的不变(目前的接口都为基于http协议的),例如原来与CP的接口为:

http://www.yeeach.com/platform/retail.do?act=verifyIp。

为了保证系统平滑的迁移,老的平台需要保留一段时间,新的平台需要以新的Webcontext方式进行部署,例如新的应用的web路径为:

http://www.yeeach.com/platformnew,与cp的接口假定新平台的处理接口为http://www.yeeach.com/platformnew/ retail.action?act=verifyIp,也即需要进行如下的迁移处理:

http://www.yeeach.com/platform/retail.do?act=verifyIp        –>         http://www.yeeach.com/platformnew/retail.action?act=verifyIp

    此种情况下与为了搜索引擎优化而进行的URL优化(也即现在流行的所谓的REST)将

http://www.yeeach.com/platform/retail.do/act/verifyIP –> http://www.yeeach.com/platform/retail.do?act=verifyIp

的场景并不相同

    同时由于跨了不同的Web Context,因此采用strtus2的struts.action.extension=action,do来实现action不同后缀的方式也行不通。

    可行的解决方案有两种:

1、  利用前端的apache或lighttpd的mod_rewrite来实现

2、  利用java开源项目UrlRewriteFilter http://tuckey.org/urlrewrite/来实现类似mod_rewrite的功能

    由于目前尚未有太多的静态页面内容,因此尚未部署apache或lighttpd(做门户时候再基于架设lighttpd),同时考虑到相对独立性,因此先采用纯java的UrlRewriteFilter解决方案来实现,简单描述一下实现方法:

1、  下载及安装UrlRewriteFilter

http://urlrewritefilter.googlecode.com/files/urlrewritefilter-3.1.0.zip 下载 UrlRewriteFilter 3.1.0版本

2、将urlrewrite-3.1.0.jar部署到旧的platform/WEB-INF/lib下

3、修改web.xml,增加如下内容

        <filter>

            <filter-name>UrlRewriteFilter</filter-name>

            <filter-class>org.tuckey.web.filters.urlrewrite.UrlRewriteFilter</filter-class>

            <init-param>

                <param-name>logLevel</param-name>

                <param-value>WARN</param-value>

            </init-param>

        </filter>

        <filter-mapping>

            <filter-name>UrlRewriteFilter</filter-name>

            <url-pattern>/*</url-pattern>

        </filter-mapping>

4、在旧的webapp platform中部署urlrewrite.xml到WEB-INF/下,内容如下

<?xml version=”1.0″ encoding=”utf-8″?>

<!DOCTYPE urlrewrite PUBLIC “-//tuckey.org//DTD UrlRewrite 3.1//EN”

        “http://tuckey.org/res/dtds/urlrewrite3.1.dtd”>

<urlrewrite use-query-string=”true”>

    <rule>

        <from>^/retail.do\?act=(.*)$</from>

        <to type=”forward”>/platformnew/retail.action?act=$1</to>

    </rule>

</urlrewrite>

注意事项:

1)、实例的请求形式为:

http://www.yeeach.com/platform/retail.do?act=verifyIp         –>         http://www.yeeach.com/platformnew/retail.action?act=verifyIp

2)、对于to type可以为redirect、forward等,由于forward不能跨不同context之间,因此只能采用redirect方式。对于在统一Webcontext请求可以采用forward方式

3)、from和to都支持类似于apache mod_rewrite正则表达式用法,具体参看文档

4)、对于urlrewritefilter 3.x版本,对于诸如/retail.action?act=verifyIp这样的参数字符串,缺省情况下urlrewritefilter并不处理,由参数use-query-string决定,缺省为false。需要显性设置为true:<urlrewrite use-query-string=”true”>

摘自:http://urlrewritefilter.googlecode.com/svn/trunk/src/doc/manual/3.1/index.html

use-query-string    (optional) 

  false (default)       The query string will not be appended to the url that the “from” element matches against.

  true                     The query string will be appended to the url that the “from” element matches against.

 

5)、一定要注意在from 的查询url中的?需要进行转义处理:\?,不然会报错。因为?字符在正则表达式是0或1多个字符。to中不需要转义

6)、对url中&字符在xml文件中,用:&amp;

 

Hibernate Criteria使用实例

在使用jmesa作为组件来实现分页、导入、排序、过滤组件时候,对paging、sort、filter的处理,使用的是Hibernate的Criteria函数,对于单表使用Criteria方法相对容易,但对于多表操作,手册上没有现成的样例可以借鉴。总结一下Criteria的一些用法,以方便在对多表数据复杂操作时候也能够使用jmesa,简化分页、导出等日常操作。

1、目前使用Criteria用于取总数及排序过滤的用法例子

public int getPersonCountWithFilter(final HibernateFilter filter) {

Integer count = (Integer) getHibernateTemplate().execute(new HibernateCallback() {

public Object doInHibernate(Session session)

throws HibernateException, SQLException {

Criteria criteria = session.createCriteria(Person.class);

criteria.add(Expression.eq(”id”,27));

criteria = filter.execute(criteria);

criteria.setProjection(Projections.rowCount()).uniqueResult();

return criteria.uniqueResult();

}

});

return count.intValue();

}

public List<Person> getPersonWithFilterAndSort(final HibernateFilter filter, final HibernateSort sort, final int rowStart, final int rowEnd) {

List applications = (List) getHibernateTemplate().execute(new HibernateCallback() {

public Object doInHibernate(Session session)

throws HibernateException, SQLException {

Criteria criteria = session.createCriteria(Person.class);

criteria = filter.execute(criteria);

criteria = sort.execute(criteria);

criteria.setFirstResult(rowStart);

criteria.setMaxResults(rowEnd - rowStart);

return criteria.list();

}

});

return applications;

}

2、数据库表结构,以sys_user和sys_user_role为例子

CREATE TABLE `sys_user_role` (

`user_id` int(11) NOT NULL,

`role_id` int(11) NOT NULL,

`user_name` varchar(100) default NULL,

`role_name` varchar(100) default NULL,

PRIMARY KEY (`role_id`,`user_id`)

) ;

INSERT INTO `sys_user_role` VALUES (’1′, ‘1′, ‘liang1′, ‘admin1′);

INSERT INTO `sys_user_role` VALUES (’2′, ‘2′, ‘liang2′, ‘admin2′);

INSERT INTO `sys_user_role` VALUES (’3′, ‘3′, ‘liang3′, ‘admin3′);

INSERT INTO `sys_user_role` VALUES (’4′, ‘4′, ‘liang4′, ‘admin4′);

INSERT INTO `sys_user_role` VALUES (’5′, ‘5′, ‘liang5′, ‘anonymous’);

INSERT INTO `sys_user_role` VALUES (’1′, ‘5′, ‘liang1′, ‘admin5′);

CREATE TABLE `sys_user` (

`user_id` int(11) NOT NULL,

`mobile` varchar(15) default NULL,

`imei` varchar(20) default NULL,

`user_name` varchar(100) NOT NULL,

`password` varchar(50) default NULL,

`user_type` varchar(40) default ‘normal’ ,

`login_type` varchar(20) default NULL,

`customer_id` int(11) default NULL,

`customer_name` varchar(200) default NULL,

`root_company_id` int(11) default NULL,

`root_company_name` varchar(255) default NULL,

`compayn_id` int(11) default NULL,

`company_name` varchar(255) default NULL,

`email` varchar(100) default NULL,

`email2` varchar(100) default NULL,

`nickname` varchar(100) default NULL,

`sex` varchar(10) default NULL ,

`status` varchar(50) default NULL,

`credit_amount` decimal(10,2) default NULL,

`credit_rank` varchar(20) default NULL,

`money` decimal(10,2) default NULL,

`integral` decimal(10,2) default ‘0.00′,

`website` varchar(200) default NULL,

`pwd_modify_date` datetime default NULL,

`pwd_duration` varchar(10) default NULL,

`signature` text,

`twitter` varchar(255) default NULL,

`qq` varchar(20) default NULL,

`msn` varchar(50) default NULL,

`icq` varchar(50) default NULL,

`yahoo` varchar(30) default NULL,

`gtalk` varchar(30) default NULL,

`blog` varchar(255) default NULL,

`interest` text,

`safe_question` varchar(100) default NULL,

`safe_answer` varchar(100) default NULL,

`safe_question2` varchar(100) default NULL,

`safe_answer2` varchar(100) default NULL,

`safe_question3` varchar(100) default NULL,

`safe_answer3` varchar(100) default NULL,

`icon` varchar(100) default NULL,

`icon2` varchar(100) default NULL,

`icon3` varchar(100) default NULL,

`is_test` tinyint(1) default NULL ,

`is_admin` tinyint(1) default NULL,

`fax` varchar(20) default NULL,

`home_phone` varchar(50) default NULL,

`office_phone` varchar(20) default NULL,

`birthday` char(19) default NULL,

`vocation` varchar(20) default NULL,

`education` varchar(50) default NULL,

`address` varchar(255) default NULL,

`postcode` varchar(20) default NULL,

`description` text,

`creator` varchar(40) default NULL,

`begin_date` datetime default NULL,

`end_date` datetime default NULL,

`create_date` datetime default NULL,

`modify_user` varchar(40) default NULL,

`modify_date` datetime default NULL,

`last_login_type` varchar(20) default NULL,

`last_login_id` varchar(20) default NULL,

`last_login_date` datetime default NULL,

PRIMARY KEY (`user_id`)

) ;

INSERT INTO `sys_user` VALUES (’1′, ‘13911111111′, null, ‘liang1′, ‘liang1′, ‘normal’, null, null, ‘liang1′, null, null, null, null, null, null, null, null, null, null, null, null, ‘0.00′, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null);

INSERT INTO `sys_user` VALUES (’2′, ‘13922222222′, null, ‘liang2′, ‘liang2′, ‘normal’, null, null, ‘liang2′, null, null, null, null, null, null, null, null, null, null, null, null, ‘0.00′, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null);

INSERT INTO `sys_user` VALUES (’3′, ‘13933333333′, null, ‘liang3′, ‘liang3′, ‘normal’, null, null, ‘liang3′, null, null, null, null, null, null, null, null, null, null, null, null, ‘0.00′, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null);

INSERT INTO `sys_user` VALUES (’4′, ‘13944444444′, null, ‘liang4′, ‘liang4′, ‘normal’, null, null, ‘liang4′, null, null, null, ‘li’, null, null, null, null, null, null, null, null, ‘0.00′, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null);

INSERT INTO `sys_user` VALUES (’5′, ‘13955555555′, null, ‘liang5′, ‘liang5′, ‘normal’, null, null, ‘liang5′, null, null, null, null, null, null, null, null, null, null, null, null, ‘0.00′, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null);

3、hbm映射文件

注意:

由于在目前的数据模型及程序中并没有使用数据库的外键约束,直接通过程序来控制外键约束关系。因此在所有的hbm中并没有使用hibernate 的one-to-many关联。要使用Criteria实现多表较为复杂的操作,需要加上one-to-many映射。但这与目前的程序实现存在冲突,解决方法如下:

由于目前使用Criteria只用于查询及统计分析部分,可以单独建立一个映射文件及映射类,用于查询及统计分析操作,例如对于SysUser表,可以建立一个SysUser-jmesa.hbm.xml,对此映射文件,将<class name=”com.mobilesoft.esales.model.SysUser” table=”sys_user” catalog=”mysql”>修改为:

<class name=”com.mobilesoft.esales.model.SysUserJmesa” table=”sys_user” >

one-to-many:

<set name=”userRoles” table=”sys_user_role” >

<key column=”role_id” />

<one-to-many class=”com.mobilesoft.esales.model.SysUserRole” />

</set>

由于只是演示,简单起见,直接用的是原有的映射文件及映射类。

3.1、SysUser.hbm.xml

<?xml version=”1.0″ encoding=”utf-8″?>

<!DOCTYPE hibernate-mapping PUBLIC “-//Hibernate/Hibernate Mapping DTD 3.0//EN”

“http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd”>

<hibernate-mapping>

<class name=”com.mobilesoft.esales.model.SysUser” table=”sys_user” catalog=”mysql”>

<id name=”userId” type=”java.lang.Integer”>

<column name=”user_id” />

<generator class=”native” />

</id>

<property name=”mobile” type=”java.lang.String”>

<column name=”mobile” length=”15″ />

</property>

<!—

省略掉其他内容

–>

<set name=”userRoles” table=”sys_user_role” >

<key column=”user_id” />

<one-to-many class=”com.mobilesoft.esales.model.SysUserRole” />

</set>

</class>

</hibernate-mapping>

3.2、SysUserRole.hbm.xml

<?xml version=”1.0″ encoding=”utf-8″?>

<!DOCTYPE hibernate-mapping PUBLIC “-//Hibernate/Hibernate Mapping DTD 3.0//EN”

“http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd”>

<!–

Mapping file autogenerated by MyEclipse Persistence Tools

–>

<hibernate-mapping>

<class name=”com.mobilesoft.esales.model.SysUserRole” table=”sys_user_role” catalog=”mysql”>

<composite-id name=”id” class=”com.mobilesoft.esales.model.SysUserRoleId”>

<key-property name=”roleId” type=”java.lang.Integer”>

<column name=”role_id” />

</key-property>

<key-property name=”userId” type=”java.lang.Integer”>

<column name=”user_id” />

</key-property>

</composite-id>

<property name=”userName” type=”java.lang.String”>

<column name=”user_name” length=”100″ />

</property>

<property name=”roleName” type=”java.lang.String”>

<column name=”role_name” length=”100″ />

</property>

</class>

</hibernate-mapping>

4、测试用例

import java.util.Iterator;

import java.util.List;

import junit.framework.TestCase;

import org.apache.log4j.Logger;

import org.hibernate.FetchMode;

import org.hibernate.criterion.Projections;

import org.hibernate.criterion.Restrictions;

import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.mobilesoft.esales.dao.hibernate.SysUserDAO;

import com.mobilesoft.esales.model.SysUser;

import com.mobilesoft.esales.model.SysUserRole;

/**

* Hibernate Criteria用法测试用例

*

* @author liangchuan@mobile-soft.cn

*

*/

public class TestCriteria extends TestCase {

private static final Logger logger = Logger.getLogger(TestCriteria.class);

private static ClassPathXmlApplicationContext context = null;

private static SysUserDAO dao;

static {

context = new ClassPathXmlApplicationContext(new String[] {

“applicationContext.xml”, “applicationContext-resources.xml”,

“applicationContext-dao.xml”, “applicationContext-service.xml” });

}

protected void setUp() throws Exception {

}

/**

* 演示使用Criteria实现:select userId from SysUser as user

*/

public void testSelectId() {

dao = (SysUserDAO) context.getBean(”SysUserDAO”);

List mylist=dao.getHibernateTemplate().getSessionFactory().openSession().createCriteria(SysUser.class)

.setProjection(

Projections.projectionList().add(

Projections.property(”userId”)

)

).list();

Iterator iterator=mylist.iterator();

while(iterator.hasNext()){

logger.fatal(”id is :”+iterator.next());

}

}

/**

* 演示使用Criteria实现:select user.*,userRole.* from SysUser as user ,SysUserRole userRole where user.userId=userRole.id

*/

public void testJoin1() {

dao = (SysUserDAO) context.getBean(”SysUserDAO”);

List mylist=dao.getHibernateTemplate().getSessionFactory().openSession().createCriteria(SysUser.class)

.setFetchMode(”userRoles”,FetchMode.JOIN).list();

Iterator iterator=mylist.iterator();

while(iterator.hasNext()){

SysUser user=(SysUser)iterator.next();

logger.fatal(”testJoin1:userid is :”+user.getUserId()+” userName is “+user.getUserName());

}

}

/**

* 演示使用Criteria实现:select user.* ,userRole.* from SysUser as user ,SysUserRole userRole

* where user.userId=userRole.id and user.userId=1

*/

public void testJoin2() {

dao = (SysUserDAO) context.getBean(”SysUserDAO”);

List mylist=dao.getHibernateTemplate().getSessionFactory().openSession().createCriteria(SysUser.class)

.setFetchMode(”userRoles”,FetchMode.JOIN)

.add(Restrictions.eq(”userId”,1))

.list();

Iterator iterator=mylist.iterator();

while(iterator.hasNext()){

SysUser user=(SysUser)iterator.next();

logger.fatal(”testJoin2:userid is :”+user.getUserId()+” userName is “+user.getUserName());

}

}

/**

* 演示使用Criteria实现:select user.* ,userRole.* from SysUser as user ,SysUserRole userRole

* where user.userId=userRole.id and userRole.id.roleId=2

* 演示createAlias的使用

*/

public void testJoin3() {

dao = (SysUserDAO) context.getBean(”SysUserDAO”);

List mylist=dao.getHibernateTemplate().getSessionFactory().openSession().createCriteria(SysUser.class)

.setFetchMode(”userRoles”,FetchMode.JOIN)

.createAlias(”userRoles”, “b”)

.add(Restrictions.eq(”b.id.roleId”,2))

.list();

Iterator iterator=mylist.iterator();

while(iterator.hasNext()){

SysUser user=(SysUser)iterator.next();

logger.fatal(”testJoin3:userid is :”+user.getUserId()+” userName is “+user.getUserName());

}

}

/**

* 演示使用Criteria实现:select count(userId) from SysUser as user ,SysUserRole userRole

* where user.userId=userRole.id

* 同时演示createAlias的使用

*/

public void testJoin4() {

dao = (SysUserDAO) context.getBean(”SysUserDAO”);

List mylist=dao.getHibernateTemplate().getSessionFactory().openSession().createCriteria(SysUser.class)

.setFetchMode(”userRoles”,FetchMode.JOIN)

.setProjection( Projections.projectionList().add( Projections.count(”userId”) ))

.list();

Iterator iterator=mylist.iterator();

while(iterator.hasNext()){

logger.fatal(”testJoin4:count(userId) is :”+iterator.next());

}

}

/**

* 演示使用Criteria实现:select count(id.roleId) from SysUserRole userRole

* 同时演示createAlias的使用

*/

public void testJoin5() {

dao = (SysUserDAO) context.getBean(”SysUserDAO”);

List mylist=dao.getHibernateTemplate().getSessionFactory().openSession().createCriteria(SysUserRole.class)

.setProjection( Projections.projectionList().add( Projections.count(”id.roleId”) ))

.list();

Iterator iterator=mylist.iterator();

while(iterator.hasNext()){

logger.fatal(”testJoin5:count(roleId) is :”+iterator.next());

}

}

}

5、Model

5.1、SysUser.java

没有什么特别的,直接用myeclipse生成,然后在SysUser中添加上:

private java.util.Set userRoles = new HashSet();

public java.util.Set getUserRoles() {

return userRoles;

}

public void setUserRoles(java.util.Set userRoles) {

this.userRoles = userRoles;

}

5.2、SysUserRole.java

package com.mobilesoft.esales.model;

/**

* SysUserRole entity.

*

* @author MyEclipse Persistence Tools

*/

public class SysUserRole implements java.io.Serializable {

// Fields

private SysUserRoleId id;

private String userName;

private String roleName;

// Constructors

/** default constructor */

public SysUserRole() {

}

/** minimal constructor */

public SysUserRole(SysUserRoleId id) {

this.id = id;

}

/** full constructor */

public SysUserRole(SysUserRoleId id, String userName, String roleName) {

this.id = id;

this.userName = userName;

this.roleName = roleName;

}

// Property accessors

public SysUserRoleId getId() {

return this.id;

}

public void setId(SysUserRoleId id) {

this.id = id;

}

public String getUserName() {

return this.userName;

}

public void setUserName(String userName) {

this.userName = userName;

}

public String getRoleName() {

return this.roleName;

}

public void setRoleName(String roleName) {

this.roleName = roleName;

}

}

6、参考文档

http://www.devarticles.com/c/a/Java/Hibernate-Criteria-Queries-in-Depth/

http://www.devx.com/Java/Article/28754/1954

 

Technorati 标签: ,,,

Why most large-scale web sites not written in Java

Gigaspaces公司的大牛Nati Shalom及其同事Geva Perry 的关于在web2.0时代,java在高性能、大容量、高负荷的互联网应用领域所扮演的角色进行了较为理智和深入的思考,在TheServerSideArtima上也引起了激烈的讨论。由于Nati ShalomGeva Perry  ,都算得上Java的大牛,其所在公司Gigaspaces开发的产品GigaSpaces eXtreme Application Platform (XAP)也是基于Java的高性能平台,因此其观点算得上对Java在互联网时代的定位的反思,相比较而言国内的“我该学习Java还是学习.Net之类的讨论”层次明显得不一样。

讨论的一些相关内容:

Why most large-scale web sites not written in Java

Why most large-scale Web sites are not written in Java [Personal View]

Large-Scale Web Sites and Java

y1po13h7kl8WSSz36U09lQcrdOfz0gLB0jbAlnLlGMewxrqDFf58IZEUmqLCtbQ5qQzwL73puADD3c

一些Web2.0应用杰出代表的系统架构

我比较赞同Geva Perry Large-Scale Web Sites and Java的观点:

my intuition is that the trend for Web apps that are coming from start-ups or large pure web players (as opposed to web apps from airlines, banks, etc.) is definitely towards the LAMP stack. However, Java will still remain strong for a while and  especially for Web apps that have to deal with more complex processes in the back-end.

对互联网企业的Web应用而言,强调的是开发、部署、维护的敏捷性,因此我觉得Web层的应用还是采用像RoR、Django、LAMP(CakePHP)的应用架构相对方便,另外在性能调优(例如Cache、页面静态化)方便,像LAMP这样的架构还是较为成熟;在诸如像电子支付这样关注事务完整性、在MVC业务层有复杂的业务逻辑处理(例如交易、结算)的互联网应用领域采用Java架构还是较为恰当的;当然像银行业务、电信系统、电子政务系统这样传统的企业应用领域(Workflow、ESB、Rule Engine、SoA、消息服务等)Java还是会占据较大的优势。

归根结底,采用什么样的语言及架构还是需要根据业务模式的需要来决定。

一些相关的文档,值得一读

http://fishtrain.com/2007/09/26/interview-with-gigaspaces

http://royal.pingdom.com/?p=95

http://royal.pingdom.com/?p=173

http://natishalom.typepad.com/nati_shaloms_blog/2007/10/why-most-scalab.html

http://natishalom.typepad.com/nati_shaloms_blog/2007/10/why-most-large-.html

http://gevaperry.typepad.com/main/2007/10/large-scale-web.html