jdbcTemplate學習(二)


前面講了增加、刪除、更新操作,這節講一下查詢。

查詢操作:

(一)查詢一個值(不需要注入參數)

queryForObject(String sql, Class<T> requiredType);

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

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

public void test() {
        String sql = "select count(*) from test";
        int count = jdbcTemplate.queryForObject(sql, Integer.class);
        
    }

(二)查詢一個值(使用預處理sql,需要注入參數)

queryForObject(String sql, Object[] args, Class<T> requiredType);

public void test(Integer id) {
        String sql = "select name from test where id = ?";
        String name = jdbcTemplate.queryForObject(sql, new Object[]{id}, String.class);
    }

還有如下方式:queryForObject(String sql, Object[] args, int[] argTypes, Class<T> requiredType);

(三)查詢單行記錄,轉換成一個對象(固定sql,不需要參數)

<T> T queryForObject(String sql, RowMapper<T> rowMapper)

public void test() {
        String sql = "select name,age from test where id = 10";
        Customer customer = jdbcTemplate.queryForObject(sql, new RowMapper<Customer>() {

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

(四)查詢單行記錄,轉換成一個對象(預處理sql,需要注入參數)

<T> T queryForObject(String sql, Object[] args, RowMapper<T> 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;
            }
            
        });
    }

也可以使用如下方式:(1)<T> T queryForObject(String sql, Object[] args, int[] argTypes, RowMapper<T> rowMapper);

          (2)<T> T queryForObject(String sql, RowMapper<T> rowMapper, Object... args);

(五)查詢數據庫中一列多行數據,即查詢數據庫中單列數據存入一個list中,方式如下:(固定sql,沒參數)

  (a)List<Map<String, Object>> queryForList(String sql)

           這個方法封裝成map放入list中,key:列名(Oracle數據庫sql執行結果列名默認為大寫,需要小寫用as取別名,別名用雙引號)  value:列的值

public void test() {//如果Oracle用這個sql查詢,返回的列名就是NAME(大寫的),對應Map里面的key就是NAME
        String sql = "select name from test where id > 0";
        //如果用這個sql查詢,返回的列名就是name(小寫的),對應Map里面的key就是name
        String sql2 = "select name as \"name\" from test where id > 0";
        
        List<Map<String, Object>> list = jdbcTemplate.queryForList(sql);//這里用的是第一個sql
    }

  (b)<T> List<T> queryForList(String sql, Class<T> elementType)

           這個方法就是直接將單類型數據存入List中。

      注意:這個T雖然是泛型,但是只支持Integer.class String.class 這種單數據類型的,自己定義的Bean不支持。(所以用來查詢單列數據)

public void test() {
        
        String sql = "select name from test where id > 0";
        List<String> list = jdbcTemplate.queryForList(sql, String.class);
    }

(六)查詢數據庫中一列多行數據,即查詢數據庫中單列數據存入一個list中,方式如下:(預處理sql,需要注入參數)

  (a)<T> List<T> queryForList(String sql, Object[] args, Class<T> elementType)

    注意:這個T雖然是泛型,但是只支持Integer.class String.class 這種單數據類型的,自己定義的Bean不支持。(所以用來查詢單列數據,同前面一個意思,后面不再解釋)

public void test(Integer id) {
        
        String sql = "select name from test where id > ?";
        List<String> list = jdbcTemplate.queryForList(sql, new Object[]{id}, String.class);
    }

  還有如下方式實現:(1)<T> List<T> queryForList(String sql, Object[] args, int[] argTypes, Class<T> elementType);

              (2)<T> List<T> queryForList(String sql, Class<T> elementType, Object... args);

  (b)List<Map<String, Object>> queryForList(String sql, Object... args)

  封裝成map存入List,和之前一樣,要注意Oracle數據庫返回的列名默認是大寫的,如果需要,用別名變小寫。

public void test(Integer id) {
        
        String sql = "select name from test where id > ?";
        List<Map<String, Object>> list = jdbcTemplate.queryForList(sql, new Object[]{id});
    }

  還有一種方式實現:List<Map<String, Object>> queryForList(String sql, Object[] args, int[] argTypes);

(七)查詢多條數據(固定sql,沒有參數)

  (a)<T> List<T> query(String sql, RowMapper<T> rowMapper) 

    每條數據映射為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;
            }
        });
    }

