SpringJDBC 用法總結

大部分網(wǎng)上的 Spring 教程大多講解的是 SSM 框架展东,其中的 M 現(xiàn)在指的是 MyBatis 這個第三方 ORM 框架,在我看來,MyBatis 有它的優(yōu)越性,如 SQL 語句與業(yè)務代碼分離俊抵,業(yè)務邏輯處理很靈活等。但是在小型業(yè)務系統(tǒng)開發(fā)時坐梯,由于 SSM 框架定義過于規(guī)范徽诲,開發(fā)具體功能時,會寫很多接口吵血,而真正的業(yè)務邏輯得不到較優(yōu)的處理谎替,呆板的框架應用反而適得其反。

本文主要介紹 SpringJDBC 的基礎操作践瓷,方便研發(fā)人員快速的實現(xiàn)數(shù)據(jù)的增刪改查院喜,而不僅僅拘泥于繁重的、各種框架組合而成的項目之中晕翠。

SpringJDBC 封裝了基礎的 JDBC 操作喷舀,讓我們不用去關心 獲取驅動、建立連接淋肾、關閉連接等非業(yè)務操作硫麻,讓我們更加專注于業(yè)務的實現(xiàn)。

本文將對 SpringJDBC 的用法進行介紹樊卓,文主要內容如下:

  • 基本的數(shù)據(jù)操作
  • 自增主鍵的獲取

1. 基本的數(shù)據(jù)操作

1.1 更改

更改 主要使用的是 update 方法

  • 重載方法:主要包括三種拿愧,按需選擇,下面展示的從簡單到復雜碌尔。
sql = "insert into customer(name,age)values (?,?)";
int rows = jdbcTemplate.update(sql,"周杰倫",35);
int rows1 = jdbcTemplate.update(sql,new Object[]{"周杰倫",35});
int rows2 = jdbcTemplate.update(sql,new Object[]{"周杰倫",35},new int[]{Types.VARCHAR,Types.DECIMAL}); // 顯式指定數(shù)據(jù)類型
  • 批量更改:一次性執(zhí)行多條 update 語句浇辜,使用 batchUpdate 方法
    • jdbcTemplate.batchUpdate(String[] sql); 固定參數(shù)值
    • jdbcTemplate.batchUpdate(sql, new BatchPreparedStatementSetter()); 可變參數(shù)值
String sql1 = "insert into customer(NAME,AGE) values (1,1)";
String sql2 = "insert into customer(NAME,AGE) values (1,1)";
String sql3 = "insert into customer(NAME,AGE) values (1,1)";
String[] strings = new String[]{sql1,sql2,sql3};
int[] a = jdbcTemplate.batchUpdate(strings); // 固定參數(shù)的多條 SQL 語句組成一個數(shù)組傳入
System.out.println(Arrays.toString(a));


sql = "insert into customer(NAME,AGE) values (?,?)";
final List<String> list = new ArrayList<String>(){};
list.add("1");list.add("2");list.add("3");
int[] b = jdbcTemplate.batchUpdate(sql, new BatchPreparedStatementSetter() {  // 帶可變參數(shù)的 SQL 語句傳入
    public void setValues(PreparedStatement preparedStatement, int i) throws SQLException {
        preparedStatement.setString(1,list.get(i));
        preparedStatement.setString(2,list.get(i));
    }
    public int getBatchSize() {
        return list.size();
    }
});
System.out.println(Arrays.toString(b));

1.2 查詢

查詢 主要使用的是 query、queryForXX 等函數(shù)唾戚,而 queryForXX 系列底層其實調用的是 query 方法柳洋,故這里只介紹通過 query 方法查詢數(shù)據(jù)。

query 有多個重載方法叹坦,例如傳入固定參數(shù)的 SQL 語句熊镣,傳入可變參數(shù)的 SQL 語句等等,語法類似上面介紹的 update 方法募书,這里介紹兩種帶回調方法的查詢語句:

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

使用 RowCallbackHandler 既可以返回單行結果绪囱,也可以返回多行結果。Spring 會對查詢的結果集逐行調用 processRow 方法莹捡,用戶不用關心怎么讀取下一行數(shù)據(jù)的問題鬼吵。

sql = "select CUST_ID,NAME,AGE from customer where CUST_ID = ?";
final Customer customer = new Customer();
// 查詢單行數(shù)據(jù)
jdbcTemplate.query(sql, new Object[]{1}, new RowCallbackHandler() {
    public void processRow(ResultSet resultSet) throws SQLException {
        customer.setCUST_ID(Integer.parseInt(resultSet.getString("CUST_ID")));
        customer.setNAME(resultSet.getString("NAME"));
        customer.setAGE(Integer.parseInt(resultSet.getString("AGE")));
    }
});
System.out.println(customer.toString()); // Customer{CUST_ID=1, NAME='張三', AGE=12}

