首先先对这段代码的简单介绍,我之前在需要操作JDBC的时候总是会因为经常要重新写SQL语句感到很麻烦。所以就能拿则拿不能拿的就简单地封装了一下。
首先是Insert。Spring框架的JDBC包里面的.core.包里面的simple包有个SimpleJdbcInsert这样一个类,它给我们带来了很好的对于插入数据的实现。
它只需要我们提供表单名称,和一个Map就可以帮我们轻松把数据放到数据库。
public int insertObject(Map<String, Object> entity, String tableName) { SimpleJdbcInsert insert = new SimpleJdbcInsert(jdbcTemplate); insert.setTableName(tableName); int result = insert.execute(entity); return result; }
这个类里面有个execute方法需要我们穿进去一个Map就能把Map里面的数据插入到数据库了,具体是怎么用的呢?下面我们就来看一下
@Test public void insert() { try { Map<String, Object> entity = new HashMap<>(); entity.put("STU_NAME", "AAA"); entity.put("STU_AGE", 66); entity.put("STU_UPDATE_DATE", new Date()); studentService.insertObject(entity, "tb_student"); } catch (Exception e) { e.printStackTrace(); } }
这是Service层的代码
@Transactional @Override public int insertObject(Map<String, Object> entity, String tableName) { dbDao.insertObject(entity, tableName); return dbDao.insertObject(entity, tableName); }
这样写就可以了。嗯。就这么简单,那···它是怎么实现的呢?
protected int doExecute(Map<String, ?> args) { checkCompiled(); List<Object> values = matchInParameterValuesWithInsertColumns(args); return executeInsertInternal(values); }
这里就是它的excute方法的底层的首层代码。这里可以看到需要我们传入一个HashMap对象,然后通过另外一个类对这个HashMaP进行解析得到一个List的对象数组。
那···这里它又是怎样解析的呢?于是我出于好奇继续对它进行“刨根问底”
public List<Object> matchInParameterValuesWithInsertColumns(Map<String, ?> inParameters) { List<Object> values = new ArrayList<Object>(); Map<String, Object> source = new LinkedHashMap<String, Object>(inParameters.size()); for (String key : inParameters.keySet()) { source.put(key.toLowerCase(), inParameters.get(key)); } for (String column : this.tableColumns) { values.add(source.get(column.toLowerCase())); } return values; }
点进去一看。嗯就是通过matchInParameterValuesWithInsertColumns这个类来实现这个Map解析的。这个实现非常简单就是把我们给他的HashMap转换成LinkHashMap。这样就能把散落在内存各处的数据串成一个有序的HashMap了。
将HashMap的数据统一它们的大小写,之后有序地丢进去这个LinkHashMap。接着通过复杂的算法获得数据库表到底有多少列,接着循环把这个HashMap的数据一个个丢到List里面,接着返回一个对象List。再进行Sql拼接
public String createInsertString(String... generatedKeyNames) { Set<String> keys = new LinkedHashSet<String>(generatedKeyNames.length); for (String key : generatedKeyNames) { keys.add(key.toUpperCase()); } StringBuilder insertStatement = new StringBuilder(); insertStatement.append("INSERT INTO "); if (getSchemaName() != null) { insertStatement.append(getSchemaName()); insertStatement.append("."); } insertStatement.append(getTableName()); insertStatement.append(" ("); int columnCount = 0; for (String columnName : getTableColumns()) { if (!keys.contains(columnName.toUpperCase())) { columnCount++; if (columnCount > 1) { insertStatement.append(", "); } insertStatement.append(columnName); } } insertStatement.append(") VALUES("); if (columnCount < 1) { if (this.generatedKeyColumnsUsed) { logger.info("Unable to locate non-key columns for table ‘" + getTableName() + "‘ so an empty insert statement is generated"); } else { throw new InvalidDataAccessApiUsageException("Unable to locate columns for table ‘" + getTableName() + "‘ so an insert statement can‘t be generated"); } } for (int i = 0; i < columnCount; i++) { if (i > 0) { insertStatement.append(", "); } insertStatement.append("?"); } insertStatement.append(")"); return insertStatement.toString(); }
这里我们可以看到这就是用了一个StringBuilder把Sql的关键字和我们传进去的数据库表的名称,还有表的列名和Values之后的我们需要插入的值。最后把完整的SQL语句再传给数据库的执行对象返回受影响条数的Int类型的结果。
这里得出一个结论,我们在学习的过程中,通道说源代码就感觉是非常高大上的对自己来说是遥不可及的东西,实际上点进去分析一下就可以发现在过往在学校的学习中,我们已经接触过这个知识,只是在用的时候缺乏经验,不知道
如何去在脑海里面把知识点取出来。所以就妨碍了我们在代码上的实现。而且对于学习需要我们拥有一个“刨根问底的心”。心中有了疑问就会不知不觉地去追求这个答案。哪怕最后的结果是个很简单的东西。
最后我发现刚才写的博文中有一段是Spring对于数据库表的字段个数的获取。这是个很强大的功能,看了这个SimpleInsert类之后我发现它非常依赖于这个东西的实现,有了它仿佛就像对数据库的表到底有多少个字段可以瞬间变的了如指掌,
我们知道了数据库有多少个字段就只需要判断SQL里面需要放多少个非空字段的内容进去就可以了,对吧。在这里我就对这个东西产生了兴趣,如果有时间的话下一次发博文可能就会围绕着这个的实现进行开展。最后希望今天写的博文对大家有用。
第一次玩博客,今天被安利了一个很方便JDBC的基于Spring框架的一个叫SimpleInsert的类,现在就来简单介绍一下
原文:https://www.cnblogs.com/DevilNerieruDaiSuki/p/10727001.html