@InsertProvider 根据bean属性,自动生成插入sql语句
以Test为例,用mybatis的@InsertProvider的注解插入数据的时候,每次都要写类似于
Mapper类
@Mapper
public interface TestDao { @InsertProvider(type = TestSqlProvider.class,method="insertAll")
public void insertOrderLine(@Param("list")List<Test> list); }
SqlProvider方法
public String insertAll(Map map) {
List<Test> list = (List<Test>) maop.get("list");
StringBuilder sb = new StringBuilder();
sb.append("INSERT INTO TEST");
sb.append("(PKEY,NAME,AGE,SEX");
sb.append("VALUES");
MessageFormat mf = new MessageFormat(
"#'{'list[{0}].pkey},#'{'list[{0}].name},#'{'list[{0}].age},#'{''list[{0}].sex}");
for (int i = ; i < list.size(); i++) {
sb.append(mf.format(new Object[] { i }));
if (i < list.size() - )
sb.append(",");
}
return sb.toSting();
}
这种方式的话,写法很繁琐,如果字段多,就特别麻烦。所以我在想可不可以通过一种比较通用化的方式,生成插入语句。
方式:
用一个注解的形式,记录字段对应的数据库列名
注解类:
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Columns {
String value();//字段名
String comment() default "";//注释
}
在Test类的字段中加上@Columns注解
例如:
@Columns(value = "PKEY",comment = "主键")
protected Integer pkey;//主键
然后写一个工具类,通过反射生成插入语句
方法:
public static String getInsertSql(Class<?> clas,int size) {
String tableName = SCHEMAS + "." + underscoreName(clas.getSimpleName());
List<Field> fieldList = getSuperFields(clas);
StringBuilder insertTable = new StringBuilder();
insertTable.append("INSERT INTO ");
insertTable.append(tableName);
StringBuilder columnsStr = new StringBuilder("(");
StringBuilder valuesStr = new StringBuilder("(");
for (int i = ; i < fieldList.size(); i++) {
fieldList.get(i).setAccessible(true);
Columns columns = fieldList.get(i).getAnnotation(Columns.class);
if (columns != null) {
columnsStr.append(columns.value());
}
String fieldName = fieldList.get(i).getName();
if (fieldName.equals("pkey")) {//db2自定生成自增主键的方式,也可以uuid
valuesStr.append("default");
}else {
valuesStr.append("#'{'list[{0}].").append(fieldName).append("}");
}
if (i < fieldList.size() - ) {
valuesStr.append(",");
columnsStr.append(",");
}
}
columnsStr.append(")");
valuesStr.append(")");
StringBuilder sql = new StringBuilder();
sql.append(insertTable).append(columnsStr).append("VALUES");
MessageFormat mf = new MessageFormat(valuesStr.toString());
for (int i = ; i < size; i++) {
sql.append(mf.format(new Object[] { i }));
if (i < size - ) {
sql.append(",");
}
}
return sql.toString();
}
// 驼峰转大写+下划线,abcAbcaBc->ABC_ABCA_BC
public static String underscoreName(String name) {
StringBuilder result = new StringBuilder();
if ((name != null) && (name.length() > )) {
result.append(name.substring(, ).toUpperCase());
for (int i = ; i < name.length(); i++) {
String s = name.substring(i, i + );
if ((s.equals(s.toUpperCase())) && (!Character.isDigit(s.charAt()))) {
result.append("_");
}
result.append(s.toUpperCase());
}
}
System.err.println("underscoreName:" + result.toString());
return result.toString();
}
/**
*
* <p>Title: getSuperFields</p>
* <p>Description:获取所有属性,包含父类</p>
* @param clas
* @return
*/
public static List<Field> getSuperFields(Class<? extends BeanBase> clas) {
List<Field> fieldList = new ArrayList<>() ;
while (clas != null) {//取父类属性
fieldList.addAll(Arrays.asList(clas .getDeclaredFields()));
clas = (Class<? extends BeanBase>) clas.getSuperclass(); //父类
}
return fieldList;
}
insetAll的写法
public String insertAll(Map map) {
List<Test> list = (List<Test>) map.get("list");
String insertSql = BeanUtils.getInsertSql(Test.class, list.size());
return insertSql;
}
到此就完成了自动化方法,这个只是粗劣的写一下,希望各位看过的大佬,指出不足
@InsertProvider 根据bean属性,自动生成插入sql语句的更多相关文章
- Entity Framewrok 7beta7中不同版本sql server自动生成分页sql语句的问题
在EF中,使用linq进行分页是很方便的,假如我们有一个EMP表,结构如下: public class Emp { [Key] public Guid No { get; set; } public ...
- 一个自动生成插入与更新SQL语句的小类
无需关注字段类型,只要传入字段名与值的集合,自动生成Ms sql server SQL语句.详见Test()方法 using System; namespace Fan.iData.SqlUtilit ...
- 仿Orm 自动生成分页SQL
分页的写法 自从用上了Orm,分页这种事就是腰不酸腿不痛了.不过有时候想用纯粹的ado.net来操作,希望返回的数据是原生的DataTable或DbDataReader类似的东西,故研究下怎么生成分页 ...
- 【转】Hibernate利用@DynamicInsert和@DynamicUpdate生成动态SQL语句
原文链接:http://www.cnblogs.com/quanyongan/p/3152290.html 最近在使用Hibernate4中,发现两个很有奥秘的注解 @DynamicInsert 和 ...
- Hibernate利用@DynamicInsert和@DynamicUpdate生成动态SQL语句
最近在使用Hibernate4中,发现两个很有奥秘的注解 @DynamicInsert 和 @DynamicUpdate 如果是在配置文件的话那就是dynamic -insert 和 dynamic- ...
- .NET Core实用技巧(一)如何将EF Core生成的SQL语句显示在控制台中
目录 .NET Core实用技巧(一)如何将EF Core生成的SQL语句显示在控制台中 前言 笔者最近在开发和维护一个.NET Core项目,其中使用几个非常有意思的.NET Core相关的扩展,在 ...
- .net core 利用日志查看ef生成的SQL语句
EF Core 没有直接提供像 EF6 那样方便的在日志中记录最终生成的 SQL 的功能,可以通过官方提供的日志记录(Microsoft.Extensions.Logging)实现. 一. 使用 Mi ...
- 深入理解 LINQ to SQL 生成的 SQL 语句
Ø 简介 在 C# 中与数据交互最常用的语句就是 LINQ 了,而 LINQ to SQL 是最直接与数据库打交道的语句,它可以根据 LINQ 语法生成对应的 SQL 语句,在数据库中去执行.本文主 ...
- oracle问题:新建了一个PDM文件,建表后生成的sql语句中含有clustered
问题描述 为了在oracle中新增表,在PDM中建表,使用其生成的sql语句,但是建表不能成功,提示 ORA-00906: 缺失左括号 原因是多了clustered 关键字 情景重现 1. 新建一个p ...
随机推荐
- odoo10 fields.Selection 根据权限显示不同的selection内容
摘要:一般作为下拉选项,selection的选项内容是固定,针对一些特殊要求,根据权限组显示不同的selection内容的,可以参考odoo源码的. 前提:基于 odoo10.0 的源码 参考源码1: ...
- 1008: ASCII码
题目描述 相信大家一定都知道大名鼎鼎的ASCII码,这次给你的任务是输入数字(表示ASCII码),输出相对应的字符信息. 输入 第一行为一个整数T(1<=T<=1000).接下来包括T个正 ...
- web前端常用的封装方法
1.放大镜 //页面加载完毕后执行 window.onload = function () { var oDemo = document.getElementById('demo'); var oMa ...
- laravel富文本编辑和图片上传
---恢复内容开始--- 首先先找到一个适合的编辑器是胜利的一步,选择wangEditor这个编辑器 地址:http://www.wangeditor.com/ 然后选择下载,我是通过网上学习的,所以 ...
- LIN总线协议
汽车电子类的IC有的采用LIN协议来烧录内部NVM,如英飞凌的TLE8880N和博世的CR665D. LIN总线帧格式如下,一个LIN信息帧有同步间隔.同步域.标示符域(PID域).数据域.校验码域. ...
- LeetCode(2)Add Two Numbers
题目: You are given two linked lists representing two non-negative numbers. The digits are stored in r ...
- 在web中绘制图像 -- canvas篇
汗,不小心点击发布了.其实正在编辑中...... HTML Canvas是现代浏览器中非常棒的绘图技术,Canvas可以绘制图形,操作图片,制作游戏,创建动画等:Canvas是很容易使用的,下面我们来 ...
- DDL、DML、DCL、DQL的理解
DDL.DML 和 DCL 的理解 DDL(data definition language)数据库定义语言 的主要语句(操作) Create 语句:可以创建数据库和数据库的一些对象. Drop 语句 ...
- js的undefined怎么判断
window.undefined=window.undefined 如何理解呢?百度搜索:window.undefined=window.undefined 博客说是为了兼容老浏览器. 技巧: 调试时 ...
- 九度oj 题目1185:特殊排序
题目描述: 输入一系列整数,将其中最大的数挑出,并将剩下的数进行排序. 输入: 输入第一行包括1个整数N,1<=N<=1000,代表输入数据的个数. 接下来的一行有N个整数. 输出: 可能 ...