Spring JdbcTemplate 查詢方法詳解

前面已經講了JdbcTemplate的增刪改操作,接下來看一下查詢

查詢操作

(1)<T> T queryForObject(String sql, Class requiredType)
  • 查詢一個值,不需要注入參數

注意:參數requiredType只能是String,Integer這種類型,不能是自定義的實體類型,只能返回一個值,不能映射對象(映射對象下面會說)

sql:預處理sql;requiredType:查詢單列結果的類型;

public void test(Integer id) {
        String sql = "select name from test where id = 1";
        String name = jdbcTemplate.queryForObject(sql, new Object[]{id}, String.class);
    }
(2) <T> T queryForObject(String sql, Object[] args, Class requiredType)
  • 查詢一個值(預處理sql,需要注入參數)
public Integer isExitType(String type_name) {
   String isExitSql = "select type_id from type where type_name = ?";
    //當results爲空時,就會拋出EmptyResultDataAccessException異常,Spring這樣做的目的是爲了防止程序員不對空值進行判斷,保證了程序的健壯性。
    //另外,當results的size大於1時,還會拋出IncorrectResultSizeDataAccessException異常,以保證返回的記錄只有一條。
    //如果我們想查詢結果爲空時,返回null而不是拋出異常,就需要捕獲EmptyResultDataAccessException,然後返回null
    try {
        Integer typeId = template.queryForObject(isExitSql, Integer.class, type_name);
        return typeId;
    } catch (DataAccessException e) {
        return null;
    }
}
(3)<T> T queryForObject(String sql, Object[] args, RowMapper rowMapper)
  • 查詢單行數據,轉換爲一個對象
public void test(Integer id) {//參數也是局部變量,也必須用final修飾,內部類中才能訪問(全局變量不用)
String sql = "select name,age from test where id = ?";
    Customer customer = jdbcTemplate.queryForObject(sql, new Object[]{id}, new RowMapper<Customer>() {

        @Override
        public Customer mapRow(ResultSet rs, int paramInt)
                throws SQLException {
            Customer c = new Customer();
            c.setName(rs.getString("name"));
            c.setAge(rs.getInt("age"));
            return c;
        }
        
    });
}

如果覺得手動實現RowMapper轉爲對象比較麻煩,可以使用BeanPropertyRowMapper,BeanPropertyRowMapper 實現了 RowMapper 接口,寫起來非常簡單:

public Blogger login(Blogger loginUser) {
        String sql = "select * from blogger where name_id = ? and pass = ?";
        try {
            Blogger blogger = template.queryForObject(sql, new BeanPropertyRowMapper<Blogger>(Blogger.class),
                    loginUser.getName_id(), loginUser.getPass());
            return blogger;
        } catch (DataAccessException e) {
            return null;//沒有查詢到會發生異常,捕獲異常之後,沒有查詢到信息就返回null
        }
    }
(4)Map<String, Object> queryForMap(String sql,Object…args)
  • 查詢一行數據,並把查詢到的結果封裝在Map集合中,返回數據多於一行的話會出錯!
 public void test() {
     String sql = "select blogger_id,nick_name from blogger where blogger_id>?";
     Map<String, Object> map = template.queryForMap(sql, 6);
}
(5) <T>List<T> queryForList(String sql, Class elementType)
  • (固定SQL)將單類型數據存入List中
    注意:Class elementType參數只支持這個Integer.class String.class 這種單數據類型的,自己定義的Bean不支持,所以T雖然是泛型,但也只能接受單數據類型的(所以用來查詢單列數據)
public void test(){
    String sql = "select nick_name from blogger where blogger_id >1";
    List<String> strings = template.queryForList(sql, String.class);
}
(6)<T>List<T> queryForList(String sql, Object[] args, Class elementType)
  • (預處理SQL,需要注入參數)與方法(4)相比除了需要注入參數以外,其他方面都一樣
    注意:Class elementType參數只支持這個Integer.class String.class 這種單數據類型的,自己定義的Bean不支持,所以T雖然是泛型,但也只能接受單數據類型的(所以用來查詢單列數據)
public void test(){
    String sql = "select nick_name from blogger where blogger_id >?";
    List<String> strings = template.queryForList(sql, new Object[]{1},String.class);
}
(7)List<Map<String, Object>> queryForList(String sql)
  • 固定SQL,返回多行數據結果,查詢數據庫中多行數據,把把查詢結果封裝爲map存入List中
