SpringJdbc

深入探讨JdbcTemplate与NamedParameterJdbcTemplate的使用与区别
一、JdbcTemplate 

查询带有参数,和行映射方法:


public Object queryForObject(String sql, Object[] args, RowMapper rowMapper),使用自定义的UserRowMapper完成映射。

一个RowMapper的常用实现BeanPropertyRowMapper,该实现可将结果集转换成一个Java Bean(字段名与Java Bean属性名不符合规范,可用别名处理)。

public List query(String sql, Object[] args, RowMapper rowMapper)返回多个结果。

public int queryForInt(String sql)(如:select count(*) from user),其他结果比如String可用queryForObject方法向下转型。

public Map queryForMap(String sql, Object[] args)返回若类型的Map(key:字段名或别名,value:列值)。

public List queryForList(String sql, Object[] args)返回多Map。

 更新public int update(String sql, Object[] args)。

插入数据并获得结果:

public Object execute(ConnectionCallback action)

其他方法简介

 

public class JdbcTemplateTest {
  // JdbcTemplate是线程安全的
 static JdbcTemplate jdbc = new JdbcTemplate(JdbcUtils.getDataSource());
 public static void main(String[] args) {
  User user = findUser("zhangsan");
  // System.out.println("user:" + user);
  // System.out.println("users:" + findUsers(3));
  // System.out.println("user count:" + getUserCount());
  // System.out.println("user name:" + getUserName(1));
  System.out.println("data:" + getData(1));
 }
 static int addUser(final User user) {
  jdbc.execute(new ConnectionCallback() {
   public Object doInConnection(Connection con) throws SQLException,
     DataAccessException {
    String sql = "insert into user(name,birthday, money) values (?,?,?) ";
    PreparedStatement ps = con.prepareStatement(sql,
      Statement.RETURN_GENERATED_KEYS);
    ps.setString(1, user.getName());
    ps.setDate(2, new java.sql.Date(user.getBirthday().getTime()));
    ps.setFloat(3, user.getMoney());
    ps.executeUpdate();
    ResultSet rs = ps.getGeneratedKeys();
    if (rs.next())
     user.setId(rs.getInt(1));
    return null;
   }
  });
  return 0;
 }
 static Map getData(int id) {
  String sql = "select id as userId, name, money, birthday  from user where id="
    + id;
  return jdbc.queryForMap(sql);
 }
 static String getUserName(int id) {
  String sql = "select name from user where id=" + id;
  Object name = jdbc.queryForObject(sql, String.class);
  return (String) name;
 }
 static int getUserCount() {
  String sql = "select count(*) from user";
  return jdbc.queryForInt(sql);
 }
 static List findUsers(int id) {
  String sql = "select id, name, money, birthday  from user where id<?";
  Object[] args = new Object[] { id };
  int[] argTypes = new int[] { Types.INTEGER };
  List users = jdbc.query(sql, args, argTypes, new BeanPropertyRowMapper(
    User.class));
  return users;
 }
 static User findUser(String name) {
  String sql = "select id, name, money, birthday  from user where name=?";
  Object[] args = new Object[] { name };
   // BeanPropertyRowMapper行映射器,只要查询的字段名与类名一样就行(对于不同的可以使用别名 as xxx),对于不同命名规范它也会进行转化,如它自动将下划线法转化为骆峰法
  Object user = jdbc.queryForObject(sql, args, new BeanPropertyRowMapper(
    User.class));
  return (User) user;
 }
 static User findUser1(String name) {
  String sql = "select id, name, money, birthday  from user where name=?";
  Object[] args = new Object[] { name };
  Object user = jdbc.queryForObject(sql, args, new RowMapper() {
   public Object mapRow(ResultSet rs, int rowNum) throws SQLException {
    User user = new User();
    user.setId(rs.getInt("id"));
    user.setName(rs.getString("name"));
    user.setMoney(rs.getFloat("money"));
    user.setBirthday(rs.getDate("birthday"));
    return user;
   }
  });
  return (User) user;
 }
}

二、NamedParameterJdbcTemplate


lNamedParameterJdbcTemplate内部包含了一个JdbcTemplate,所以JdbcTemplate能做的事情NamedParameterJdbcTemplate都能干; NamedParameterJdbcTemplate相对于JdbcTemplate主要增加了参数可以命名的功能。

lpublic Object queryForObject(String sql, Map paramMap, RowMapper rowMapper)

lpublic Object queryForObject(String sql, SqlParameterSource paramSource, RowMapper rowMapper)

SqlParameterSource的两个主要实现MapSqlParameterSource

和BeanPropertySqlParameterSource

lpublic int update(String sql, SqlParameterSource paramSource, KeyHolder generatedKeyHolder)保存数据获得主键。

 