sql = "select CUST_ID,NAME,AGE from customer";
final List<Customer> customerList = new ArrayList<Customer>();
final Customer customer1 = new Customer();
// 查詢到多行數(shù)據(jù),代碼與上面沒有區(qū)別道盏,唯一的不同就是將結果集存入 List
jdbcTemplate.query(sql, new RowCallbackHandler() {
    public void processRow(ResultSet resultSet) throws SQLException {
        customer1.setCUST_ID(Integer.parseInt(resultSet.getString("CUST_ID")));
        customer1.setNAME(resultSet.getString("NAME"));
        customer1.setAGE(Integer.parseInt(resultSet.getString("AGE")));
        customerList.add(customer1);
    }
});
System.out.println(customerList);// [Customer{CUST_ID=38, NAME='3', AGE=3}, Customer{CUST_ID=38, NAME='3', AGE=3}]

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

使用 RowMapper 處理結果集而柑,它直接返回的是 List文捶,相比于上面荷逞,我們不用手動將對象添加到 List 中

sql = "select CUST_ID,NAME,AGE from customer";

List<Customer> customerList = jdbcTemplate.query(sql, new RowMapper<Customer>() {
    public Customer mapRow(ResultSet resultSet, int i) throws SQLException {
        Customer customer = new Customer();
        customer.setCUST_ID(Integer.parseInt(resultSet.getString("CUST_ID")));
        customer.setNAME(resultSet.getString("NAME"));
        customer.setAGE(Integer.parseInt(resultSet.getString("AGE")));
        return customer;
    }
});
System.out.println(customerList); // [Customer{CUST_ID=38, NAME='3', AGE=3}, Customer{CUST_ID=38, NAME='3', AGE=3}]

(3) 方法 a 與方法 b 的使用場景與注意事項

  • RowCallbackHandler 接口的實現(xiàn)類是可以有狀態(tài)媒咳,即在多線程環(huán)境下,可能會有線程安全的問題种远。
    下面代碼就展示了其實現(xiàn)類 RowCountCallbackHandler 打印結果集行數(shù)的示例涩澡,在多線程環(huán)境中,若行數(shù)發(fā)生變化坠敷,下面的結果可能不會一致妙同。而 RowMapper 實現(xiàn)類沒有這種情況。
RowCountCallbackHandler countCallbackHandler = new RowCountCallbackHandler();
jdbcTemplate.query("select * from customer",countCallbackHandler);
System.out.println(countCallbackHandler.getRowCount());
  • 當處理大結果集時膝迎, RowMapper 是將結果集所有數(shù)據(jù)放到 List<T> 中粥帚,這會占用大量 JVM 內存。RowCallbackHandler 接口內的 processRow() 方法則是一邊獲取數(shù)據(jù)一邊處理限次。RowMapper 是先獲取再處理芒涡,RowCallbackHandler 邊獲取邊處理。

2. 自增主鍵的獲取

在數(shù)據(jù)庫層面卖漫,一個表往往會有一個主鍵來唯一標識這一行數(shù)據(jù)费尽。

新增記錄時,返回新增記錄對應的自增主鍵值羊始,即返回的該列屬性包含兩個旱幼,一個是自增,另一個是主鍵突委。

SpringJDBC 提供了對自增主鍵獲取的方法柏卤,插入數(shù)據(jù)時,返回插入數(shù)據(jù)的主鍵匀油。

定義 KeyHolder 對象即可完成上述功能缘缚,步驟如下:

  1. 執(zhí)行 statement 語句時,指定綁定主鍵
connection.prepareStatement(sql1,PreparedStatement.RETURN_GENERATED_KEYS) 

final String sql1 = "insert into customer(name,age)values(?,?)";
KeyHolder keyHolder = new GeneratedKeyHolder();
jdbcTemplate.update(new PreparedStatementCreator() {
    public PreparedStatement createPreparedStatement(Connection connection) throws SQLException {
        PreparedStatement preparedStatement = connection.prepareStatement(sql1,PreparedStatement.RETURN_GENERATED_KEYS);
        preparedStatement.setString(1,"suiyia");
        preparedStatement.setString(2,"30");
        return preparedStatement;
    }
},keyHolder);
System.out.println(keyHolder.getKey().toString());
  1. keyHolder 的返回形式
  • Number getKey() 主鍵是數(shù)值類型钧唐,單列忙灼、一行
  • Map<String,Object> getKeys復合類型,多列钝侠、一行
  • List<Map<String,Object>> getKeyList 復合類型该园、多列、多行

