沈阳市网站设计制作公司,建设工程监理,汉中市建设工程审批,网络管理服务器一、前言本次实际应用中#xff0c;使用到了如下几个要点#xff1a;mysql的动态建表;mysql的多表插入;mysql的多表更新;mysql的多表删除;二、使用场景2.1 动态建表要求建立多个表#xff0c;例如电压、电流等表#xff0c;这些表的字段是完全一样的#xff0c;只有表名不…一、前言本次实际应用中使用到了如下几个要点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)) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COLLATEutf8mb4_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会自动把这些值给拼接上去。最后通过这个注解将这条动态语句插入到数据库中。Overridepublic String toString() {return (this.getSysId(),this.getMpntId(),this.getDataDate(),this.getDataPoint(), this.getDataItemId(), this.getVal());}复制代码2.3 多表批量更新应用场景与上同理对多个表进行批量更新。传参形式依旧为如下Map。同理在实体类中写了个获取update sql的方法DataNoArgsConstructorpublic 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;Overridepublic String toString() {return (this.getSysId(),this.getMpntId(),this.getDataDate(),this.getDataPoint(), this.getDataItemId(), this.getVal());}public String updateSql() {return val this.getVal() where sys_idthis.getSysId() and mpnt_idthis.getMpntId() and data_date this.getDataDate() and data_pointthis.getDataPoint() and data_item_idthis.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.tablesWhere table_name LIKE calc%;复制代码