浏览 5644 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2007-02-05
最近我将该功能模块进行了重构,使其可以脱离ecside来使用,从而可以用来简化其他的数据库操作。 具体用法结合下面的例子来讲解: 示例 : 对 USER_INFO 表进行查询。 查询条件为 USERNAME GENDER。 第1步:定义spring文件: <bean id="testQuery1" class="org.ecside.easyda.DataAccessModel"> <!-- 注入一个标准的数据源 --> <property name="dataSource" ref="test_datasource" /> <property name="sqls"> <map> <!-- 这个key的名字随便取 --> <entry key="queryInfoByNameGender" > <value> select * from user_info where 1=1 #{IF:USERNAME!=EMPTY} and username like #{USERNAME} #{/IF} #{IF:GENDER!=EMPTY} and gender=#{GENDER} #{/IF} </value> </entry> </map> </property> </bean> 第2步,在适当的位置(如BO中)执行下列java代码 // 这里也可以使用 Ioc 注入。 DataAccessModel dam=(DataAccessModel)factory.getBean("testQuery1"); //parameterMap为传入参数,key为USERNAME GENDER。 List list=(List)dam.executeQuery("queryInfoByNameGender", parameterMap); ok,执行完了,执行的每条结果会放入MAP,所有的MAP最后放入LIST Map的Key是SQL语句执行结果的各个列的名字。 其中 #{USERNAME} #{GENDER} 为参数在传入的参数Map中的key. 其中 #{IF..} 字句用来拼装SQL.。 其语义为 如果满足条件 就把IF内的字符串拼接到有效的SQL语句中。 支持简单的条件: A<B : #{IF:A#{_L}B}....{/IF} A>B : #{IF:A#{_G}B}....{/IF} A=B : #{IF:A=B}....{/IF} A!=B : #{IF:A!=B}....{/IF} A<=B : #{IF:A#{_L}=B}....{/IF} A>=B : #{IF:A#{_G}=B}....{/IF} A为参数(的KEY), B为数值,可以是EMPTY NULL 字符串 数字 等如 #{IF:USERNAME!='admin'}....{/IF} #{IF:AGE #{_L}= 18}....{/IF} 注意 < >于号出现在 sql语句中时也请使用 #{_L} #{_G} #{IF:A=B}....{/IF} 内部 可以是任何语句,也可以使用任何参数。不一定非要是A. 例如 这样也是可以的 #{IF:USERROLE='1'} and (GENDER = ${XXXX} or AGE ${_L} 25 {/IF} 传入参数可以使用组件中提供的getParameterMap方法从request中自动生成,相应的代码很简单: public static Map getParameterMap(HttpServletRequest request) { Map parameterMap = new HashMap(); Enumeration names = request.getParameterNames(); while (names.hasMoreElements()) { String name = (String) names.nextElement(); String[] s = request.getParameterValues(name); if (s != null) { if (s.length == 1) { parameterMap.put(name, request.getParameterValues(name)[0]); } else { parameterMap.put(name, request.getParameterValues(name)); } } } return parameterMap; } 如果查询叶面的input区域是 姓名:<input type="text" name="i_user_name"> 性别:<input type="text" name="i_user_gender"> 通过 getParameterMap 取得参数map后,如果想直接调用sql 那么sql需要改动为 <entry key="queryInfoByNameGender" > <value> select * from user_info where 1=1 #{IF:i_user_name!=EMPTY} and username like #{i_user_name} #{/IF} #{IF:i_user_gender!=EMPTY} and gender=#{i_user_gender} #{/IF} </value> </entry> 一个DataAccessModel bean里可以写入多个sql. 可以是 delete update insert select {call... 例如下面这个 <bean id="myEasyDA" class="demo.MyDataAccessModel"> <property name="dataSource" ref="test_datasource" /> <property name="sqls"> <map> <entry key="baseInfo1" > <value> {call CM_CUST_REAL_INFO_P( #{I_SERVICE_KIND}, #{I_SERVICE_NO}, #{I_CITY_CODE}, #{I_SERVICE_ID}, #{I_CUSTOMER_ID}, #{OUT:OUT_F_CUST_NAME}, #{OUT:OUT_F_GENDER}, #{OUT:OUT_F_DUTY}, #{OUT:OUT_F_PRODUCT_NAME}, #{OUT:OUT_F_POINT_VALUE}, #{OUT:OUT_F_STATUS}, #{OUT:ON_FLAG}, #{OUT:OS_PROMPT} )} </value> </entry> <entry key="updateUser" > <value> update user_info set passwd=#{PASSWD} , userrole=#{USERROLE} , email=#{EMAIL}, gender=#{GENDER} WHERE userid=#{USERID} </value> </entry> <entry key="deleteUser" > <value> delete from user_info WHERE userid=#{USERID} </value> </entry> <entry key="getUserMemo" > <value> select MEMO,EMAIL from user_info WHERE userid=#{USERID} </value> </entry> </map> </property> </bean> 其中 #{OUT:...} 用来标识 存储过程的输出参数。 其中的 demo.MyDataAccessModel 继承自 org.ecside.easyda.DataAccessModel 你可以在这个类里覆盖父类的registerInterceptors方法,为每个sql添加前后拦截器。 代码如下: public class MyDataAccessModel extends DataAccessModel { public void registerInterceptors(){ addInterceptor(new DataAccessInterceptor("updateUser"){ public void before(Map parameterMap, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { } public void after(Map parameterMap, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setAttribute(ECSideConstants.C_UPDATE_RESULT_MESSAGE,request.getParameter("USERNAME")); ServletUtil.writeDefaultTextToClient(parameterMap, request, response); } }); addInterceptor(new DataAccessInterceptor("deleteUser"){ public void before(Map parameterMap, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { } public void after(Map parameterMap, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setAttribute(ECSideConstants.C_UPDATE_RESULT_MESSAGE,request.getParameter("USERNAME")); ServletUtil.writeDefaultTextToClient(parameterMap, request, response); } }); } } 已知不足: 在事务控制方面做的工作几乎为0。 #{IF}功能不够强大,不支持复杂的逻辑判断。 所以目前不适合用在复杂的场合。 另:整个过程输入 输出的sql类型 全是string,所以如果要做类型方面的转换,需要自己在sql语句级别进行。 这篇文章没有提供代码,打算下和 ecside 1.1 final一起推出。 希望大家可以针对这个模块提出些建议和意见 谢谢大家了。 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2007-02-06
where 11=1
为什麽一个1是红色、一个1是蓝色? |
|
返回顶楼 | |
发表时间:2007-02-06
是 1=1 但不知道为什么 贴上来就变成 11=1 了
|
|
返回顶楼 | |