MyBatis增删改查(CURD)通用方法简单实现(防sql注入)

每个项目都会用到最基本的增删改查操作,而很多代码都是重复的。所以这篇文章写一下自己在项目中抽取出来的通用代码(基于Mybatis和spring框架,数据库是MySql),其中有一些工具方法是参考别人的。之前看过很多文章的实现方法都是通过字符串拼接Sql语句,然后再mybatis.xml映射文件中直用${sql},如下:

直接在dao方法里面拼接好传过来,这样一个坏处就是不能防止sql注入,在mybatis映射文件中,能用#{}的尽量用#{}(在这里不聊${}与#{}的区别,不清楚两者区别的可以去了解一下)。

1.DAO接口:

**
 * 公共数据库操作层
 * @param  实体PO类型
 * @param  PO主键类型
 */
public interface Dao {	
        /**
         * 记录添加
         * @param po
         * @return
         */
        public int add(T po);
	
	/**
	 * 批量添加
	 * @param poList
	 * @return
	 */
	public int addBatch (List poList);
	
	/**
         * 通过主键获取某个记录
         * @param id 主键
         * @return PO
         */
	public T get(PK id);
	
	/**
         * 通过主键获取某个字段的值
         * @param id
         * @param fileName
         * @return
         */
	public Serializable getField(PK id, String fileName);

	/**
         * 条件获取一条记录
         * @param t
         * @param 条件表达式
         * @return PO
         */
	public T get(Where where);
	
	/**
         * 条件获取某个记录字段
         * @param where
         * @param fileName
         * @return
         */
	public Serializable getFile(Where where, String fileName);
	
	/**
         * 条件查询列表
         * @param where 条件表达式
         * @return PO列表
         */
	public List list(Where where);
	
	/**
         * 更新不为null的PO字段
         * @param po
         * @return 受影响的行数
         */
	public int updateLocal(T po);
	
	/**
         * 更新PO的所有字段
         * @param po
         * @return 受影响的行数
         */
	public int update(T po);
	
	/**
         * 条件更新不为null的字段
         * @param po
         * @param 条件表达式
         * @return 受影响的行数
         */
	public int updateLocal(T po, Where where);
	
	/**
         * 条件更新所有字段
         * @param po
         * @param 条件表达式
         * @return 受影响的行数
         */
	public int update(T po, Where where);
	
	/**
         * 删除某个记录
         * @param id 主键
         * @return 受影响的行数
         */
	public int del(PK id);
	
	/**
         * 条件删除某个记录
         * @param where 条件表达式
         * @return 受影响的行数
         */
	public int del(Where where);
	
	/**
         * 获取指定条件的记录数
         * @param where 条件表达式
         * @return 查询到的记录数
         */
	public long count(Where where);
	
	/**
         * 获取对应表中的记录数
         * @return 表中的条数
         */
	public long count();
	
	public List in(String fileName, Serializable[] values);
	/**
         * 内查询
         * @param fileName 用于内查询的字段
         * @param values 字段的值
         * @return 查询到的结果集
         */
	public List in(String fileName, Serializable[] values,Where where);
}

其中Po为所有实体类的父类,所有要入库的实体类都继承它:

public class Po {
	
}

比如:Test

public class Test extends Po{
	private Integer id;
	private String name;
//省去set/get方法
}

而里面有一些方法参数为Where,这个为封装的条件类,在下面详细说。

2.DAO实现类DaoImpl

@SuppressWarnings("unused")
@Repository
public class DaoImpl implements Dao {

	protected Logger logger = Logger.getLogger(this.getClass());

	@Resource(name = "sqlSessionTemplateASS")
	protected SqlSessionTemplate sqlSessionTemplateASS;    //sqlSession实例,spring-mybatis.xml配置文件中配置

	private Class entityClass;

	private String pkName;		    //主键字段

	private String idName;		    //对应id名称

	private String tableName;           //表名

	private List sqlParms;        //实体类参数列表,无值无id

