SpringBoot整合JdbcTemplate快速開(kāi)發(fā)數(shù)據(jù)訪問(wèn)層
很多人一提到 SpringBoot 操作數(shù)據(jù)庫(kù),就只想到 MyBatis、JPA,其實(shí)在很多簡(jiǎn)單業(yè)務(wù)、小工具項(xiàng)目、后臺(tái)管理模塊里,根本沒(méi)必要上重型框架。JdbcTemplate 才是輕量、簡(jiǎn)單、開(kāi)箱即用的神器,沒(méi)有復(fù)雜配置、沒(méi)有 XML、沒(méi)有各種插件,幾行代碼就能完成增刪改查,非常適合快速開(kāi)發(fā)。
一、JdbcTemplate 適合什么場(chǎng)景?
- 單表簡(jiǎn)單業(yè)務(wù),不想寫(xiě) MyBatis XML/注解
- 微服務(wù)內(nèi)部小模塊、輕量接口
- 快速原型開(kāi)發(fā)、臨時(shí)數(shù)據(jù)處理
- 對(duì) SQL 可控,但又不想引入復(fù)雜 ORM
優(yōu)點(diǎn):
- 極輕量,無(wú)額外依賴
- 直接寫(xiě)原生 SQL,靈活直觀
- 性能接近原生 JDBC,無(wú)損耗
- Spring 自帶,自動(dòng)整合事務(wù)
二、引入依賴
只需要 web + jdbc + mysql 驅(qū)動(dòng)即可:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>三、application.yml 配置
和 MyBatis 數(shù)據(jù)源配置完全一樣:
spring:
datasource:
url: jdbc:mysql://localhost:3306/testdb?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver不需要任何額外配置,啟動(dòng)項(xiàng)目自動(dòng)裝配 JdbcTemplate。
四、建表 SQL
CREATE TABLE `user` ( `id` bigint NOT NULL AUTO_INCREMENT, `username` varchar(50) DEFAULT NULL, `age` int DEFAULT NULL, `email` varchar(50) DEFAULT NULL, `create_time` datetime DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
五、實(shí)體類(lèi) User
package com.demo.entity;
import lombok.Data;
import java.time.LocalDateTime;
@Data
public class User {
private Long id;
private String username;
private Integer age;
private String email;
private LocalDateTime createTime;
}六、直接使用 JdbcTemplate(最簡(jiǎn)潔方式)
JdbcTemplate 常用方法:
- update():增、刪、改
- queryForObject():查詢單個(gè)對(duì)象
- query():查詢列表
- batchUpdate():批量操作
1. 新增
@Autowired
private JdbcTemplate jdbcTemplate;
public int addUser(User user) {
String sql = "insert into user(username, age, email) values(?, ?, ?)";
return jdbcTemplate.update(
sql,
user.getUsername(),
user.getAge(),
user.getEmail()
);
}2. 刪除
public int deleteById(Long id) {
String sql = "delete from user where id=?";
return jdbcTemplate.update(sql, id);
}3. 修改
public int updateUser(User user) {
String sql = "update user set username=?, age=?, email=? where id=?";
return jdbcTemplate.update(
sql,
user.getUsername(),
user.getAge(),
user.getEmail(),
user.getId()
);
}4. 根據(jù) ID 查詢單個(gè)對(duì)象
public User findById(Long id) {
String sql = "select * from user where id=?";
return jdbcTemplate.queryForObject(
sql,
new BeanPropertyRowMapper<>(User.class),
id
);
}5. 查詢列表
public List<User> findAll() {
String sql = "select * from user";
return jdbcTemplate.query(
sql,
new BeanPropertyRowMapper<>(User.class)
);
}6. 帶條件查詢
public List<User> findByAge(Integer age) {
String sql = "select * from user where age=?";
return jdbcTemplate.query(
sql,
new BeanPropertyRowMapper<>(User.class),
age
);
}7. 統(tǒng)計(jì)數(shù)量
public Long count() {
String sql = "select count(*) from user";
return jdbcTemplate.queryForObject(sql, Long.class);
}8. 批量插入
public void batchAdd(List<User> userList) {
String sql = "insert into user(username, age, email) values(?,?,?)";
jdbcTemplate.batchUpdate(sql, new BatchPreparedStatementSetter() {
@Override
public void setValues(PreparedStatement ps, int i) throws SQLException {
User user = userList.get(i);
ps.setString(1, user.getUsername());
ps.setInt(2, user.getAge());
ps.setString(3, user.getEmail());
}
@Override
public int getBatchSize() {
return userList.size();
}
});
}七、封裝成標(biāo)準(zhǔn) Service 層
@Service
public class UserService {
@Autowired
private JdbcTemplate jdbcTemplate;
// 新增
@Transactional(rollbackFor = Exception.class)
public boolean add(User user) {
String sql = "insert into user(username,age,email) values(?,?,?)";
return jdbcTemplate.update(sql, user.getUsername(), user.getAge(), user.getEmail()) > 0;
}
// 刪除
@Transactional
public boolean delete(Long id) {
String sql = "delete from user where id=?";
return jdbcTemplate.update(sql, id) > 0;
}
// 修改
@Transactional
public boolean update(User user) {
String sql = "update user set username=?,age=?,email=? where id=?";
return jdbcTemplate.update(sql,
user.getUsername(),
user.getAge(),
user.getEmail(),
user.getId()) > 0;
}
// 根據(jù)ID查詢
public User findById(Long id) {
String sql = "select * from user where id=?";
try {
return jdbcTemplate.queryForObject(
sql,
new BeanPropertyRowMapper<>(User.class),
id);
} catch (EmptyResultDataAccessException e) {
return null;
}
}
// 查詢?nèi)?
public List<User> list() {
String sql = "select * from user";
return jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(User.class));
}
}注意:queryForObject 查詢不到會(huì)拋異常,必須 try-catch 處理。
八、Controller 接口
@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
private UserService userService;
@PostMapping("/add")
public Result add(@RequestBody User user) {
userService.add(user);
return Result.success("添加成功");
}
@DeleteMapping("/delete/{id}")
public Result delete(@PathVariable Long id) {
userService.delete(id);
return Result.success("刪除成功");
}
@PutMapping("/update")
public Result update(@RequestBody User user) {
userService.update(user);
return Result.success("修改成功");
}
@GetMapping("/{id}")
public Result findById(@PathVariable Long id) {
return Result.success(userService.findById(id));
}
@GetMapping("/list")
public Result list() {
return Result.success(userService.list());
}
}九、JdbcTemplate 事務(wù)支持
直接使用 @Transactional 即可,和 MyBatis 完全一致:
@Transactional(rollbackFor = Exception.class)
public void testTransaction() {
// 兩次修改,要么都成功,要么都回滾
jdbcTemplate.update("update user set age=20 where id=1");
int i = 1 / 0; // 模擬異常
jdbcTemplate.update("update user set age=30 where id=2");
}十、JdbcTemplate 與 MyBatis 如何選擇?
- 簡(jiǎn)單單表、快速開(kāi)發(fā) → JdbcTemplate
- 復(fù)雜查詢、多表關(guān)聯(lián)、動(dòng)態(tài)SQL → MyBatis
- 企業(yè)后臺(tái)管理系統(tǒng) → MyBatis 更易維護(hù)
- 小接口、輕量服務(wù) → JdbcTemplate 更清爽
十一、注意事項(xiàng)
1. 查詢不到數(shù)據(jù)報(bào)錯(cuò)queryForObject 無(wú)數(shù)據(jù)會(huì)拋異常,需要捕獲 EmptyResultDataAccessException
2. 類(lèi)型不匹配
數(shù)據(jù)庫(kù)日期、數(shù)字類(lèi)型要與實(shí)體類(lèi)對(duì)應(yīng)
3. SQL 注入風(fēng)險(xiǎn)
必須使用 ? 占位符,不要字符串拼接
4. 批量操作性能
大量數(shù)據(jù)建議分批插入,避免一次過(guò)大
十二、總結(jié)
SpringBoot 整合 JdbcTemplate 可以說(shuō)是最簡(jiǎn)單的數(shù)據(jù)層方案:
只需要引入 spring-boot-starter-jdbc,自動(dòng)裝配,直接寫(xiě) SQL 就能完成所有操作。
沒(méi)有配置、沒(méi)有 XML、沒(méi)有學(xué)習(xí)成本,非常適合小項(xiàng)目、快速開(kāi)發(fā)場(chǎng)景,也是 Spring 生態(tài)最原生的數(shù)據(jù)訪問(wèn)方式。
以上就是SpringBoot整合JdbcTemplate快速開(kāi)發(fā)數(shù)據(jù)訪問(wèn)層的詳細(xì)內(nèi)容,更多關(guān)于SpringBoot JdbcTemplate數(shù)據(jù)訪問(wèn)層的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
解決springdataJPA對(duì)原生sql支持的問(wèn)題
這篇文章主要介紹了解決springdataJPA對(duì)原生sql支持的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-06-06
SpringBoot中的CompletableFuture類(lèi)詳解
這篇文章主要介紹了SpringBoot中的CompletableFuture類(lèi)詳解,在?Java8中,引入了CompletableFuture類(lèi),它提供了一種簡(jiǎn)單而強(qiáng)大的方式來(lái)執(zhí)行異步任務(wù),今天我們就來(lái)詳細(xì)解讀一下這個(gè)類(lèi),需要的朋友可以參考下2023-07-07
springboot2啟動(dòng)時(shí)執(zhí)行,初始化(或定時(shí)任務(wù))servletContext問(wèn)題
這篇文章主要介紹了springboot2啟動(dòng)時(shí)執(zhí)行,初始化(或定時(shí)任務(wù))servletContext問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-01-01
SpringAop中AspectJ框架的切入點(diǎn)表達(dá)式
這篇文章主要介紹了SpringAop中AspectJ框架的切入點(diǎn)表達(dá)式,AspectJ是一個(gè)基于Java語(yǔ)言的AOP框架,Spring2.0以后新增了對(duì)AspectJ切點(diǎn)表達(dá)式支持,@AspectJ 是AspectJ1.5新增功能,通過(guò)JDK5注解技術(shù),允許直接在Bean類(lèi)中定義切面,需要的朋友可以參考下2023-08-08
MyBatis游標(biāo)Cursor的正確使用和百萬(wàn)數(shù)據(jù)傳輸?shù)膬?nèi)存測(cè)試
這篇文章主要介紹了MyBatis游標(biāo)Cursor的正確使用和百萬(wàn)數(shù)據(jù)傳輸?shù)膬?nèi)存測(cè)試,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-01-01
Maven?自動(dòng)化構(gòu)建的實(shí)現(xiàn)示例
本文主要介紹了Maven?自動(dòng)化構(gòu)建的實(shí)現(xiàn)示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2024-05-05
解決springboot整合cxf-jaxrs中json轉(zhuǎn)換的問(wèn)題
這篇文章主要介紹了解決springboot整合cxf-jaxrs中json轉(zhuǎn)換的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-07-07

