结合Mybatis和Java集合实现的通用数据库处理方法(取代传统Dao层结构)

  本套方法主要核心为利用Java中的集合替代了传统Dao模式下的bean层,从而减小了代码量。  java

  废话很少,代码以下。数据库

  以新增方法为例:json

  (1)java中的mapper接口数组

    /**
     * 通用添加数据操做
     * @param map
     * @return
     */
    public boolean add(Map<String, Object> map);

  定义接收参数类型。  安全

  (2)Maybatis的mapper.xml映射文件。数据结构

<insert id="add" parameterType="java.util.Map" >
        insert into ${tablename}
        <foreach collection="keys" item="k" index="index" open="(" separator="," close=")">
            ${k}
        </foreach>
        values
        <foreach collection="keys" item="k" index="index" open="(" separator="," close=")">
            ${params[k]}
        </foreach>
</insert>

  传入的参数为一个Map对象,内部封装有表名:tableName;插入字段名列表:keys(为一字符串数组);字段值:params(Map对象,键为字段名,值为字段值)。app

根据<foreach>标签循环组合完整的为SQL语句。post

  (3)业务层实现方法。spa

 
 

  /**
  * 添加数据
  * @param tableName 表名
  * @param params 参数列表
  * @return true:修改为功 false: 修改失败
  */设计

public boolean addData(String tableName, Map<String, Object> params) {
        
        String[] keys = new String[params.size()];    //字段名
        Set<String> sset = params.keySet();
        int i = 0;
        for(String os : sset){
            keys[i++] = os;
        }
        Map<String, Object> map=new HashMap<String, Object>();
        map.put("tablename" , tableName);
        map.put("keys" , keys);
        map.put("params" , params);
        
        if(commonMapper.add(map)){
            return true;
        }else{
            return false;
        }
    }
该层主要做用为将数据封装成map层所须要的数据结构,即将表名,字段名,字段值封装入Mao中传递给Dao层方法。

 (4)Controller层方法
  
  /**
     * 添加数据
     * 
     * @param request
     * @param response
     * @param model
     * @return
     */
    @RequestMapping("/user/addData.do") public @ResponseBody String addData(HttpServletRequest request, HttpServletResponse response, Model model) { String tableName=""; //表名 String ds = null; //前台数据 try { ds = new String (request.getParameter("postData")); } catch (Exception e1) { e1.printStackTrace(); } JSONArray json=JSONArray.parseArray(ds); JSONObject jsonOne; Map<String,Object> map=new HashMap<String, Object>(); for(int i=0;i<json.size();i++){ jsonOne = json.getJSONObject(i); if(jsonOne.get("Key").equals("tableName")){ tableName = (String) jsonOne.get("Value"); //获取表名 }else{ String key = (String) jsonOne.get("Key"); String value = jsonOne.get("Value").toString(); if(key.charAt(0)=='#'){ //数值类型 key = key.substring(1); }else{ //字符串类型加引号 value = "'"+value+"'"; } map.put(key,value); } } if(commonService.addData(tableName,map)){ return "true"; }else{ return "false"; } }
controller层方法,主要为接受前台数据,将其初步组合传递给Server层进行封装,并接受其返回数据。

以上即为新增方法完整的后台操做流程。下面以较为复杂的分组查询方法为例介绍查询操做的实现。
(1)Maper接口
    /**
     * 根据字段查询(查询字段)
     * @param map
     * @return
     */
    public List<Map<String, Object>> selectFieldsByKeys(Map<String, Object> map);

一样的接口定义,返回类型定义为List<Map<String,Object>>类型数据,其中Map的键对应返回数据的字段名,值对应字段值。前台接收数据时便可根据对应Key值接收字段值。

(2)Mapper XML实现
    <select id="selectFieldsByKeys" resultType="java.util.Map" parameterType="java.util.Map">
        SELECT ${fieldName} FROM ${tablename} 
        <if test="keys != null and keys != ''">
            <where>
            <foreach collection="keys" item="k" index="index" open="" separator=" and " close="">
                ${k} = ${params[k]}
              </foreach>
              </where>
        </if>
        <if test="groupName != null and groupName != ''">
            GROUP BY ${groupName}
        </if>
        <if test="havingName != null and havingName != ''">
            HAVING ${havingName}
        </if>
          <if test="orderName != null and orderName != ''">
            ORDER BY ${orderName}
        </if>
    </select>

  <1>定义返回类型为 resultType="java.util.Map" 类型。

  <2>循环接收查询条件

  <3>判断是否加入其余SQL语句

(3)service方法实现
  
 
 

  /**
  * 分组查询(条件为=)
  * @param tableName 表名
  * @param fieldName 所需查询的字段名
  * @param params 查询条件 map(key:字段名 value:数据值)
  * @param groupName 分组依赖
  * @param havingName聚合条件
  * @param orderName 排序条件(所需排序的字段名)
  * @return
  */

public List<Map<String, Object>> selectFieldsByKeys(String tableName,String fieldName,Map<String, Object> params,String groupName,
            String havingName,String orderName) {
        Map<String, Object> map=new HashMap<String, Object>();
        String[] keys = null; 
        if(params!=null){
            keys = new String[params.size()];        //查询字段名数组
            Set<String> sset = params.keySet();                //获取字段名
            int i = 0;
            for (String os : sset) {
                keys[i++] = os;
            }
        }
            map.put("fieldName",fieldName);
            map.put("tablename" , tableName);
            map.put("keys" , keys);
            map.put("params" , params);
            map.put("groupName", groupName);
            map.put("havingName", havingName);
            map.put("orderName", orderName);
        
        List<Map<String, Object>> result = null;
        result = commonMapper.selectFieldsByKeys(map);
        return result;
    }
将数据封装成map层所须要的数据结构
(4)Controller层方法
根据不一样的需求调用。

注:
以上两个例子分别是以添加和删除为例介绍了实现思想,实际运用中,可根据不一样的须要添加其余方法。例如,多条添加;根据子查询添加,特殊条件查询,调用存储过程等本文主要介绍了后台代码的实现,前台可根据时间需求同样设计出一样的通用操做,减小代码量,提升复用,在此再也不赘述。该套方法,主要做用就是与数据库进行解耦,不用构建实体类与数据库作映射,可实现不一样程序间的代码复用。业务的实现,可在业务层进行代码实现Spring 可经过 @Transactional注解实现。该套方法适用场景有所局限,例如:安全性,在xml中,是经过'$'进行的拼接,容易被SQL注入攻击。该套方法还有很大的改进空间和适用局限欢迎各位大神指出错误,提出建议。
相关文章
相关标签/搜索