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;
 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM