当前位置:Gxlcms > 数据库问题 > Spring JDBC 访问数据库

Spring JDBC 访问数据库

时间:2021-07-01 10:21:17 帮助过:20人阅读

。Spring为KeyHolder接口指代了一个通用的实现类GeneratedKeyHolder,该类返回新增记录时的自增长主键值。假设希望在新增对象后,将主键值加载到对象中,则代码示例

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   数据库   

人气教程排行