	private List selectSqlParms;    //查询参数列表 无值有id

	private SqlUtil sqlUtil;            //工具类

	public DaoImpl(){
		this("id", "id");
	}

	/**
	 * 
	 * @param pkName 主键字段名
	 * @param idName 对应id名称
	 */
	@SuppressWarnings("unchecked")
	public DaoImpl(String pkName,String idName){
		super();

		this.sqlUtil = new SqlUtil();

		this.entityClass = (Class) GenericsUtils.getSuperClassGenricType(this.getClass());//获取当前类的class

		this.sqlParms = this.sqlUtil.getPramList(this.entityClass);//通过class获取该实体类的参数放到Pram
		this.selectSqlParms = this.sqlUtil.getPramListOfSelect(this.entityClass);//通过class获取该实体类的参数放到Pram

		this.tableName = this.sqlUtil.getTableName(this.entityClass);

		this.pkName = pkName;

		this.idName = idName;

	}

	/**
	 * 添加
	 */
	@Override
	public int add(T po) {
		MybatisPo mybatisPo = new MybatisPo(this.pkName,this.idName,this.tableName,
				this.selectSqlParms,this.sqlParms);

		List pramList = SqlUtil.getPramListofStatic(po);
		mybatisPo.setPramList(pramList);
		int c = sqlSessionTemplateASS.insert("add", mybatisPo);
		SqlUtil.setFileValue(po, idName, (Serializable)mybatisPo.getPkValue());
		return c;
	}
	
	/**
	 * 批量添加
	 */
	@Override
	public int addBatch(List poList) {
		MybatisPo mybatisPo = new MybatisPo(this.pkName,this.idName,this.tableName,
				this.selectSqlParms,this.sqlParms);

		List> batchPramList = new ArrayList<>();
		for (T po:poList) {
			List pramList = SqlUtil.getPramListofStatic(po);
			batchPramList.add(pramList);
		}
		mybatisPo.setBatchPramList(batchPramList);
		return sqlSessionTemplateASS.insert("addBatch", mybatisPo);
	}

	/**
	 * 通过主键获取某个记录
	 * @param id 主键
	 */
	@Override
	public T get(PK ID) {
		MybatisPo mybatisPo = new MybatisPo(this.pkName,this.idName,this.tableName,
				this.selectSqlParms,this.sqlParms);
		mybatisPo.setPkValue(ID);
		Map resultMap = sqlSessionTemplateASS.selectOne(
				"getById", mybatisPo);

		return handleResult(resultMap, this.entityClass);
	}

	/**
	 * 条件查询列表
	 */
	@Override
	public List list(Where where) {
		MybatisPo mybatisPo = new MybatisPo(this.pkName,this.idName,this.tableName,
				this.selectSqlParms,this.sqlParms);

		mybatisPo.setWhere(where);
		List> selectList = sqlSessionTemplateASS.selectList("selectList", mybatisPo);

		List list = new ArrayList<>();
		for (Map map : selectList) {
			T t = handleResult(map, this.entityClass);
			list.add(t);
		}
		return list;
	}

	/**
	 * 通过主键获取某个字段的值
	 */
	@Override
	public Serializable getField(PK id, String fileName) {
		MybatisPo mybatisPo = new MybatisPo(this.pkName,this.idName,this.tableName,
				this.selectSqlParms,this.sqlParms);
		mybatisPo.setPkValue(id);
		String field = fileName;
		String tabField = "";
		Field f = sqlUtil.getField(this.entityClass, fileName);
		if (null == f) {
			logger.error("查询字段失败(无法找到" + this.entityClass + "中的" + fileName + "字段)");
		}
		FieldName annotation = f.getAnnotation(FieldName.class);
		if (null == annotation) {
			tabField = sqlUtil.toTableString(fileName) + " as " + fileName;
		}else{
			tabField = annotation.name() + " as " + fileName;
		}

		List pl = new ArrayList();
		Pram p = new Pram();
		p.setFile(tabField);
		pl.add(p);
		mybatisPo.setSelectSqlParms(pl);

		Map resultMap = sqlSessionTemplateASS.selectOne(
				"getById", mybatisPo);
		return (Serializable) resultMap.get(fileName);
	}

