脱离实体类操作数据库(mysql版本)
原理很简单:
1、利用mysql的information_schema库,获取对用表的信息;
2、使用DataSource,建立数据库连接,并执行sql脚本;
3、Map的keySet和values集合是顺序一致的;
4、" on duplicate key update "这里摸了个鱼,将新增和修改整合在一起了;
直接上代码:
package com.modern.client.core; import cn.hutool.core.map.MapBuilder; import cn.hutool.core.map.MapUtil; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.google.common.collect.Lists; import lombok.SneakyThrows; import org.springframework.util.Assert; import javax.sql.DataSource; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.util.*; import java.util.stream.Collectors; /** * 数据库脱离实体操作助手 */ public class MybatisHelper { /** * 获取所有列 * * @param ds * @param tableName * @return */ @SneakyThrows private static List<String> tableColumns(DataSource ds, String tableName) { Connection connection = ds.getConnection(); try { ResultSet set = connection.prepareCall("select column_name from information_schema.`COLUMNS` where table_name = '" + tableName + "'").executeQuery(); ArrayList<String> list = Lists.newArrayList(); while (set.next()) { list.add(set.getString(1)); } return list; } finally { connection.close(); } } /** * 获取主键 * * @param ds * @param tableName * @return */ @SneakyThrows private static String tablePrimarykey(DataSource ds, String tableName) { Connection connection = ds.getConnection(); try { ResultSet set = connection.prepareCall("select column_name from information_schema.`COLUMNS` where table_name = '" + tableName + "' and COLUMN_key = 'PRI'").executeQuery(); Assert.isTrue(set.next(),"表"+tableName+"未找到主键!"); return set.getString(1); } finally { connection.close(); } } @SneakyThrows private static void callSql(DataSource ds, String sql) { Connection connection = ds.getConnection(); try { connection.prepareCall(sql).execute(); } finally { connection.close(); } } /** * 删除 * * @param ds * @param tableName * @param jsonStr * @throws SQLException */ public static void delete(DataSource ds, String tableName, String jsonStr) throws SQLException { String primarykey = tablePrimarykey(ds, tableName); Assert.notNull(primarykey, "表" + tableName + "无主键,执行删除失败!"); String value = null; JSONObject object = JSON.parseObject(jsonStr); for (Map.Entry<String, Object> entry : object.entrySet()) { if (entry.getKey().equalsIgnoreCase(primarykey.replaceAll("_", ""))) { value = entry.getValue().toString(); break; } } Assert.notNull(value, "表" + tableName + "无主键 值,执行删除失败!"); StringBuilder builder = new StringBuilder(); builder.append(" delete from "); builder.append(tableName); builder.append(" where "); builder.append(primarykey); builder.append(" = "); builder.append("'"); builder.append(value); builder.append("'"); callSql(ds, builder.toString()); } /** * 新增或修改 * * @param ds * @param tableName * @param jsonStr */ public static void insertOrUpdate(DataSource ds, String tableName, String jsonStr) { List<String> columns = tableColumns(ds, tableName); JSONObject object = JSON.parseObject(jsonStr); MapBuilder<Object, Object> mapBuilder = MapUtil.builder(); for (Map.Entry<String, Object> entry : object.entrySet()) { List<String> res = columns.stream().filter(p -> entry.getKey().equalsIgnoreCase(p.replaceAll("_", ""))).collect(Collectors.toList()); if (res.size() <= 0) continue; mapBuilder.put(res.get(0), entry.getValue()); } Map<Object, Object> map = mapBuilder.build(); StringBuilder builder = new StringBuilder(); //insert builder.append(" insert into "); builder.append(tableName); builder.append(keyBunch(map.keySet())); builder.append(" values "); builder.append(valueBunch(map.values())); //update builder.append(updateBunch(map.keySet())); callSql(ds, builder.toString()); } /** * insertOrUpdate 分支 * @param c * @return */ private static String keyBunch(Collection<?> c) { StringBuilder builder = new StringBuilder("("); Iterator<?> iterator = c.iterator(); while (iterator.hasNext()) { builder.append(iterator.next()); if(iterator.hasNext()) builder.append(","); } builder.append(")"); return builder.toString(); } /** * insertOrUpdate 分支 * @param c * @return */ private static String valueBunch(Collection<?> c) { StringBuilder builder = new StringBuilder("("); Iterator<?> iterator = c.iterator(); while (iterator.hasNext()) { builder.append("'"); builder.append(iterator.next().toString()); builder.append("'"); if(iterator.hasNext()) builder.append(","); } builder.append(")"); return builder.toString(); } /** * insertOrUpdate 分支 * @param c * @return */ private static String updateBunch(Collection<?> c) { StringBuilder builder = new StringBuilder(" on duplicate key update "); Iterator<?> iterator = c.iterator(); while (iterator.hasNext()) { Object next = iterator.next(); builder.append(next); builder.append(" =values( "); builder.append(next); builder.append(")"); if(iterator.hasNext()) builder.append(","); } return builder.toString(); } public static void main(String[] args) { Map<String, String> map = MapUtil.builder(new HashMap<String,String>()) .put("id", "1") .put("organization_id", "9") .put("c", "9") .put("d", "9") .put("x", "2024-01-01").build(); StringBuilder builder = new StringBuilder(); //insert builder.append(" insert into "); builder.append("aaaa"); builder.append(keyBunch(map.keySet())); builder.append(" values "); builder.append(valueBunch(map.values())); //update builder.append(updateBunch(map.keySet())); System.out.println("args = " + builder.toString()); } }
最后拼接效果:
INSERT INTO aaaa ( c, d, organization_id, x, id )
VALUES
( '9', '9', '9', '2024-01-01', '1' )
ON DUPLICATE KEY UPDATE c =
VALUES
( c ),
d =
VALUES
( d ),
organization_id =
VALUES
( organization_id ),
x =
VALUES
( x ),
id =
VALUES
(
id
)