map中的key,value類型根據需要自定義,非常方便。像這種實現RowMapper<T>接口的匿名類,T可以為Map,也可以為自定義的對象類型,如上兩種,根據需要選擇。

  (b) void query(String sql, RowCallbackHandler rch)

   注意:如果使用RowCallbackHandler 回調類,這個方法是沒有返回值的,而是在回調類中將結果放入預先定義的List中,用法如下:

public void test() {
        String sql = "select name,age from test where id > 10";
        
        //局部變量,必須用final修飾,內部類中才能訪問(全局變量不用)
        final 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);
            }
        });
    }

當然,這種方式也可以轉換為map,存入list中,和上面a方式一樣,這里就不詳解了。

  (c)<T> T query(final String sql, final ResultSetExtractor<T> rse)

  ResultSetExtractor使用回調方法extractData(ResultSet rs)提供給用戶整個結果集,讓用戶決定如何處理該結果集。

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

            @Override
            public List<Customer> extractData(ResultSet rs)
                    throws SQLException, DataAccessException {
                List<Customer> result = new ArrayList<Customer>();
                while(rs.next()) {
                    Customer customer = new Customer();
                    customer.setName(rs.getString("name"));
                    customer.setAge(rs.getInt("age"));
                    result.add(customer);
                }
                return result;
            }
        });
    }

同樣也可以轉換為map對象放入list中,如下:

public void test() {
        String sql = "select name,age from test where id > 10";

        List<Map<String, Integer>> list = jdbcTemplate.query(sql, new ResultSetExtractor<List<Map<String, Integer>>>() {

            @Override
            public List<Map<String, Integer>> extractData(ResultSet rs)
                    throws SQLException, DataAccessException {
                List<Map<String, Integer>> result = new ArrayList<Map<String, Integer>>();
                while(rs.next()) {
                    Map<String, Integer> map = new HashMap<String, Integer>();
                    map.put(rs.getString("name"), rs.getInt("age"));
                    result.add(map);
                }
                return result;
            }
        });
    }

   (d)<T> List<T> query(PreparedStatementCreator psc, RowMapper<T> rowMapper)

public void test() {//局部變量,必須用final修飾,內部類中才能訪問(全局變量不用)
        final String sql = "select name,age from test where id > 10";
        
        List<Customer> list = jdbcTemplate.query(new PreparedStatementCreator() {
            
            @Override
            public PreparedStatement createPreparedStatement(Connection conn)
                    throws SQLException {
                PreparedStatement ps = conn.prepareStatement(sql);
         //如果sql是預處理的,需要傳入參數,可以在這里寫jdbc代碼傳入,后面就不列舉這種方法了
return ps; } }, new RowMapper<Customer>() { @Override public Customer mapRow(ResultSet rs, int rowNum) throws SQLException { Customer customer = new Customer(); customer.setAge(rs.getInt("age")); customer.setName(rs.getString("name")); return customer; } }); }

可以將RowMapper換成ResultSetExtractor或者RowCallbackHandler回調類,和前面一樣,因此還有下面兩種方法:

  (1)void query(PreparedStatementCreator psc, RowCallbackHandler rch);

  (2)<T> T query(PreparedStatementCreator psc, ResultSetExtractor<T> rse);

(八)查詢多條數據(預處理sql,需要傳入參數)

  (a)<T> List<T> query(String sql, PreparedStatementSetter pss, RowMapper<T> rowMapper)

public void test(final Integer id) {//參數也是局部變量,也必須用final修飾,內部類中才能訪問(全局變量不用)
        String sql = "select name,age from test where id > ?";
        
        List<Customer> list = jdbcTemplate.query(sql, new PreparedStatementSetter() {
            
            @Override
            public void setValues(PreparedStatement ps)
                    throws SQLException {
                ps.setInt(1, id);
            }
        }, new RowMapper<Customer>() {

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

用RowMapper回調類還有三種方法:

    (1)<T> List<T> query(String sql, Object[] args, int[] argTypes, RowMapper<T> rowMapper);

    (2)<T> List<T> query(String sql, Object[] args, RowMapper<T> rowMapper);

    (3)<T> List<T> query(String sql, RowMapper<T> rowMapper, Object... args);

而如果把回調類換成ResultSetExtractor或者RowCallbackHandler回調類,又有八種方法(像上面一樣各有四種),這里就不舉出來了,和前面用法一致。

 


免責聲明!

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



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