	/**
	 * 条件获取一条记录
	 */
	@Override
	public T get(Where where) {
		MybatisPo mybatisPo = new MybatisPo(this.pkName,this.idName,this.tableName,
				this.selectSqlParms,this.sqlParms);
		mybatisPo.setWhere(where);
		List> selectList = sqlSessionTemplateASS.selectList("selectList", mybatisPo);

		if(selectList.size() <= 0) {
			return null;
		}
		return handleResult(selectList.get(0), this.entityClass);
	}

	/**
	 * 条件获取某个记录字段
	 */
	@Override
	public Serializable getFile(Where where, String fileName) {
		MybatisPo mybatisPo = new MybatisPo(this.pkName,this.idName,this.tableName,
				this.selectSqlParms,this.sqlParms);
		mybatisPo.setWhere(where);

		String field = fileName;
		String tabField = "";
		Field f = sqlUtil.getField(this.entityClass, fileName);
		if (null == f) {
			logger.error("查询字段失败(无法找到" + this.entityClass + "中的" + fileName + "字段)");
		}
		FieldName annotation = f.getAnnotation(FieldName.class);
		if (null == annotation) {
			tabField = sqlUtil.toTableString(fileName) + " as " + fileName;
		}else{
			tabField = annotation.name() + " as " + fileName;
		}

		List pl = new ArrayList();
		Pram p = new Pram();
		p.setFile(tabField);
		pl.add(p);
		mybatisPo.setSelectSqlParms(pl);

		List> selectList = sqlSessionTemplateASS.selectList("selectList", mybatisPo);
		if(selectList.size() <= 0) {
			return null;
		}
		return (Serializable) selectList.get(0).get(fileName);
	}

	/**
	 * 更新po对象非空的地方到数据库对应的字段
	 */
	@SuppressWarnings("unchecked")
	@Override
	public int updateLocal(T po) {
		Serializable id = sqlUtil.getFileValue(po, this.idName);
		if(null == id){
			return 0;
		}

		T pold = get((PK)id);
		if (pold != null) {
			return updateLocal(po, new Where(pkName, "=", id+""));
		}
		return 0;
	}

	/**
	 * 如果po存在 更新 po的所有字段 空字段也更新到对于字段
	 */
	@SuppressWarnings("unchecked")
	@Override
	public int update(T po) {
		Serializable id = sqlUtil.getFileValue(po, this.idName);
		if(null == id){
			return 0;
		}

		T pold = get((PK)id);
		if (pold != null) {
			return update(po, new Where(pkName, "=", id+""));
		}
		return 0;
	}

	/**
	 * 条件更新po非空的地方
	 */
	@Override
	public int updateLocal(T po, Where where) {
		MybatisPo mybatisPo = new MybatisPo(this.pkName,this.idName,this.tableName,
				this.selectSqlParms,this.sqlParms);

		List prams = sqlUtil.getPramList(po);
		List pramsNotNull = new ArrayList<>();
		mybatisPo.setWhere(where);

		for (int i = 0; i < prams.size(); i++) {
			Object value = prams.get(i).getValue();
			if(null != prams.get(i).getValue()){
				if (value instanceof byte[] ) {
					value = new String((byte[]) value);
				}else if(value instanceof Boolean){
					value = ((boolean)value == true ? 1 : 0);
				}
				pramsNotNull.add(new Pram(prams.get(i).getFile(), value));
			}
		}
		mybatisPo.setPramList(pramsNotNull);
		return sqlSessionTemplateASS.update("update", mybatisPo);
	}

