zoukankan      html  css  js  c++  java
  • Spring JdbcTemplate使用别名传参(NamedParameterJdbcTemplate)

    原文地址http://www.voidcn.com/article/p-cwqegtpg-hx.html

    在使用JdbcTemplate时,一般传参都是用的?来绑定参数,但是对于某种情况就不适用了,例如Sql中如果存在IN,那么写SQL的时候就会比较麻烦,例如,咱们要查ID在某个范围内的数据,一般情况下咱们这么写:

    List<String> ids = new ArrayList<String>();
    ids.add("id1");
    ids.add("id2");
    ids.add("id3");
    String sql = "SELECT * FROM TEST WHERE ID IN(";
    for(int i = 0; i<ids.size();i++){
        sql+="?";
        if(i!=ids.size()){
            sql+=",";
        }
    }
    sql+=")";
    List result = getJdbcTemplate.queryForList(sql, ids.toArray());

    这里需要提到的类就是NamedParameterJdbcTemplate,他是Spring给开发者提供的一个基于JdbcTemplate的类,他支持命名参数特性。包含了JdbcTemplate中的大部分方法,主要有三类:execute方法、query及queryForXXX方法、update及batchUpdate方法。

    咱们可以看一个由NamedParameterJdbcTemplate完成的上述例子:

    List<String> ids = new ArrayList<String>();
    ids.add("id1");
    ids.add("id2");
    ids.add("id3");
    String sql = "SELECT * FROM TEST WHERE ID IN(:ids)";
    Map params = new HashMap();
    params.addValue("ids", ids);
    NamedParameterJdbcTemplate jdbcTemplate = null;
    jdbcTemplate = new NamedParameterJdbcTemplate(getJdbcTemplate());
    List reslut = jdbcTemplate.query(sql, params);

    可以看到Sql中的参数可以用 :[name] 的方式书写,在执行之前,所有的参数可以放在一个Map中,key为Sql中的参数名,这样的话,就简化了咱们自己拼写Sql的工作量。
    其实,这只是NamedParameterJdbcTemplate的好处之一,另一个好处就是,对于同一个参数,多次出现在一条sql中时,也很好处理。
    例如咱们要查一个数据,传入的时间参数要在字段F1和字段F2之间。那么可以这么写:

    String sql = "SELECT * FROM TEST WHERE F1>:time and F2<:time";
    Map params = new HashMap();
    params.addValue("time", new Date());
    NamedParameterJdbcTemplate jdbcTemplate = null;
    jdbcTemplate = new NamedParameterJdbcTemplate(getJdbcTemplate());
    List reslut = jdbcTemplate.query(sql, params);

    上面咱们利用NamedParameterJdbcTemplate查询时,是将所有参数放入到了一个Map中,其实NamedParameterJdbcTemplate为咱们提供的参数模型不止Map。还有SqlParameterSource和BeanPropertySqlParameterSource。
    其中SqlParameterSource和咱们用Map一样,他只是对Map进行了封装。
    而BeanPropertySqlParameterSource封装了一个JavaBean对象,通过JavaBean对象属性来决定命名参数的值。
    例如咱们创建了一个Bean。

    public class User {  
        private int id;  
        private String userName;
        private String password; 
        //省略getter和setter       
    }

    现在验证一个登录信息是否正确:

    public boolean login(String userName,String password){
        NamedParameterJdbcTemplate namedParameterJdbcTemplate = null;  
        namedParameterJdbcTemplate = new NamedParameterJdbcTemplate(getJdbcTemplate());  
        User user = new User();  
        model.setUserName("jialeens");  
        model.setPassword("hehe");  
        String sql = "SELECT COUNT(1) FROM USER WHERE USERNAME=:userName AND PASSWORD=:password";  
        SqlParameterSource paramSource = new BeanPropertySqlParameterSource(user);  
        int size = namedParameterJdbcTemplate.queryForInt(sql, paramSource);  
        return size==1;
    }

    可以看到,传入的参数是一个对象Bean,Sql在执行时,会根据Sql中的参数名去获取对应Bean中的属性。

    NamedParameterJdbcTemplate内部包含了一个JdbcTemplate,所以JdbcTemplate能做的事情NamedParameterJdbcTemplate都能干; NamedParameterJdbcTemplate相对于JdbcTemplate主要增加了参数可以命名的功能。
    public Object queryForObject(String sql, Map paramMap, RowMapper rowMapper)
    public Object queryForObject(String sql, SqlParameterSource paramSource, RowMapper rowMapper)
    SqlParameterSource的两个主要实现MapSqlParameterSource
    和BeanPropertySqlParameterSource
    public 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();//这样可以得到联合主键的值  
     //keyholder.getKeyList();//这样可以得到一些主主键值,若一次添加好几条记录  
     }
     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;
     }
  • 相关阅读:
    Codeforces Round #494 (Div. 3) D. Coins and Queries (贪心,数学)
    Codeforces Round #645 (Div. 2) D. The Best Vacation (贪心,二分)
    Codeforces Round #481 (Div. 3) F. Mentors (模拟,排序)
    Codeforces Round #646 (Div. 2) B. Subsequence Hate (思维,前缀和)
    windows的类似shell 命令操作 风行天下
    Linux防火墙iptables的策略 风行天下
    HP服务器安装配置教程 风行天下
    zabbix 监控数据库 及 tcp连接数 风行天下
    Linux日志 风行天下
    CENTOS 挂载ntfs移动硬盘 风行天下
  • 原文地址:https://www.cnblogs.com/dyh004/p/11551373.html
Copyright © 2011-2022 走看看