前面已經講了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