	/**
	 * 条件更新 po 空也更新到对于字段
	 */
	@Override
	public int update(T po, Where where) {
		MybatisPo mybatisPo = new MybatisPo(this.pkName,this.idName,this.tableName,
				this.selectSqlParms,this.sqlParms);

		List prams = sqlUtil.getPramList(po);
		mybatisPo.setPramList(prams);
		mybatisPo.setWhere(where);

		for (int i = 0; i < prams.size(); i++) {
			Object value = prams.get(i).getValue();
			if(null != prams.get(i).getValue()){
				if (value instanceof byte[] ) {
					value = new String((byte[]) value);
				}else if(value instanceof Boolean){
					value = ((boolean)value == true ? 1 : 0);
				}
			}else{
				value = "null";
			}
		}
		return sqlSessionTemplateASS.update("update", mybatisPo);
	}

	/**
	 * 删除指定id的数据
	 */
	@Override
	public int del(PK id) {
		if (id == null) {
			return 0;
		}
		return del(new Where(pkName, "=", id+""));
	}

	/**
	 * 条件删除
	 */
	@Override
	public int del(Where where) {
		MybatisPo mybatisPo = new MybatisPo(this.pkName,this.idName,this.tableName,
				this.selectSqlParms,this.sqlParms);
		mybatisPo.setWhere(where);

		return sqlSessionTemplateASS.delete("delete", mybatisPo);
	}

	@Override
	public long count(Where where) {
		MybatisPo mybatisPo = new MybatisPo(this.pkName,this.idName,this.tableName,
				this.selectSqlParms,this.sqlParms);
		mybatisPo.setWhere(where);
		return sqlSessionTemplateASS.selectOne("selectCount", mybatisPo);
	}

	@Override
	public long count() {
		return count(null);
	}

	@Override
	public List in(String fileName, Serializable[] values) {
		return in(fileName, values, null);
	}

	@Override
	public List in(String fileName, Serializable[] values,Where where) {
		StringBuilder sb = new StringBuilder("(");
		for (String s:(String[])values) {
			sb.append(s).append(",");
		}
		sb.replace(sb.length()-1, sb.length(), ")");

		if (where == null) {
			where = new Where(fileName, "in", sb.toString());
		} else {
			where.and(fileName, "in", sb.toString());
		}
		return list(where);
	}

	protected T handleResult(Map resultMap, Class tClazz) {
		if (null == resultMap) {
			return null;
		}
		T t = null;
		try {
			t = tClazz.newInstance();
		} catch (InstantiationException e) {
			logger.error("/********************************");
			logger.error("实例化Bean失败(" + this.entityClass + ")!"
					+ e.getMessage());
			logger.error("/********************************");
		} catch (IllegalAccessException e) {
			logger.error("/********************************");
			logger.error("实例化Bean失败(" + this.entityClass + ")!"
					+ e.getMessage());
			logger.error("/********************************");
		}
		for (Map.Entry entry : resultMap.entrySet()) {
			String key = entry.getKey();
			Serializable val = (Serializable) entry.getValue();
			try {
				SqlUtil.setFileValue(t, key, val);
			} catch (Exception e) {
				logger.error("/********************************");
				logger.error("/实例化Bean失败(" + this.entityClass + ")不能赋值到字段(" + key + "):"
						+ e.getMessage());
				logger.error("/********************************");
			}
		}
		return t;
	}
}

List对应一个实体对象,Pram则对应实体里面的一个属性:

public class Pram {

	private String file;    //实体属性名
	
	private Object value;    //属性对应的值

	public Pram(){}
	
	public Pram(String file){
		this.file = file;
	}
	public Pram(String file, Object value){
		this.file = file;
		this.value = value;
	}
//省略set/get方法
}

在这里贴出SqlUtil工具类的几个主要方法,可以参考或者自己实现,通过反射就可以获取。

public List getPramList(Class po){
		List list = new ArrayList<>();
		Class thisClass = po;
		Field[] fields = thisClass.getDeclaredFields();
		for(Field f : fields){
			if(!f.getName().equalsIgnoreCase("ID") && !f.isAnnotationPresent(TempField.class)){
				String fName = f.getName();
				if (f.isAnnotationPresent(FieldName.class)) {
					String fieldName = f.getAnnotation(FieldName.class).name();
					Pram pram = new Pram(fieldName);
					list.add(pram);
				}else{
					String fieldName = toTableString(fName);
					Pram pram = new Pram(fieldName);
					list.add(pram);
				}
			}
		}
		return list;
	}

