ssm項目對mybatis中增刪改sql的封裝

最近搭建了一個ssm的項目,結果發現每個模塊對應的xml文件都要寫一堆insert/update之類的重複性代碼,區別就是表和字段不一樣而已,於是我開始了對其封裝。

 

這裏大概說一下思路:

一、向service的實現類impl類的insert方法中傳入參數List<entity>,在該方法中調用在service的公共類中封裝的轉換方法convertList
二、convertList方法將List<entity>轉換爲了Map<String,Object>,並從中得到了entity的字段名稱與主鍵、每個enttiy的值等信息。
三、dao接口接受Map<String,Object>參數

四、創建一個公共xml文件,裏面對findOne / findAll / insert / update / delete 等常用方法進行封裝。
五、在對應模塊的xml文件中,通過sql標籤聲明表名與主鍵,然後通過include標籤調用公共xml文件中對應sql。

 

特別提示,這裏用到了一個包,我主要用這個包確定entity中的主鍵。
 

<!-- 用於java反射獲取entity中的註解 -->
    <dependency>
      <groupId>javax.persistence</groupId>
      <artifactId>persistence-api</artifactId>
      <version>1.0.2</version>
    </dependency>

 

下面是滿滿的乾貨,拿走,別客氣!!!

一、模板xml文件:GenericMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="GenericMapper">

    <sql id="findOne">select main.* from <include refid="tableName"/> main where main.<include refid="primaryKey"/> = #{mainId}</sql>
    <sql id="findAll">select main.* from <include refid="tableName"/> main</sql>

    
    <sql id="insert">
        INSERT INTO <include refid="tableName"/> (<foreach collection="map.fields" index="key" item="value" separator=",">${value}</foreach>) VALUES
        <foreach collection="map.list" item="item" separator=",">
            (<foreach collection="item" item="value" separator=",">#{value}</foreach>)
        </foreach>
    </sql>

    <sql id="update">
        update <include refid="tableName"/>
        <set>
            <foreach collection="map.fields" item="name" separator=",">
                ${name} = case <include refid="primaryKey"/>
                <foreach collection="map.list" item="item">
                    <foreach collection="item" index="key" item="val" >
                        <if test="key == map.primaryKey"> when ${"'"}${val}${"'"} then </if><if test="key == name"> #{val} </if>
                    </foreach>
                </foreach>
                end
            </foreach>
        </set>
        where <include refid="primaryKey"/> in (<foreach collection="map.mainIds" item="value" separator=",">#{value}</foreach>)
    </sql>
    
    
    <sql id="delete">delete main from <include refid="tableName"/> main where main.<include refid="primaryKey"/>=#{mainId}</sql>

    
    <sql id="deleteByMainIds">
        delete main from <include refid="tableName"/> main where main.<include refid="primaryKey"/> in
        <foreach collection="list"  item="item" open="(" separator="," close=")"  >
            #{item}
        </foreach>
    </sql>
    <sql id="deleteAll">delete main from <include refid="tableName"/> main</sql>
</mapper>

 

二、某個模塊的xml文件中的部分代碼:CoreMenuUrlInfoDao.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="model.core.menuurl.dao.CoreMenuUrlInfoDao">
    <!--表名-->
    <sql id="tableName">core_menu_url_info</sql>
    <!--主鍵-->
    <sql id="primaryKey">URL_ID</sql>
    
    <select id="findOne" resultType="CoreMenuUrlInfoEntity" parameterType="String">
        <include refid="GenericMapper.findOne"/>
    </select>

    <insert id="insert" >
        <include refid="GenericMapper.insert"/>
    </insert>

    <update id="update">
        <include refid="GenericMapper.update"/>
    </update>

    <delete id="delete" parameterType="String">
        <include refid="GenericMapper.delete"/>
    </delete>
</mapper>

 

三、dao文件:CoreMenuUrlInfoDao.java

import model.core.menuurl.entity.CoreMenuUrlInfoEntity;
import org.apache.ibatis.annotations.Param;

import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

public interface CoreMenuUrlInfoDao {
    CoreMenuUrlInfoEntity findOne(@Param("mainId") String mainId);

    int insert(@Param("map") Map<String,Object> map);

    int update(@Param("map") Map<String,Object> map);

    int delete(@Param("mainId") String mainId);

}

 

四、entity:CoreMenuUrlInfoEntity.java


import javax.persistence.*;
import java.sql.Timestamp;

@Entity
@Table(name = "core_menu_url_info")
public class CoreMenuUrlInfoEntity {
    private String urlId;
    private String title;
    private String code;
    private String url;
    private String parameter;
    private Timestamp sysTime;

    @Id
    @Column(name = "URL_ID")
    public String getUrlId() {
        return urlId;
    }

    public void setUrlId(String urlId) {
        this.urlId = urlId;
    }

    @Basic
    @Column(name = "TITLE")
    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    @Basic
    @Column(name = "CODE")
    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    @Basic
    @Column(name = "URL")
    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    @Basic
    @Column(name = "PARAMETER")
    public String getParameter() {
        return parameter;
    }

    public void setParameter(String parameter) {
        this.parameter = parameter;
    }

    @Basic
    @Column(name = "SYS_TIME")
    public Timestamp getSysTime() {
        return sysTime;
    }

    public void setSysTime(Timestamp sysTime) {
        this.sysTime = sysTime;
    }
}

 

五、實現類:CoreMenuUrlServiceImpl.java


import model.core.menuurl.dao.CoreMenuUrlInfoDao;
import model.core.menuurl.entity.CoreMenuUrlInfoEntity;
import model.core.menuurl.service.CoreMenuUrlService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import util.context.ApplicationContext;
import util.datamanage.GenericService;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.UUID;

@Service
public class CoreMenuUrlServiceImpl extends GenericService<CoreMenuUrlInfoEntity> implements CoreMenuUrlService {
    @Autowired
    private CoreMenuUrlInfoDao dao;

    @Override
    public CoreMenuUrlInfoEntity findOne(String primaryId) {
        return dao.findOne(primaryId);
    }

    @Override
    @Transactional
    public int insert(CoreMenuUrlInfoEntity entity){
        return dao.insert(convertList(entity));
    }
    @Override
    @Transactional
    public int insert(List<CoreMenuUrlInfoEntity> list) {
        return dao.insert(convertList(list));
    }

    @Override
    @Transactional
    public int update(CoreMenuUrlInfoEntity entity) {
        return dao.update(convertList(entity));
    }
    @Override
    @Transactional
    public int update(List<CoreMenuUrlInfoEntity> list) {
        return dao.update(convertList(list));
    }

    @Override
    @Transactional
    public int delete(String primaryId) {
        return dao.delete(primaryId);
    }

}

 

六、接口:CoreMenuUrlService.java


import model.core.menuurl.entity.CoreMenuUrlInfoEntity;
import org.apache.ibatis.annotations.Param;

import java.util.List;

public interface CoreMenuUrlService {
    CoreMenuUrlInfoEntity findOne(String mainId);

    int insert(CoreMenuUrlInfoEntity entity);
    int insert(List<CoreMenuUrlInfoEntity> list);

    int update(CoreMenuUrlInfoEntity entity);
    int update(List<CoreMenuUrlInfoEntity> list);

    int delete(String mainId);
}

七、service的一個公共類:GenericService.java


import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import util.CommonUtil;

import javax.persistence.Id;
import java.lang.reflect.Field;
import java.util.*;

public class GenericService<T>{
	public Logger logger = LoggerFactory.getLogger(this.getClass());

	public Map<String,Object> convertList(T obj){
		List<T> list = new ArrayList<>();
		list.add(obj);
		return convertList(list);
	}
	public Map<String,Object> convertList(List<T> list){
		String primaryKey = "";
		List<String> fields = new ArrayList<>();
		List<LinkedHashMap<String,Object>> reList = new ArrayList<>();
		List<Object> mainIds = new ArrayList<>();
		try{
			if(list == null || list.size() < 1){
				throw new Exception("對象轉換失敗!");
			}
			int i = 0;
			for(Object obj : list){
				LinkedHashMap<String,Object> valMap = new LinkedHashMap<>();
				Class c = obj.getClass();
				for(Field field : c.getDeclaredFields()){
					//設置爲可訪問
					field.setAccessible(true);
					String name = humpToUnderline(field.getName().toString());
					Object val = field.get(obj);
					boolean isMain = false;

					//通過該字段的get方法判斷其是否存在@Id註解
					if(c.getMethod(underlineToHump("GET_" + name)).isAnnotationPresent(Id.class)){
						mainIds.add(val);
						isMain = true;
					}
					if(i == 0){
						if(isMain){
							primaryKey = name;
						}
						fields.add(name);
					}
					valMap.put(name,val);
				}
				reList.add(valMap);
				i++;
			}

		}catch (Exception e){
			e.printStackTrace();
		}

		Map<String,Object> map = new HashMap<>();
		//將駝峯命名的字段名轉爲下劃線
		map.put("primaryKey", primaryKey);
		map.put("mainIds", mainIds);
		map.put("fields", fields);
		map.put("list", reList);
		return map;
	}

	public Map<String,Object> entityToMap(T obj){
		Map<String,Object> map = new HashMap<>();
		Class c = obj.getClass();
		try{
			for(Field field : c.getDeclaredFields()){
				//設置爲可訪問
				field.setAccessible(true);
				map.put(field.getName().toString(),field.get(obj));
			}
		}catch (Exception e){
			e.printStackTrace();
		}
		return map;
	}


	//將list中map的key按照駝峯命名法進行轉換,如:MENU_ID > menuId
	public List<Map<String,Object>> underlineToHump(List<Map<String,Object>> list){
		List<Map<String,Object>> listNew = new ArrayList<>();
		for(Map<String,Object> map : list){
			Map<String,Object> mapNew = new HashMap<>();
			for(Map.Entry<String,Object> m : map.entrySet()){
				mapNew.put(CommonUtil.lineToHump(m.getKey()),m.getValue() == null ? "" : m.getValue());
			}
			listNew.add(mapNew);
		}
		return listNew;
	}

	public String underlineToHump(String field){
		return CommonUtil.lineToHump(field);
	}
	//駝峯命名轉爲下劃線命名,如:menuId > MENU_ID
	public String humpToUnderline(String field){
		StringBuilder sb=new StringBuilder(field);
		int temp=0;//定位
		if (!field.contains("_")) {
			for(int i=0;i<field.length();i++){
				if(Character.isUpperCase(field.charAt(i))){
					sb.insert(i+temp, "_");
					temp+=1;
				}
			}
		}
		return sb.toString().toUpperCase();
	}
}

八、其實到第七步就可以了,不過爲了完整性,還是把後面部分放出來。CoreMenuUrlController.java


import model.core.menuurl.entity.CoreMenuUrlInfoEntity;
import model.core.menuurl.service.CoreMenuUrlService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import util.datamanage.GenericController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;

@Controller
@RequestMapping("/core/menuurl")
public class CoreMenuUrlController extends GenericController{

    @Autowired
    private CoreMenuUrlService mainService;

    @RequestMapping("saveMain")
    @ResponseBody
    public String saveMain(HttpServletRequest request, HttpServletResponse response)throws Exception{
        String primaryId = request.getParameter("urlId");
        String title = request.getParameter("title");
        String code = request.getParameter("code");
        String url = request.getParameter("url");
        String parameter = request.getParameter("parameter");

        CoreMenuUrlInfoEntity entity = new CoreMenuUrlInfoEntity();
        if(StringUtils.isBlank(primaryId)){
            entity.setUrlId(UUID.randomUUID().toString());
        }else{
            entity = mainService.findOne(primaryId);
        }
        entity.setTitle(title);
        entity.setCode(code);
        entity.setUrl(url);
        entity.setParameter(parameter);
        entity.setSysTime(new Timestamp(System.currentTimeMillis()));
        try{
            if(StringUtils.isBlank(primaryId)){
                mainService.insert(entity);
            }else{
                mainService.update(entity);
            }
        }catch (Exception e){
            e.printStackTrace();
            return returnFaild();
        }
        return returnSuccess();
    }

    @RequestMapping("deleteMain")
    @ResponseBody
    public String deleteMain(HttpServletRequest request, HttpServletResponse response)throws Exception{
        String primaryId = request.getParameter("primaryId");
        try {
            mainService.delete(primaryId);
            return returnSuccess();
        }catch (Exception e){
            e.printStackTrace();
            return returnFaild();
        }
    }
}

 

九、Controller的公共方法:GenericController.java


import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Controller中的通用方法
 */
public class GenericController {
    public Logger logger = LoggerFactory.getLogger(this.getClass());
    //將查詢的數據轉換成字符串返回
    public static String getTable(Object list,int count){
        Map<String, Object> table = new HashMap<String, Object>();

        table.put("code", 0);
        table.put("msg", "查詢成功");
        table.put("count", count);
        table.put("data", list);
        JSONObject jsonObject = JSONObject.fromObject(table);
        return jsonObject.toString();
    }


    public static String returnStringByMap(Object obj) {
        return JSONObject.fromObject(obj).toString();
    }
    public static String returnStringByList(Object obj) {
        return JSONArray.fromObject(obj).toString();
    }

    //操作成功的返回
    public static String returnSuccess(String msg) {
        JSONObject re = new JSONObject();
        if(StringUtils.isBlank(msg)){
            msg="操作成功!";
        }
        re.put("error", false);
        re.put("msg", msg);
        return re.toString();
    }

    //操作失敗的返回
    public static String returnFaild(String msg) {
        JSONObject re = new JSONObject();
        if(StringUtils.isBlank(msg)){
            msg="操作失敗!";
        }
        re.put("error", true);
        re.put("msg", msg);
        return re.toString();
    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章