public void test(){
    String sql = "select * from blogger";
    List<Map<String, Object>> list = template.queryForList(sql);
}
(8)List<Map<String, Object>> queryForList(String sql,Object[] args)
  • 預處理SQL,需要注入參數,把每一行數據封裝在Map裏,然後存入List中
public void test(){
    String sql = "select * from blogger where blogger_id = ?";
    List<Map<String, Object>> list = template.queryForList(sql,new Object[]{2});
}
(9) <T> List<T> query(String sql, RowMapper rowMapper)
  • 固定SQL,把每條數據映射爲Java對象,存入List中
public void test() {
    String sql = "select name,age from test where id > 10";
    List<Customer> list = jdbcTemplate.query(sql, new RowMapper<Customer>() {

        @Override
        public Customer mapRow(ResultSet rs, int rowNum)
                throws SQLException {
            //這裏必須new對象,不能在方法外new,然後用同一個,因爲是一個List,查詢出來多個對象映射,
            //必須保證每一次調用都使用一個新的。
            //如果不new,而是使用同一個對象,會導致存入到List中的都是一樣的對象(都是最後一個對象)。
            Customer customer = new Customer();
            customer.setName(rs.getString("name"));
            customer.setAge(rs.getInt("age"));
            return customer;
        }
    });
}

該方法也可以把每一行數據轉換爲自定義key-value的map對象放入list中,如下:(所以說使用回調類比簡單方法更強大,裏面邏輯自己按需求寫)

public void test() {
    String sql = "select name,age from test where id > 10";
     List<Map<Integer,Object>> list = jdbcTemplate.query(sql, new RowMapper<Map<Integer,Object>>() {

         @Override
         public Map<Integer,Object> mapRow(ResultSet rs, int rowNum)
                 throws SQLException {
             Map<Integer, Object> map = new HashMap<Integer, Object>();
             map.put(rowNum, rs.getString("name"));
             map.put(rowNum, rs.getInt("age"));
             return map;
         }
     });
 }
(10)void query(String sql, RowCallbackHandler rch)
  • 如果使用RowCallbackHandler 回調類,這個方法是沒有返回值的,而是在回調類中將結果放入預先定義的List中,用法如下:
public void test() {
   String sql = "select name,age from test where id > 10";
   
   List<Customer> list = new ArrayList<Customer>();
   jdbcTemplate.query(sql, new RowCallbackHandler() {
       
       @Override
       public void processRow(ResultSet rs) throws SQLException {
           Customer customer = new Customer();
           customer.setName(rs.getString("name"));
           customer.setAge(rs.getInt("age"));
           list.add(customer);
       }
   });
}
(11)
1、<T> List<T> query(String sql, Object[] args, RowMapper rowMapper)
2、<T> List<T> query(String sql, RowMapper rowMapper, @Nullable Object… args)

以上兩種方法都可以實現,預處理SQL,需要注入參數,把數據封裝爲對象存在List中

不同的是參數傳遞:

  • 方法1必須以數組的形式傳遞參數
  • 而方法2的參數傳遞就可以以單個參數傳遞,也可以以數組進行傳遞
public void test() {//局部變量,必須用final修飾,內部類中才能訪問(全局變量不用)
    String sql = "select * from blogger where blogger_id > ? and gender = ?";
    List<Blogger> query1 = template.query(sql, new BeanPropertyRowMapper<Blogger>(Blogger.class), 3,0);
    List<Blogger> query2 = template.query(sql, new Object[]{3,0}, new BeanPropertyRowMapper<Blogger>(Blogger.class));
    //query1與query2的輸出結果是一樣的
}
(12) <T>List<T> query(PreparedStatementCreator psc, RowMapper rowMapper)

固定SQL,使用原始預處理執行SQL,並封裝成對象存入List中

public void test() {
   String sql = "select * from blogger where blogger_id > 1";

    List<Blogger> list = template.query(new PreparedStatementCreator() {
        @Override
        public PreparedStatement createPreparedStatement(Connection connection) throws SQLException {
            PreparedStatement ps = connection.prepareStatement(sql);
            return ps;
        }
    }, new BeanPropertyRowMapper<Blogger>(Blogger.class));
    System.out.println(list);
}

參考博客:
https://www.cnblogs.com/cainiao-Shun666/p/7852305.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章