public class NamedJdbcTemplate {
  // JdbcTemplate是线程安全的
 static JdbcTemplate jdbc = new JdbcTemplate(JdbcUtils.getDataSource());
 static NamedParameterJdbcTemplate named = new NamedParameterJdbcTemplate(
   JdbcUtils.getDataSource());
 public static void main(String[] args) {
  User user=new User();
  user.setMoney(10);
  user.setId(2);
//  System.out.println(findUser(user));
  System.out.println(findUser1(user));
 }
 static void addUser(User user){
  String sql = "insert into user(name,birthday, money) values (:name,:birthday,:money) ";//:后的命名要与列名一致
  SqlParameterSource ps=new BeanPropertySqlParameterSource(user);//从user中取出数据,与sql语句中一一对应将数据换进去
  KeyHolder keyHolder=new GeneratedKeyHolder();
  named.update(sql, ps, keyHolder);
  int id=keyHolder.getKey().intValue();//获得主键
  user.setId(id);
  Map map=keyHolder.getKeys();
 }
 static User findUser1(User user) {
  String sql = "select id, name, money, birthday  from user where money>:money and id<:id";
  SqlParameterSource ps=new BeanPropertySqlParameterSource(user);
  Object u=named.queryForObject(sql, ps, new BeanPropertyRowMapper(User.class));
  return (User) u;
 }
 static User findUser(User user) {
  String sql = "select id, name, money, birthday  from user where money>:m and id<:id";
  Object[] args = new Object[] {user.getName(),user.getMoney(),user.getId() };
  Map params=new HashMap();
  params.put("m", user.getMoney());
  params.put("id", user.getId());
  Object u=named.queryForObject(sql, params, new BeanPropertyRowMapper(User.class));
  return (User) u;
 }

  三、 SimpleJdbcTemplate


SimpleJdbcTemplate内部包含了一个NamedParameterJdbcTemplate;所以NamedParameterJdbcTemplate能做的事情SimpleJdbcTemplate都能干,SimpleJdbcTemplate相对于NamedParameterJdbcTemplate主要增加了JDK5.0的泛型和可变长度参数支持。

public <T> List<T> query(String sql, ParameterizedRowMapper<T> rm, Object... args)

public <T> T queryForObject(String sql, ParameterizedRowMapper<T> rm, SqlParameterSource args)

public <T> List<T> query(String sql, ParameterizedRowMapper<T> rm, SqlParameterSource args)

getJdbcOperations返回的是JdbcOperations(实现JdbcTemplate)

getNamedParameterJdbcOperations返回的是NamedParameterJdbcOperations(实现是NamedParameterJdbcTemplate)

 

public class UserDaoSpringImpl implements UserDao {
 private SimpleJdbcTemplate simpleJdbcTemplate=new SimpleJdbcTemplate(JdbcUtils.getDataSource());
 @Override
 public void addUser(User user) {
  String sql="insert into user (name,money,birthday) value (:name,:money,:birthday)";
  SqlParameterSource param=new BeanPropertySqlParameterSource(user);
  KeyHolder keyHolder=new GeneratedKeyHolder();
  this.simpleJdbcTemplate.getNamedParameterJdbcOperations().update(sql, param, keyHolder);
  user.setId(keyHolder.getKey().intValue());
 }
 @Override
 public User getUser(int userId) {
  String sql="selec id,name,money,birthday from where id=?";
  return this.simpleJdbcTemplate.queryForObject(sql, ParameterizedBeanPropertyRowMapper.newInstance(User.class), userId);
 }
 @Override
 public User findUser(String name, String password) {
  String sql="selec id,name,money,birthday from where name=?";
  return this.simpleJdbcTemplate.queryForObject(sql, ParameterizedBeanPropertyRowMapper.newInstance(User.class), name);
 }
 @Override
 public void update(User user) {
//  String sql="update user set name=?,birthday=?,money=? where id=?";
//  this.simpleJdbcTemplate.update(sql, user.getName(),user.getBirthday(),user.getMoney(),user.getId());
  String sql="update user set name=:name,birthday=:birthday,money=:money where id=:id";
  this.simpleJdbcTemplate.update(sql,new BeanPropertySqlParameterSource(user));
 }
 @Override
 public void delete(User user) {
  String sql="delete from user where id="+user.getId();
  this.simpleJdbcTemplate.update(sql, user.getId());
 }
}

 

 

### Spring JDBC 使用教程 #### JdbcTemplate 类介绍 Spring框架简化了Java数据库连接(JDBC)编程,创建了一个名为`JdbcTemplate`的模板类 `org.springframework.jdbc.core.JdbcTemplate`[^2]。此模板类封装了许多繁琐的任务,比如资源获取和释放、异常处理以及执行SQL语句。 #### 配置 JdbcTemplate 实例 为了使用`JdbcTemplate`, 开发者需先定义一个数据源(`DataSource`)并将其注入到`JdbcTemplate`实例中: ```xml <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource" ref="dataSource"/> </bean> ``` 这段XML配置文件片段展示了如何声明一个`JdbcTemplate` bean, 并通过属性设置关联的数据源对象[^1]。 #### 执行查询操作 利用`JdbcTemplate`可以方便地执行各种类型的SQL命令,包括但不限于SELECT查询: ```java List<Map<String, Object>> rows = jdbcTemplate.queryForList("SELECT * FROM users"); for (Map<String, Object> row : rows){ System.out.println(row); } ``` 上述代码演示了怎样调用`queryForList()`方法来运行一条简单的全表扫描查询,并打印每一行记录的结果集。 ### 常见问题解决方案 当遇到与Spring JDBC有关的问题时,可以从以下几个方面着手排查: - **无法找到驱动程序**: 如果应用程序抛出了类似于“找不到合适的Driver”的错误,则可能是由于缺少必要的JDBC驱动库造成的。确保已将相应的jar包加入classpath路径下。 - **事务管理失败**: 当尝试提交或回滚事务却未达到预期效果时,应检查是否正确设置了传播行为(propagation behavior),并且确认所有的DAO层方法都处于同一个事务上下文中工作[^3]. - **性能优化不足**: 对于大规模读取场景下的低效表现,考虑采用分页加载策略或者批量更新方式提升效率;另外还可以评估一下是否有更好的索引结构可用以加速特定模式下的检索速度[^4].
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值