一、前言

本次实际应用中,使用到了如下几个要点:

mysql的动态建表;

mysql的多表插入;

mysql的多表更新;

mysql的多表删除;

二、使用场景

2.1 动态建表

要求建立多个表,例如电压、电流等表,这些表的字段是完全一样的,只有表名不一样,那么我们就可以把表名等字段放在基准表中,然后从基准表中获得所有的表名字段,以list的形式传入mybatis中,进行循环动态拼接创建。

void createTelemetryTable(List list);

复制代码

CREATE TABLE if not exists `${item}` (

sys_id bigint NOT NULL,

mpnt_id bigint NOT NULL,

data_date DATE NOT NULL,

data_point int NOT NULL,

data_item_id bigint NOT NULL,

val DECIMAL(10,2) NOT NULL,

KEY `${item}_sys_id` (`sys_id`),

KEY `${item}_mpnt_id` (`mpnt_id`),

KEY `${item}_data_date` (`data_date`),

KEY `${item}_data_point` (`data_point`),

KEY `${item}_data_item_id` (`data_item_id`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

复制代码

部分截图如下:

2.2 多表批量插入

应用场景就是实际使用中,拿到一批数据,然后这批数据对应到多个不同表,那么最好的方式就是通过map映射,例如:Map>。那么这时候就需要自己来写动态sql了。

其中需要了解的两个mybatis注解就是:@Insert 和@InsertProvider 都是用来在实体类的Mapper类中的注解保存方法的SQL语句。区别就是@Insert是直接配置sql语句,而@InsertProvider则是通过sql工厂类及对应的方法生产sql语句,这种方法的好处就是可以写出更为复杂的sql。

@InsertProvider的注解方式为:

@InsertProvider(type = BaseMapperEnhanceImpl.class,method = "insertCalBatchTable")

void insertBatch(@Param("tables") Map> ycTable);

复制代码

说明:type指明sql工厂类,method是工厂类里对应的方法。

多表批量插入的代码如下:

/**

* 计算服务的批量插入:参数名称必须传 list ,例 @Param("list")

**/

public String insertCalBatchTable(Map map){

Map table = (Map) map.get("tables");

String sql = table.keySet().stream().map(i -> insertBatch((Collection) table.get(i),i)).collect(Collectors.joining());

return sql;

}

/**

* 计算服务批量插入

**/

private String insertBatch(Collection col,String table){

if(CollectionUtil.isEmpty(col)){

throw new RuntimeException("saveAll parameter size is zero or null");

}

Object t = null;

ArrayList list;

if(col instanceof List){

list = (ArrayList) col;

t = list.get(0);

}else{

throw new RuntimeException("Only list or set types are allowed");

}

Class cls = t.getClass();

Field[] fields = cls.getDeclaredFields();

StringBuffer sql = new StringBuffer();

sql.append("INSERT INTO `"+table+"` ");

sql.append("(");

for (Field field :fields) {

field.setAccessible(true);

TableField tableField = field.getAnnotation(TableField.class);

if(ObjectUtil.isNotNull(tableField)){

sql.append(tableField.value()+",");

}

}

sql.delete(sql.length()-1,sql.length());

sql.append(") VALUES ");

for (int i = 0; i < list.size(); i++) {

sql.append(list.get(i).toString());

if (i < list.size() - 1) {

sql.append(",");

}

}

sql.append(";");

return sql.toString();

}

复制代码

说明:可以看下这个插入对象的实体类:需要在待插入的字段上加上@TableField注解,然后通过重写toString来获取sql的插入语句:然后sql会自动把这些值给拼接上去。最后通过这个注解将这条动态语句插入到数据库中。

@Override

public String toString() {

return "("+this.getSysId()+","+this.getMpntId()+",'"+this.getDataDate()+"',"+this.getDataPoint()+","+ this.getDataItemId()+","+ this.getVal()+")";

}

复制代码

2.3 多表批量更新

应用场景与上同理,对多个表进行批量更新。传参形式依旧为如下:Map>。同理,在实体类中写了个获取update sql的方法:

@Data

@NoArgsConstructor

public class CalcDateCurve {

@TableField(value = "sys_id")

private long sysId;

@TableField(value = "mpnt_id")

private long mpntId;

@TableField(value = "data_date")

private Date dataDate;

@TableField(value = "data_point")

private Integer dataPoint;

@TableField(value = "data_item_id")

private long dataItemId;

@TableField(value = "val")

private BigDecimal val;

private String key;

@Override

public String toString() {

return "("+this.getSysId()+","+this.getMpntId()+",'"+this.getDataDate()+"',"+this.getDataPoint()+","+ this.getDataItemId()+","+ this.getVal()+")";

}

public String updateSql() {

return "val ="+this.getVal()+" where sys_id="+this.getSysId() +" and mpnt_id="+this.getMpntId() +" and data_date = '"+this.getDataDate()+"' and data_point="+this.getDataPoint()+" and data_item_id="+this.getDataItemId() ;

}

}

复制代码

mapper 层:

@UpdateProvider(type = BaseMapperEnhanceImpl.class,method = "updateCalBatchTable")

void updateBatch(@Param("tables") Map> ycTable);

复制代码

工厂类方法:

/**

* 计算服务的批量更新

**/

private String updateBatch(Collection col,String table) {

if(CollectionUtil.isEmpty(col)){

throw new RuntimeException("saveAll parameter size is zero or null");

}

Object t = null;

ArrayList list;

if(col instanceof List){

list = (ArrayList) col;

t = list.get(0);

}else{

throw new RuntimeException("Only list or set types are allowed");

}

Class cls = t.getClass();

Field[] fields = cls.getDeclaredFields();

StringBuffer sql = new StringBuffer();

for (int i = 0; i < list.size(); i++) {

try {

sql.append("UPDATE `"+table+"` SET ");

sql.append(list.get(i).getClass().getDeclaredMethod("updateSql").invoke(t));

} catch (NoSuchMethodException e) {

e.printStackTrace();

} catch (IllegalAccessException e) {

e.printStackTrace();

} catch (InvocationTargetException e) {

e.printStackTrace();

}

}

sql.append(";");

return sql.toString();

}

复制代码

说明:这块用到了反射该类来获取该类的某个方法,也是自己在项目中第一次用到反射的东西。

2.4 批量删除表

这个小玩意也记录下来,手动去清除表:查出所有语句遍历执行也是可以改进的。

Select CONCAT( 'drop table ', table_name, ';' )

FROM information_schema.tables

Where table_name LIKE 'calc%';

复制代码

mysql动态sql是什么,mysql中动态sql的一次实际应用相关推荐

  1. java mysql查询字段换行,java类中写sql语句,查询条件包含换行

    java类中写sql语句,查询条件包含换行 detachedCriteria.add(Restrictions.or( Restrictions.like("chengBanDanWeiId ...

  2. phpmyadmin执行mysql语句_如何在phpMyAdmin中执行sql语句

    大家使用phpMyAdmin中常遇到这样的问题:MySQL Error Message: MySQL Query Error SQL: SELECT main.*, field.* FROM ucho ...

  3. mysql中sql插入时间_mysql中使用sql语句插入日期时间类型的写法

    [例子如下: select * from ( select rownumber() over() as rownumber, id from associate ) as temp where row ...

  4. php mysql防注入字符串过滤_php中防止SQL注入的方法

    最好对magic_quotes_gpc已经开放的情况下,还是对$_POST['lastname']进行检查一下. 再说下mysql_real_escape_string和mysql_escape_st ...

  5. php动态创建变量名,PHP中动态创建变量名(可变变量)

    PHP中,我们可以动态地创建一个变量名.例如,你想要使用与数据库查询得到的字段名称一致的变量名. 使用PHP中"可变变量"的语法,即在一个其值为你想作为变量名称的变量前面加一个$: ...

  6. sql 时间范围查询_Excel中使用SQL查询,单元格范围最多支持65536行?

    1.先建立一个excel,本人的版本为2016 2.然后向下填充数字,操作为填充--序列 这样生成1-66666的序列 3.使用SQL查询语句,进行查询 使用语句 : select 序列 from [ ...

  7. access oracle sql语句,在 Access 中使用 SQL 建索引

    时 间:2017-12-29 08:30:39 作 者:摘 要:  一般在Oracle中使用Sql,在Access中使用很少,不过与Oracle的Sql还是有很多相似之处的.以下SQL语句在ACCES ...

  8. mysql 设计动态字段_数据库设计中动态列的设计方法

    问题提出: 在进行数据库开发过程中,我们往往会碰到这种情形: 如在劳资计算中,对每个人有很多薪酬项目需要汇总计算出工资,如基本工资,计件工资,计时工资,奖金,补贴,代扣等等,但我们在建表的过程中既不能 ...

  9. mysql 反斜杠 转义_MySQL中执行sql语句反斜杠需要进行转义

    最近在执行一个sql备份的还原后,发现系统的部分路径找不到,于是开始debug,最后发现,是由于备份的sql语句在还原时,反斜杠(\)被mysql吃掉了.本文对反斜杠和顺斜杠进行了测试,并给出了解决方 ...

  10. jQuery可以查MySQL吗,我们可以在JQuery中执行SQL查询吗

    can we execute mySQL queries in jQuery Calllback functions & misc. functions like simple query U ...

最新文章

  1. C++ Opencv 读取指定路径中的所有文件(图片)及指定路径中指定格式的所有文件(图片)
  2. linux内核分两种,Linux内核版本
  3. Java 8 StampedLocks与ReadWriteLocks和同步
  4. html5情人节贺卡,Web工程师的情人节卡片
  5. Day7 子类调用父类的方法supper 绑定方法与非绑定方法
  6. python前端调用后端模型_前端调用后端的方法(基于restful接口的mvc架构)
  7. 大白话 设计模式之虚拟工厂
  8. EqualLogic强势增长,戴尔领跑iSCSI中国及香港地区市场
  9. 如何监控 Tomcat?Zabbix 与 Cloud Insight 对比
  10. 【小5聊】重装系统之台式电脑BIOSTAR映泰主板,启动U盘PE系统以及重装后无法启动情况
  11. Rplidar学习(四)—— ROS下进行rplidar雷达数据采集源码分析
  12. SD和SDHC和SDXC卡的区别, class与u1/u3关系
  13. android mov转mp4格式转换,如何在线将MOV文件转换成MP4文件?
  14. 引用次数在15000次以上的都是什么神仙论文?
  15. (附源码)计算机毕业设计ssm红色景点自驾游网站管理系统
  16. 思维导图软件XMind破解版下载地址 附最简安装教程
  17. 科学计算机怎么解一元一次方程,解一元一次方程“八不要”
  18. window10 男装linux,男人帮男装购物app-男人帮手机版下载v2.3.5-Linux公社
  19. Android架构之高可用移动网络连接
  20. 虚拟偶像 “造星” 指南,二次元、超写实、智能驱动,你会粉上谁?

热门文章

  1. linux驱动静态分配内存,Linux驱动设计——内存与IO访问
  2. Eclipse中要导出jar包中引用了第三方jar包怎么办
  3. java 类 request_java普通类得到request对象
  4. vue 兄弟组件之间的传值
  5. 少儿编程150讲轻松学Scratch(三)-关卡类游戏《鱼塘》
  6. ipad2018编写html,IT教程:ipad6是ipad2018吗
  7. u32转换bool类型_4.29.类型转换
  8. 【APICloud系列|7】开发一个APP完整流程及注意事项
  9. graph面板x轴模式包括哪些_发那科数控车床面板讲解
  10. linux 秒数转时间格式,通过delphi将秒数转换成日期格式