@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 ...
随机推荐
- Python旅途——入门基础
1.入门 作为近几年计算机程序设计语言中很火的Python,是一种面向对象的动态类型语言,最初被设计用于编写自动化脚本(shell),随着版本的不断更新和语言新功能的添加,越来越多被用于独立的.大 ...
- UIBarButtonSystemItem 样式
使用时需要注意创建方式的区别: 01 typedef enum { 02 UIBarButtonSystemItemDone, 03 UIBarButtonSystemItemCanc ...
- (原)剑指offer变态跳台阶
变态跳台阶 时间限制:1秒空间限制:32768K 题目描述 一只青蛙一次可以跳上1级台阶,也可以跳上2级……它也可以跳上n级.求该青蛙跳上一个n级的台阶总共有多少种跳法. 分析一下明天是个斐波那契 ...
- luogu3809 后缀排序 后缀数组
ref and 挑战程序设计竞赛. 主要是发现自己以前写得代码太难看而且忘光了,而且我字符串死活学不会啊,kmp这种东西我都觉得是省选+难度啊QAQ #include <iostream> ...
- Linux快捷键列表
Linux快捷键列表 快捷键 功能描述 快捷键 功能描述 control+p 查询命令历史纪录的上一条命令 方向上键 查询命令历史纪录的上一条命令 control+n 查询命令历史纪录的下一条命令 方 ...
- 【转】DCOM远程调用权限设置
原文:https://blog.csdn.net/ervinsas/article/details/36424127 最近几天被搞得焦头烂额,由于DCOM客户端程序是在32位系统下开发的,调试时DCO ...
- Flutter 发布APK时进行代码/资源混淆的坑
Flutter 发布APK时进行代码/资源混淆的坑 @author ixenos 1. 关键点 proguard是Java的代码混淆工具,但是当用第三方库的时候,必须要告诉proguard不要检查,因 ...
- 奇奇怪怪的冒泡排序 TOJ 2014: Scramble Sort
粘贴两个特别简单的冒泡排序 2014: Scramble Sort Description In this problem you will be given a series of lists co ...
- 【Android】SharedPreference存储数据
SharedPreference存储数据 使用SharedPreference保存数据 putString(key,value) 使用SharedPreference读取数据 getString( ...
- iOS学习笔记04-视图切换
一.视图切换 UITabBarController (分页控制器) - 平行管理视图 UINavigationController (导航控制器) - 压栈出栈管理视图 模态窗口 二.UITabBar ...