时间:2021-07-01 10:21:17 帮助过:20人阅读
public static void addUserWithKeyHolder(final User user){ final String sql = "insert into jf_user(user_name,user_pwd,user_age) values(?,?,?)"; KeyHolder keyHolder = new GeneratedKeyHolder(); jdbcTemplate.update(new PreparedStatementCreator() { @Override public PreparedStatement createPreparedStatement(Connection con) throws SQLException { PreparedStatement ps = con.prepareStatement(sql); ps.setString(1, user.getUsername()); ps.setString(2, user.getUserpwd()); ps.setString(3, user.getUserage()); return ps; } }, keyHolder); user.setSerialNo(keyHolder.getKey().intValue()); }
如果数据库并发率比较高,如在插入记录后执行查询主键之前,数据库又执行了如果条插入记录,那么通过数据查询语句新增主键值将会只返回最后一条插入的主键值。因此,使用查询语句获取的主键值是不安全的,这也是为什么有些数据库(如Oracle)故意不提供自增键,而是只提供序列的原因,序列强制要求用户在新增记录前,先获取主键值。Oracle通过SELECT <SEQUENCE_NAME>.nextval FROM DUAL获取序列的下一个值。
2.3、批量更改数据
如果需要一次性插入或更新多条记录,可以使用jdbcTemplate的batchUpdate方法
batchUpdate示例:
public static void addUsers(final List<User> users){ final String sql = "insert into jf_user(user_name,user_pwd,user_age) values(?,?,?)"; jdbcTemplate.batchUpdate(sql, new BatchPreparedStatementSetter() { @Override public void setValues(PreparedStatement ps, int i) throws SQLException { // TODO Auto-generated method stub User user = users.get(i); ps.setString(1, user.getUsername()); ps.setString(2, user.getUserpwd()); ps.setString(3, user.getUserage()); } @Override public int getBatchSize() { // TODO Auto-generated method stub return users.size(); } }); }
2.4、查询数据
2.4.1、使用RowCallbackHandler处理结果集
Spring提供了org.springframework.jdbc.core.RowCallbackHandler回调接口,通过该接口可以定义如何从结果集中获取数据。
RowCallbackHandler示例:
/** * @Title: getUserBySerialNo * @Description: TODO 获取单个结果集 * @param @param serialNo * @param @return 设定文件 * @return User 返回类型 * @throws */ public User getUserBySerialNo(final int serialNo){ String sql = "SELECT serial_no,user_name,user_pwd,user_age FROM jf_user.jf_users WHERE serial_no = ?"; final User user = new User(); jdbcTemplate.query(sql, new Object[]{serialNo},new RowCallbackHandler() { @Override public void processRow(ResultSet rs) throws SQLException { user.setSerialNo(serialNo); user.setUsername(rs.getString("user_name")); user.setUserpwd(rs.getString("user_pwd")); user.setUserage(rs.getString("user_age")); } }); return user; } /** * @Title: getUsers * @Description: TODO 获取多个结果集 * @param @param fromSerialNo * @param @param toSerialNo * @param @return 设定文件 * @return List<User> 返回类型 * @throws */ public List<User> getUsers(final int fromSerialNo,final int toSerialNo){ String sql = "SELECT serial_no,user_name,user_pwd,user_age FROM jf_user.jf_users WHERE serial_no between ? and ?"; final List<User> users = new ArrayList<>(); jdbcTemplate.query(sql, new Object[]{fromSerialNo,toSerialNo}, new RowCallbackHandler() { @Override public void processRow(ResultSet rs) throws SQLException { // TODO Auto-generated method stub User user = new User(); user.setSerialNo(rs.getInt("serial_no")); user.setUsername(rs.getString("user_name")); user.setUserpwd(rs.getString("user_pwd")); user.setUserage(rs.getString("user_age")); users.add(user); } }); return users; }
2.4.2、使用RowMapper<T>处理结果集
Spring也提供了一个和RowCallbackHandler功能类似的RowMapper<T>接口,它也可以使用RowMapper<T>定义结果集逻辑映射,在结果集为多行记录时,该接口更容易使用。
RowMapper<T>代码示例
/** * @Title: getUsersOnRowMapper * @Description: TODO 利用RowMapper<T>映射多行数据 * @param @param fromSerialNo * @param @param toSerialNo * @param @return 设定文件 * @return List<User> 返回类型 * @throws */ public List<User> getUsersOnRowMapper(final int fromSerialNo,final int toSerialNo){ String sql = "SELECT serial_no,user_name,user_pwd,user_age FROM jf_user.jf_users WHERE serial_no between ? and ?"; return jdbcTemplate.query(sql, new Object[]{fromSerialNo,toSerialNo},new RowMapper<User>(){ @Override public User mapRow(ResultSet rs, int rowNum) throws SQLException { // TODO Auto-generated method stub User user = new User(); user.setSerialNo(rs.getInt("serial_no")); user.setUsername(rs.getString("user_name")); user.setUserpwd(rs.getString("user_pwd")); user.setUserage(rs.getString("user_age")); return user; } }); }
2.5、查询单值数据
如果查询的结果集仅有一个值,如SELECT COUNT(*) FROM jf_users等,就可以使用更简单的方式获取结果的值。JdbcTemplate为获取结果集中的单值数据提供了3组方法,分别用于获取int、long的单值,其他类型的单值以Object类型返回
2.6、调用存储过程
JdbcTemplate提供了2个调用存储过程的接口方法:
<T> T execute(String callString,CallableStatementCallback<T> action);
<T> T execute(CallableStatementCreator csc,CallableStatementCallback<T> cs);
调用存储过程示例:
CREATE PROCEDURE P_GET_VIEW_POINT_NUM(IN in_serialNO,INT,OUT out_num INT) BEGIN SELECT COUNT(*) INTO out_num FROM jf_user WHERE serialNO = in_serialNo; END;
/** * @Title: getUserCounts * @Description: TODO JdbcTemplate调用存储过程 * @param @param serailNo * @param @return 设定文件 * @return int 返回类型 * @throws */ public int getUserCounts(final int serailNo){ String sql = "{call P_GET_VIEW_POINT_NUM(?,?)}"; String execute = jdbcTemplate.execute(sql, new CallableStatementCallback() { @Override public Object doInCallableStatement(final CallableStatement cs) throws SQLException, DataAccessException { // TODO Auto-generated method stub cs.setInt(1, serailNo); cs.registerOutParameter(2, Types.INTEGER); cs.execute(); return cs.getInt(2); } }); return Integer.valueOf(execute); }
本文出自 “阿酷博客源” 博客,请务必保留此出处http://aku28907.blog.51cto.com/5668513/1820917
Spring JDBC 访问数据库
标签:spring jdbc jdbctemplate 数据库