3. 小結

本文只是對 SpringJDBC 的基本常用操作做了簡單介紹帅韧,之所以介紹 SpringJDBC里初,是因為在快速開發(fā)的后臺系統(tǒng)中,沒有足夠的時間去寫接口等忽舟,這種方式在小型簡單的系統(tǒng)開發(fā)時效率更高双妨。但在大型復雜的系統(tǒng)研發(fā)中淮阐,踏實寫接口,遵守框架的開發(fā)規(guī)范是很有必要的刁品。

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末泣特,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子挑随,更是在濱河造成了極大的恐慌状您,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,635評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件兜挨,死亡現(xiàn)場離奇詭異膏孟,居然都是意外死亡,警方通過查閱死者的電腦和手機拌汇,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,543評論 3 399
  • 文/潘曉璐 我一進店門柒桑,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人噪舀,你說我怎么就攤上這事魁淳。” “怎么了傅联?”我有些...
    開封第一講書人閱讀 168,083評論 0 360
  • 文/不壞的土叔 我叫張陵先改,是天一觀的道長。 經(jīng)常有香客問我蒸走,道長仇奶,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,640評論 1 296
  • 正文 為了忘掉前任比驻,我火速辦了婚禮该溯,結果婚禮上,老公的妹妹穿的比我還像新娘别惦。我一直安慰自己狈茉,他們只是感情好,可當我...
    茶點故事閱讀 68,640評論 6 397
  • 文/花漫 我一把揭開白布掸掸。 她就那樣靜靜地躺著氯庆,像睡著了一般。 火紅的嫁衣襯著肌膚如雪扰付。 梳的紋絲不亂的頭發(fā)上堤撵,一...
    開封第一講書人閱讀 52,262評論 1 308
  • 那天,我揣著相機與錄音羽莺,去河邊找鬼实昨。 笑死,一個胖子當著我的面吹牛盐固,可吹牛的內容都是我干的荒给。 我是一名探鬼主播丈挟,決...
    沈念sama閱讀 40,833評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼志电!你這毒婦竟也來了曙咽?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 39,736評論 0 276
  • 序言:老撾萬榮一對情侶失蹤溪北,失蹤者是張志新(化名)和其女友劉穎桐绒,沒想到半個月后夺脾,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體之拨,經(jīng)...
    沈念sama閱讀 46,280評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 38,369評論 3 340
  • 正文 我和宋清朗相戀三年咧叭,在試婚紗的時候發(fā)現(xiàn)自己被綠了蚀乔。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,503評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡菲茬,死狀恐怖吉挣,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情婉弹,我是刑警寧澤睬魂,帶...
    沈念sama閱讀 36,185評論 5 350
  • 正文 年R本政府宣布,位于F島的核電站镀赌,受9級特大地震影響氯哮,放射性物質發(fā)生泄漏。R本人自食惡果不足惜商佛,卻給世界環(huán)境...
    茶點故事閱讀 41,870評論 3 333
  • 文/蒙蒙 一喉钢、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧良姆,春花似錦肠虽、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,340評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至痊剖,卻和暖如春韩玩,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背邢笙。 一陣腳步聲響...
    開封第一講書人閱讀 33,460評論 1 272
  • 我被黑心中介騙來泰國打工啸如, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人氮惯。 一個月前我還...
    沈念sama閱讀 48,909評論 3 376
  • 正文 我出身青樓叮雳,卻偏偏與公主長得像想暗,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子帘不,可洞房花燭夜當晚...
    茶點故事閱讀 45,512評論 2 359

推薦閱讀更多精彩內容

  • 關于Mongodb的全面總結 MongoDB的內部構造《MongoDB The Definitive Guide》...
    中v中閱讀 31,947評論 2 89
  • 刻意練習并不復雜说莫,總結其關鍵詞:目標明確,專注投入寞焙,及時反饋储狭,不斷挑戰(zhàn)舒適區(qū),找到行業(yè)優(yōu)秀導師捣郊,強化動機辽狈,堅持練習...
    陌生如我閱讀 387評論 0 0
  • 今天聽到同學每天7點就交班了,而我每天8點才起床呛牲,甚是慚愧刮萌。
    冰城雨滴閱讀 248評論 0 0
  • 握不住的沙 夜色正美,皎白的月掛在天空娘扩,為大地灑下一片白茫茫的月光着茸,凄美清冷,心無睡...
    869a90eecb7b閱讀 140評論 0 0