public List getPramListOfSelect(Class po){
		List list = new ArrayList<>();
		Class thisClass = po;
		Field[] fields = thisClass.getDeclaredFields();
		for(Field f : fields){
			if (!f.isAnnotationPresent(TempField.class)) {
				String fName = f.getName();
				if (f.isAnnotationPresent(FieldName.class)) {
					String fieldName = f.getAnnotation(FieldName.class).name();
					Pram pram = new Pram(fieldName + " as " + fName);
					list.add(pram);
				}else{
					String fieldName = toTableString(fName);
					Pram pram = new Pram(fieldName + " as " + fName);
					list.add(pram);
				}
			}
		}
		return list;
	}

public String getTableName(Class po){
		if(po.isAnnotationPresent(TableName.class)){
			return po.getAnnotation(TableName.class).name();
		}else{
			String tName = toTableString(po.getSimpleName());
			String poName = tName.substring(tName.length() - 2, tName.length());
			if("po".equals(poName)){
				tName = tName.substring(0,tName.length() - 3);
			}
			return tName;
		}
	}

public static List getPramListofStatic(Po po){
		List list = new ArrayList<>();
		Class thisClass = po.getClass();
	    Field[] fields = thisClass.getDeclaredFields();
	    	try {
	    		for(Field f : fields){
		    		if(!f.getName().equalsIgnoreCase("ID") && !f.isAnnotationPresent(TempField.class)){
		    			String fName = f.getName();

		    			String getf = "get";
		    			String fieldType = f.getGenericType().toString();
		    			if (fieldType.indexOf("boolean") != -1 || fieldType.indexOf("Boolean") != -1) {
		    				getf = "is";
						}
		    			if (f.isAnnotationPresent(FieldName.class)) {
		    				String fieldName = f.getAnnotation(FieldName.class).name();
		    				Method get = thisClass.getMethod(getf + fName.substring(0, 1).toUpperCase() + fName.substring(1));
		    				Object getValue = get.invoke(po);
		    				Pram pram = new Pram(fieldName, getValue);
							list.add(pram);
		    			}else{
		    				String fieldName = new SqlUtil().toTableString(fName);
		    				Method get = thisClass.getMethod(getf + fName.substring(0, 1).toUpperCase() + fName.substring(1));
		    				Object getValue = get.invoke(po);
		    				Pram pram = new Pram(fieldName, getValue);
							list.add(pram);
						}
		    		}
	    		}
			} catch (NoSuchMethodException e) {
				e.printStackTrace();
			} catch (SecurityException e) {
				e.printStackTrace();
			}
	    	catch (IllegalAccessException e) {
				e.printStackTrace();
			} catch (IllegalArgumentException e) {
				e.printStackTrace();
			} catch (InvocationTargetException e) {
				e.printStackTrace();
			}
		return list;
	}
	/**
	 * 将某个实体通过反射强制赋给实体某个域
	 * @param po
	 * @param fileName
	 * @param fileValue
	 * @return
	 */
	public static boolean setFileValue(Po po, String fileName, Serializable fileValue){
		fileName = UnderlineToHump(fileName);
		Class thisClass = po.getClass();
		try {
			Field fie    ld = thisClass.getDeclaredField(fileName);
			String calssName = field.getType().getName();
			if (calssName.equals("int") || calssName.equals("java.lang.Integer")) {
				if (Integer.MAX_VALUE >  new Integer("" + fileValue)) {
					Integer val = new Integer("" + fileValue);
					Method method = thisClass.getMethod("set" + fileName.substring(0, 1).toUpperCase() + fileName.substring(1), field.getType());
					method.invoke(po, val);
					return true;
				}else{
					throw new RumtimeException();
				}
			}else if(calssName.equals("long") || calssName.equals("java.lang.Long")){
				Long val = new Long("" + fileValue);
				Method method = thisClass.getMethod("set" + fileName.substring(0, 1).toUpperCase() + fileName.substring(1), field.getType());
				method.invoke(po, val);
				return true;
			}else{
				Method method = thisClass.getMethod("set" + fileName.substring(0, 1).toUpperCase() + fileName.substring(1), field.getType());
				method.invoke(po, fileValue);
				return true;
			}
	
		} catch (NoSuchMethodException e) {
			e.printStackTrace();
		} catch (SecurityException e) {
			e.printStackTrace();
		}catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		}
		
		return false;
	}
