美文网首页
Spring JdbcTemplate 插入时返回记录的主键

Spring JdbcTemplate 插入时返回记录的主键

作者: 李逍遥JK | 来源:发表于2017-12-20 19:44 被阅读116次

    插入一条记录返回记录的主键,在普通的jdbc操作中实现比较简单

            /**
             * 插入一条记录,并返回主键
             **/
            public Integer addCase(CaseName caseN) {
            Connection conn = null;
            PreparedStatement pst = null;
            ResultSet rest = null;
            String sql = "insert into CaseName(Name,DepID) values(?,?) select SCOPE_IDENTITY()";
    
            Integer row = null;
            try {
                conn = JdbcPool.dataSource.getConnection();
                pst = conn.prepareStatement(sql);
                pst.setString(1, caseN.getName());
                pst.setInt(2, caseN.getDepID());
                row = pst.executeUpdate();
    
                rest = pst.getGeneratedKeys();
                if (rest.next()) {
                    row = rest.getInt(1);
                }
            } catch (SQLException e) {
                e.printStackTrace();
            } finally {
                JdbcUtils.closeConn(conn, pst, null);
            }
    
            return row;
    }
    

    主要是通过sql 语句的select SCOPE_IDENTITY()";和rest = pst.getGeneratedKeys()实现。但是在SpringJdbcTemplate 中执行update语句返回的是表中生效的行数,并不是我们需要的主键

        @Override
        public Integer updateCaseByNode(Integer id, String node) {
            String sql = "update CaseName set Node = ? where ID = ?";
            // 返回 生效 的数据行数
            return jdbcTemplate.update(sql,node, id);
        }
    

    这时问题就变得非常棘手,在网上查阅资料后我总结了下面的两种实现方式
    1.sql语句中包含select SCOPE_IDENTITY()

        /**
         * dao层插入数据的接口实现方法
         * @param caseName
         * @return
         */
        @Override
        public Integer saveCase(CaseName caseName) {
            String sql = "insert into CaseName(Name,DepID) values(?,?) select SCOPE_IDENTITY() ";
            // 调用insertCase
            return insertCase(sql, caseName.getName(), caseName.getDepId()+"");
        }
    
        /**
         * 具体的插入方法
         * @param sql
         * @param caseName
         * @param depId
         * @return
         */
        private Integer insertCase(String sql, String caseName, String depId){
            KeyHolder keyHolder = new GeneratedKeyHolder();
            jdbcTemplate.update(new PreparedStatementCreator() {
                @Override
                public PreparedStatement createPreparedStatement(Connection conn)
                        throws SQLException {
                    // 预处理
                    PreparedStatement ps = conn.prepareStatement(sql);
                    ps.setString(1, caseName);
                    ps.setString(2, depId);
                    return ps;
                }
            }, keyHolder);
            // 返回主键
             System.out.println("插入后数据主键:" + keyHolder.getKey().intValue());
            return  keyHolder.getKey().intValue();
        }
    

    2.sql语句中不含select SCOPE_IDENTITY(),在PrepareStatement参数中加入PreparedStatement.RETURN_GENERATED_KEYS

        /**
         * dao层插入数据的接口实现方法
         * @param caseName
         * @return
         */
        @Override
        public Integer saveCase(CaseName caseName) {
            // 注意sql 和方式1 的区别
            String sql = "insert into CaseName(Name,DepID) values(?,?)  ";
            // 调用insertCase
            return insertCase(sql, caseName.getName(), caseName.getDepId()+"");
        }
    
    
        /**
         * 具体的插入方法
         * @param sql
         * @param caseName
         * @param depId
         * @return
         */
        private Integer insertCase(String sql, String caseName, String depId){
            KeyHolder keyHolder = new GeneratedKeyHolder();
            jdbcTemplate.update(new PreparedStatementCreator() {
                @Override
                public PreparedStatement createPreparedStatement(Connection conn)
                        throws SQLException {
                    // 预处理 注意参数 PreparedStatement.RETURN_GENERATED_KEYS
                    PreparedStatement ps = conn.prepareStatement(sql,PreparedStatement.RETURN_GENERATED_KEYS);
                    ps.setString(1, caseName);
                    ps.setString(2, depId);
                    return ps;
                }
            }, keyHolder);
            // 返回主键
            System.out.println("插入后数据主键:" + keyHolder.getKey().intValue());
            return  keyHolder.getKey().intValue();
        }
    

    效果如下


    图1.png

    以上两种方式,推荐第二种,因为select SCOPE_IDENTITY()在不同的数据库中可能不存在这种语法。

    相关文章

      网友评论

          本文标题:Spring JdbcTemplate 插入时返回记录的主键

          本文链接:https://www.haomeiwen.com/subject/nmrnwxtx.html