javascript
Spring Boot JdbcTemplate 入门
原創(chuàng)出處?http://www.iocoder.cn/Spring-Boot/JdbcTemplate/?「芋道源碼」
1. 概述
雖然說(shuō),我們現(xiàn)在項(xiàng)目的 DAL 數(shù)據(jù)訪問(wèn)層,大多使用 MyBatis 或者 JPA ,但是可能極少部分情況下也會(huì)使用 JDBC 。而使用的 JDBC 一般來(lái)說(shuō),一共有 3 種方式:
- 原生 JDBC ,或者自己項(xiàng)目封裝的 JDBC 工具類。
- Apache Common?,提供了?DbUtils?工具類。
- Spring JDBC?,提供了?JdbcTemplate?工具類。
咳咳咳,項(xiàng)目實(shí)戰(zhàn)中,我選擇 MyBatis ,哈哈哈。
下面,我們來(lái)快速入門?JdbcTemplate?的使用。
2. 快速入門
示例代碼對(duì)應(yīng)倉(cāng)庫(kù):lab-14-jdbctemplate?。
本小節(jié),我們會(huì)使用?spring-boot-starter-jdbc?自動(dòng)化配置 JDBC 主要配置。同時(shí),編寫相應(yīng)的 SQL 操作。
2.1 引入依賴
在?pom.xml?文件中,引入相關(guān)依賴。
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.1.3.RELEASE</version><relativePath/> <!-- lookup parent from repository --></parent><modelVersion>4.0.0</modelVersion><artifactId>lab-14-jdbctemplate</artifactId><dependencies><!-- 實(shí)現(xiàn)對(duì)數(shù)據(jù)庫(kù)連接池的自動(dòng)化配置 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-jdbc</artifactId></dependency><dependency> <!-- 本示例,我們使用 MySQL --><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.48</version></dependency><!-- 方便等會(huì)寫單元測(cè)試 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency></dependencies></project>
2.2 Application具體每個(gè)依賴的作用,胖友自己認(rèn)真看下艿艿添加的所有注釋噢。
創(chuàng)建?Application.java?類,配置?@SpringBootApplication?注解即可。代碼如下:
// Application.java@SpringBootApplication public class Application { }2.3 配置文件
在?application.yml?中,添加 DataSource 配置,如下:
spring:# datasource 數(shù)據(jù)源配置內(nèi)容datasource:url: jdbc:mysql://47.112.193.81:3306/testb5f4?useSSL=false&useUnicode=true&characterEncoding=UTF-8driver-class-name: com.mysql.jdbc.Driverusername: testb5f4password: F4df4db0ed86@112.4 UserDO
在?cn.iocoder.springboot.lab14.jdbctemplate.dataobject?包路徑下,創(chuàng)建?UserDO.java?類,用戶 DO 。代碼如下:
// UserDO.javapublic class UserDO {/*** 用戶編號(hào)*/private Integer id;/*** 賬號(hào)*/private String username;/*** 密碼(明文)** ps:生產(chǎn)環(huán)境下,千萬(wàn)不要明文噢*/private String password;/*** 創(chuàng)建時(shí)間*/private Date createTime;// ... 省略 setting/getting 方法}對(duì)應(yīng)的創(chuàng)建表的 SQL 如下:
CREATE TABLE `users` (`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '用戶編號(hào)',`username` varchar(64) COLLATE utf8mb4_bin DEFAULT NULL COMMENT '賬號(hào)',`password` varchar(32) COLLATE utf8mb4_bin DEFAULT NULL COMMENT '密碼',`create_time` datetime DEFAULT NULL COMMENT '創(chuàng)建時(shí)間',PRIMARY KEY (`id`),UNIQUE KEY `idx_username` (`username`) ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;2.5 UserDao
在?cn.iocoder.springboot.lab14.mybatis.dao?包路徑下,創(chuàng)建?UserDao?接口。代碼如下:
// UserDao.java@Repository public class UserDao {/*** 聲明 INSERT 操作的 PreparedStatementCreatorFactory 對(duì)象*/private static final PreparedStatementCreatorFactory INSERT_PREPARED_STATEMENT_CREATOR_FACTORY= new PreparedStatementCreatorFactory("INSERT INTO users(username, password, create_time) VALUES(?, ?, ?)");static {// 設(shè)置返回主鍵INSERT_PREPARED_STATEMENT_CREATOR_FACTORY.setReturnGeneratedKeys(true);INSERT_PREPARED_STATEMENT_CREATOR_FACTORY.setGeneratedKeysColumnNames("id");// 設(shè)置每個(gè)占位符的類型INSERT_PREPARED_STATEMENT_CREATOR_FACTORY.addParameter(new SqlParameter(Types.VARCHAR));INSERT_PREPARED_STATEMENT_CREATOR_FACTORY.addParameter(new SqlParameter(Types.VARCHAR));INSERT_PREPARED_STATEMENT_CREATOR_FACTORY.addParameter(new SqlParameter(Types.TIMESTAMP));}@Autowiredprivate JdbcTemplate template;/*** 使用 PreparedStatementCreator 實(shí)現(xiàn)插入數(shù)據(jù)** @param entity 實(shí)體* @return 影響行數(shù)*/public int insert(UserDO entity) {// 創(chuàng)建 KeyHolder 對(duì)象,設(shè)置返回的主鍵 IDKeyHolder keyHolder = new GeneratedKeyHolder();// 執(zhí)行插入操作int updateCounts = template.update(INSERT_PREPARED_STATEMENT_CREATOR_FACTORY.newPreparedStatementCreator(Arrays.asList(entity.getUsername(), entity.getPassword(), entity.getCreateTime())), keyHolder);// 設(shè)置 ID 主鍵到 entity 實(shí)體中if (keyHolder.getKey() != null) {entity.setId(keyHolder.getKey().intValue());}// 返回影響行數(shù)return updateCounts;}/*** 使用 SimpleJdbcInsert 實(shí)現(xiàn)插入數(shù)據(jù)** @param entity 實(shí)體* @return 影響行數(shù)*/public int insert0(UserDO entity) {// 創(chuàng)建 SimpleJdbcInsert 對(duì)象SimpleJdbcInsert insertOp = new SimpleJdbcInsert(template);insertOp.setTableName("users");insertOp.setColumnNames(Arrays.asList("username", "password", "create_time"));insertOp.setGeneratedKeyName("id");// 拼接參數(shù)Map<String, Object> params = new HashMap<>();params.put("username", entity.getUsername());params.put("password", entity.getPassword());params.put("create_time", entity.getCreateTime());// 執(zhí)行插入操作Number id = insertOp.executeAndReturnKey(params);// 設(shè)置 ID 主鍵到 entity 實(shí)體中entity.setId(id.intValue());// 返回影響行數(shù)return 1;}public int updateById(UserDO entity) {// JdbcTemplate 生成更新的動(dòng)態(tài) SQL 不是很方便,需要自己二次封裝。類似 SimpleJdbcInsert 對(duì)象return template.update("UPDATE users SET password = ? WHERE id = ?", entity.getPassword(),entity.getId());}public int deleteById(Integer id) {return template.update("DELETE FROM users WHERE id = ?", id);}public UserDO selectById(Integer id) {return template.queryForObject("SELECT id, username, password, create_time FROM users WHERE id = ?",new BeanPropertyRowMapper<>(UserDO.class), // 結(jié)果轉(zhuǎn)換成對(duì)應(yīng)的對(duì)象id);}public UserDO selectByUsername(String username) {return template.queryForObject("SELECT id, username, password, create_time FROM users WHERE username = ? LIMIT 1",new BeanPropertyRowMapper<>(UserDO.class), // 結(jié)果轉(zhuǎn)換成對(duì)應(yīng)的對(duì)象username);}public List<UserDO> selectByIds(List<Integer> ids) {// 創(chuàng)建 NamedParameterJdbcTemplate 對(duì)象NamedParameterJdbcTemplate namedParameterJdbcTemplate = new NamedParameterJdbcTemplate(template);// 拼接參數(shù)Map<String, Object> params = new HashMap<>();params.put("ids", ids);// 執(zhí)行查詢r(jià)eturn namedParameterJdbcTemplate.query("SELECT id, username, password, create_time FROM users WHERE id IN (:ids)", // 使用 :ids 作為占位服務(wù)params,new BeanPropertyRowMapper<>(UserDO.class) // 結(jié)果轉(zhuǎn)換成對(duì)應(yīng)的對(duì)象);}}- 具體的每個(gè)操作,胖友看下方法名和注釋。
- 雖然說(shuō),我們可以在 Service 中使用 JdbcTemplate 進(jìn)行數(shù)據(jù)庫(kù)的操作,但是艿艿還是建議將每個(gè)表的操作,分裝到對(duì)應(yīng)的 Dao 中。一方面,代碼可以更加簡(jiǎn)潔,另一方面,未來(lái)如果替換為 MyBatis 或 JPA 等 ORM 框架時(shí),業(yè)務(wù)層無(wú)需做調(diào)整。
2.6 簡(jiǎn)單測(cè)試
創(chuàng)建?UserDaoTest?測(cè)試類,我們來(lái)測(cè)試一下簡(jiǎn)單的 UserDaoTest 的每個(gè)操作。代碼如下:
// UserDaoTest.java@RunWith(SpringRunner.class) @SpringBootTest(classes = Application.class) public class UserDaoTest {@Autowiredprivate UserDao userDao;@Testpublic void testInsert() {UserDO user = new UserDO().setUsername(UUID.randomUUID().toString()).setPassword("nicai").setCreateTime(new Date());userDao.insert(user);System.out.println(user);}@Testpublic void testInsert0() {UserDO user = new UserDO().setUsername(UUID.randomUUID().toString()).setPassword("nicai").setCreateTime(new Date());userDao.insert0(user);System.out.println(user);}@Testpublic void testUpdateById() {UserDO updateUser = new UserDO().setId(1).setPassword("wobucai");userDao.updateById(updateUser);}@Testpublic void testDeleteById() {userDao.deleteById(2);}@Testpublic void testSelectById() {UserDO user = userDao.selectById(1);System.out.println(user);}@Testpublic void testSelectByUsername() {UserDO user = userDao.selectByUsername("yunai");System.out.println(user);}@Testpublic void testSelectByIds() {List<UserDO> users = userDao.selectByIds(Arrays.asList(1, 5));System.out.println("users:" + users.size());}}具體的,胖友可以自己跑跑,妥妥的。
666. 彩蛋
雖然說(shuō),我們?cè)谌粘i_發(fā)中,基本很少在直接接觸到 JDBC ,但是 JDBC 在問(wèn) 們的開發(fā)中,無(wú)處不在:
- HikariCP、Druid 在其上,提供了數(shù)據(jù)庫(kù)連接池的功能。
- Sharding Sphere 在其上,提供了分庫(kù)分表、讀寫分離等功能。
- Seata 在其上,提供了分布式事務(wù)的功能。
- Hibernate、MyBatis 在其上,提供了 ORM 的功能。
-
Elasticsearch SQL JDBC?在其上,提供了訪問(wèn) ES 的 Driver 實(shí)現(xiàn)。
總結(jié)
以上是生活随笔為你收集整理的Spring Boot JdbcTemplate 入门的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 教你用 Netty 实现一个简单的 RP
- 下一篇: gradle idea java ssm