/**
	 * 将驼峰标识转换为下划线
	 * @param text
	 * @return
	 */
	public static String toTableString(String text){
		if (text==null||"".equals(text.trim())){  
			return "";  
		} 

		StringBuilder sb=new StringBuilder(text);
		int temp=0;//定位
		for(int i=0;i

在DaoImpl实现方法中,都是根据每个方法构造所需的MybatisPo,MybatisPo是传到dao-mapper.xml中sql方法的参数,如下:

public class MybatisPo{
	
	private String pkName;					//主键字段
	
	private String idName;					//对应id名称
	
	private Object pkValue;					//主键值
	
	private String tableName;
	
	private List sqlParms;		            //无值无id 插入单个时的插入列
	
	private List selectSqlParms;                 //无值有id  查询参数列表 

	private List pramList;		            //插入列表值 有值无id
	
	private List> batchPramList;	            //批量插入的时候用到
	
	private Where where;                                //sql条件

	public MybatisPo() {}
	
	public MybatisPo(String pkName,String idName,String tableName,List selectSqlParms,List sqlParms) {
		this.pkName = pkName;
		this.idName = idName;
		this.tableName = tableName;
		this.selectSqlParms = selectSqlParms;
		this.sqlParms = sqlParms;
	}
//省略set/get方法
}

这个类包含下面第3点写到的dao-mapper.xml中构造的通用方法所需的参数。

Sql条件类Where封装了dao-mapper.xml中条件语句,所以在业务方法中需要构造所需的Where来完成自定义条件的查询或更新等功能。Where:

/**
 * 条件类
 * @author Administrator
 *
 */
public class Where {
	private String limit;        //对应mysql的limit语句
	private String orderBy;      //排序条件
	private List list = new ArrayList(); //对应sql语句中where后面的条件
	
	public Where(){}
	/**
	 * 
	 * @param file 字段名        如:name
	 * @param where 条件符号     如:=
	 * @param value 条件值       如:hehe,就相当于想添加一个 name='hehe'的条件
	 */
	public Where(String file, String where, Serializable value){
		file = SqlUtil.toTableString(file);
		WherePo po = new WherePo(file,where,(String)(value+""));
		this.list.add(po);
	}
	//and一个条件,Global.WHERE_AND是一个字符串:"and",下面还有对于的"or"
	public Where and (String file,String where, Serializable value){
		file = SqlUtil.toTableString(file);
		this.list.add(new WherePo(file, where, (String)(value+""), Global.WHERE_AND));
		return this;
	}
	//or 一个条件
	public Where or (String file,String where, Serializable value){
		file = SqlUtil.toTableString(file);
		this.list.add(new WherePo(file, where, (String)(value+""), Global.WHERE_OR));
		return this;
	}
	
	public Where limit(int startNum, int length){
		this.limit = String.format("limit %s,%s", startNum,length);
		return this;
	}
	
	/**
	 * 添加排序规则 order by
	 * @param file 字段
	 * @param sequence 排序规则  desc/asc
	 * @return
	 */
	public Where orderBy(String file,String sequence){
		this.orderBy = "order by ";
		if (sequence == null) {
			sequence = "";
		}
		this.orderBy += String.format("%s %s,", file , sequence);
		return this;
	}
	
	/**
	 * 默认asc排序
	 * @param file
	 * @return
	 */
	public Where orderBy(String fileName){
		fileName = SqlUtil.toTableString(fileName);
		this.orderBy(SqlUtil.toTableString(fileName), Global.SEQ_ASC);
		return this;
	}
}

where后面可跟多个条件,所以每个条件用一个WherePo来表示:

/**
 * 条件实体类
 * @author Administrator
 */
public class WherePo {
	private String relation;//关系 and/or...
	private String file;//字段名
	private String where;//条件
	private String value;//值
	
	public WherePo() {
	}
	
	public WherePo(String file, String where, String value) {
		this.file = file;
		this.where = where;
		this.value = value;
	}
	
	public WherePo(String file, String where, String value,String relation) {
		this.file = file;
		this.where = where;
		this.value = value;
		this.relation = relation;
	}//省略set/get方法
}

在DaoImpl中sqlSessionTemplateASS.insert("add", mybatisPo);就是调用dao-mapper.xml中id为add的方法,传入的参数为mybatisPo,其他的以此类推。接下来我们来看一下dao-mapper.xml如何实现通用。
 

3.dao-mapper.xml映射文件的实现





	
	
	
	
		insert into ${tableName}
		
			${item.file}
		
		values
		
			#{item.value}
		
		;
	

	
	
		insert into ${tableName}
		
			${item.file}
		
		values
		
			
				
					#{item.value}
				
			
		
		;
	

	
	

	
	

	
	
		update ${tableName}
		
			
				${item.file}=#{item.value},
			
		
		
	

	
	
		delete from ${tableName}
		
	

	
	

	
	
		
			
				
					
						
							
								
									
										
											${item.file} ${item.where}
											CONCAT('%',#{item.value},'%')
										
										
											AND ${item.file} ${item.where}
											CONCAT('%',#{item.value},'%')
										
										
											OR ${item.file} ${item.where}
											CONCAT('%',#{item.value},'%')
										
										

										
									
								
								
									
										
											${item.file} ${item.where} #{item.value}
										
										
											AND ${item.file} ${item.where} #{item.value}
										
										
											OR ${item.file} ${item.where} #{item.value}
										
										

										
									
								
							
						
					
				
			
			
				
					${where.orderBy}
				
			
			
				${where.limit}
			
		
		;
	

用户输入的参数都用#{}传入到sql,而一些表名、列名等非用户输入的则用${}直接显示,用这种方法实现通用sql。

4.spring-application.xml配置

还需要在application.xml中做一些配置,然后在web.xml中加载此配置文件:




	
	
		
	

	
		
		
		
		
	
	
	
	
		
		
		
	

	
	

	
	
		
	

到这里所有核心代码就差不多了,接下来简单说一下在运用时的一些例子。

5.一些有涉及到的类

/**
 * 实体类字段约束注解
 * 标有此注解的字段对应数据库中的字段名强制约束为该注解中的name值
 */
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface FieldName {
	String name() default PUBVALUE.FIELD_NAME_DEFAUL_VALUE;
}
/**
 * 标识某个字段不录入数据库中
 * 标识该注解的字段将没有增删改查的功能。
 * @author Administrator
 */
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface TempField {
 
}
/**
 * 标识一个实体类对应数据库表的表名
 * 拥有该注解的PO类执行增删改差的时候将优先使用该注解内的值
 * @author Administrator
 *
 */
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface TableName {
	String name();
}

 

这两个注解是标在实体类属性上的。

 

6.应用

MyBatis增删改查(CURD)通用方法简单实现(防sql注入)_第1张图片MyBatis增删改查(CURD)通用方法简单实现(防sql注入)_第2张图片MyBatis增删改查(CURD)通用方法简单实现(防sql注入)_第3张图片

在这里有一些比较复杂或者其他特殊要求的dao要自己在对于的Dao中实现,这个工具暂时也还没考虑到一些性能特殊要求的实现办法,欢迎一起探讨学习。

你可能感兴趣的:(javaweb)