本套方法主要核心为利用Java中的集合替代了传统Dao模式下的bean层,从而减少了代码量。
废话不多,代码如下。
以新增方法为例:
(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对象,键为字段名,值为字段值)。
根据<foreach>标签循环组合完整的为SQL语句。
(3)业务层实现方法。
/**
* 添加数据
* @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注入攻击。
该套方法还有很大的改进空间和适用局限欢迎各位大神指出错误,提出建议。