Mybatis写mapper时,每个表都需要INSERT UPDATE写很长的语句比较麻烦,80%的表和java bean是简单的一一对应关系,因此考虑使用mybatis的SQLProvider注解减少这部分重复劳动。
SELECT和DELETE语句由于涉及字段较少,写起来还在可接收范围内,所以没做通用的。
也可以把javabean增加写注解,类似JPA那样指定表名、字段名、主键等,但做得太多就失去了mybatis依赖SQL的灵活性了
InsertUpdateSqlProvider.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98
| import java.lang.reflect.Field; import java.util.Date; import java.util.HashMap; import java.util.Map; import org.apache.ibatis.jdbc.SQL;
public class InsertUpdateSqlProvider {
public static String insert(Object obj) { Map<String, String> map; try { map = getFieldsMap(obj, true); } catch (IllegalArgumentException | IllegalAccessException e) { throw new RuntimeException(e); } return new SQL() { { INSERT_INTO(getTableName(obj)); for (String col : map.keySet()) { VALUES(col, map.get(col)); } } }.toString(); } private static String updateById(Object obj, boolean includeNullValueField) { Map<String, String> map; try { map = getFieldsMap(obj, includeNullValueField); map.remove("id"); } catch (IllegalArgumentException | IllegalAccessException e) { throw new RuntimeException(e); } return new SQL() { { UPDATE(getTableName(obj)); for (String col : map.keySet()) { SET(col + "=" + map.get(col)); } WHERE("id = #{id}"); } }.toString(); } public static String updateById(Object obj) { return updateById(obj, true); } public static String updateNonNullById(Object obj) { return updateById(obj, false); } private static Map<String, String> getFieldsMap(Object obj, boolean includeNullValue) throws IllegalArgumentException, IllegalAccessException { HashMap<String, String> result = new HashMap<>(); Class<?> cls = obj.getClass(); Field[] fields = cls.getDeclaredFields(); for (Field f : fields) { String col = f.getName(); String colName = col.substring(0, 1).toUpperCase() + col.substring(1); f.setAccessible(true); try { cls.getMethod("get" + colName); cls.getMethod("set" + colName, f.getType()); } catch (NoSuchMethodException | SecurityException e) { continue; } if ((!"id".equals(col) && includeNullValue) || f.get(obj) != null) { result.put(camelCase2Underscore(col), "#{" + col + "}"); } } return result; } public static String getTableName(Object obj) { return camelCase2Underscore(obj.getClass().getSimpleName()); } public static String camelCase2Underscore(String s) { StringBuffer buf = new StringBuffer(); for (String w : s.split("(?<!(^|[A-Z]))(?=[A-Z])|(?<!^)(?=[A-Z][a-z])")) { buf.append("_").append(w.toLowerCase()); } return buf.substring(1); } }
|
使用通用provider的Mapper类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| import org.apache.ibatis.annotations.InsertProvider; import org.apache.ibatis.annotations.Options; import org.apache.ibatis.annotations.UpdateProvider; import org.springframework.stereotype.Repository; @Repository public interface GenericDao { @UpdateProvider(type=InsertUpdateSqlProvider.class, method="updateById") public int updateById(Object bean); @UpdateProvider(type=InsertUpdateSqlProvider.class, method="updateNonNullById") public int updateNonNullById(Object bean); @Options(useGeneratedKeys=true, keyProperty="id", keyColumn="id") @InsertProvider(type=InsertUpdateSqlProvider.class, method="insert") public int insert(Object bean); @InsertProvider(type=InsertUpdateSqlProvider.class, method="insert") public int insertWithoutGeneratedKey(Object bean); }
|