SpringBoot系列(17):基于Spring內(nèi)置的JdbcTemplate實(shí)現(xiàn)極簡(jiǎn)CRUD功能
作者:
修羅debug
版權(quán)聲明:本文為博主原創(chuàng)文章,遵循 CC 4.0 by-sa 版權(quán)協(xié)議,轉(zhuǎn)載請(qǐng)附上原文出處鏈接和本聲明。
摘要:現(xiàn)如今市面上以Java技術(shù)棧為主、用于開發(fā)Web項(xiàng)目的主流持久層框架主要包括Hibernate、JPA、Spring Data JPA、ibatis、Mybatis等等,其中,用的比較多的當(dāng)屬M(fèi)ybatis、Hibernate/ Spring Data JPA,即所謂的SSM或者SSH項(xiàng)目啦!本文我們將基于Spring內(nèi)置的JdbcTemplate實(shí)現(xiàn)一個(gè)功能模塊的CRUD操作。
內(nèi)容:對(duì)于目前市面上流行的持久層框架Mybatis、Hibernate/ Spring Data JPA,相信大家或多或少都見過,甚至有的小伙伴都已經(jīng)用它們來擼過N套項(xiàng)目了,本文我們就不分享介紹這些主流框架的應(yīng)用了。相反,我們回歸到核心框架Spring中內(nèi)置JdbcTemplate組件,一起來體驗(yàn)一下Spring 內(nèi)置的JdbcTemplate如何實(shí)現(xiàn)一個(gè)業(yè)務(wù)模塊的CRUD操作功能。
JdbcTemplate,顧名思義,其實(shí)是從傳統(tǒng)的JDBC操作組件演進(jìn)而來的,但是它卻不能等同于傳統(tǒng)的JDBC(否則,就沒有介紹的必要了),它屏蔽了傳統(tǒng)JDBC的數(shù)據(jù)庫連接操作、語句管理以及資源關(guān)閉管理等既繁瑣、而又重復(fù)性的操作代碼,采用“模板設(shè)計(jì)模式”,并基于強(qiáng)大的Spring框架作為依托而隆重推出的操作數(shù)據(jù)庫的利器!
在對(duì)業(yè)務(wù)模塊進(jìn)行CRUD等功能操作之前,我們需要在我們的項(xiàng)目中顯示、自動(dòng)注入JdbcTempalte操作組件(當(dāng)然啦,你如果喜歡用XML進(jìn)行配置,那也完全是ok的)!
@Bean("primaryJdbcTemplate")
public JdbcTemplate primaryJdbcTemplate(@Qualifier("primaryDataSource") DataSource dataSource){
JdbcTemplate jdbcTemplate=new JdbcTemplate(dataSource);
return jdbcTemplate;
}
在這里,我們需要注入主數(shù)據(jù)源primaryDataSource實(shí)例,用來構(gòu)造JdbcTemplate實(shí)例。之后我們以數(shù)據(jù)庫表user為案例,分享介紹極簡(jiǎn)的CRUD功能,其中,該數(shù)據(jù)庫表user的DDL定義如下所示:
CREATE TABLE `user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT '名字',
`code` varchar(255) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT '工號(hào)',
`email` varchar(255) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT '郵箱',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='用戶信息表';
(1)首先,我們自然需要?jiǎng)?chuàng)建一個(gè)Controller,用于接收前端過來的請(qǐng)求數(shù)據(jù),這個(gè)controller下自然由CRUD幾個(gè)方法,其完整的源代碼如下所示:
/**
* spring jdbcTemplate
* @Author:debug (SteadyJack)
* @Link: weixin-> debug0868 qq-> 1948831260
* @Date: 2019/11/11 21:33
**/
@RestController
@RequestMapping("jdbc/template/user")
public class JbdcTemplateController extends AbstractController{
@Autowired
private JdbcTemplateService jdbcTemplateService;
//TODO:新增
@RequestMapping(value = "add",method = RequestMethod.POST,consumes = MediaType.APPLICATION_JSON_UTF8_VALUE)
public BaseResponse info(@RequestBody @Validated UserDto userDto, BindingResult result){
String checkRes=ValidatorUtil.checkResult(result);
if (StringUtils.isNotBlank(checkRes)){
return new BaseResponse(StatusCode.InvalidParams.getCode(),checkRes);
}
BaseResponse response=new BaseResponse(StatusCode.Success);
try {
int res=jdbcTemplateService.addUser(userDto);
response.setData(res);
}catch (Exception e){
response=new BaseResponse(StatusCode.Fail.getCode(),e.getMessage());
}
return response;
}
//TODO:查詢一個(gè)
@RequestMapping(value = "query/one",method = RequestMethod.GET)
public BaseResponse queryOne(@RequestParam Integer id){
if (id<=0){
return new BaseResponse(StatusCode.InvalidParams);
}
BaseResponse response=new BaseResponse(StatusCode.Success);
try {
response.setData(jdbcTemplateService.queryUserById(id));
}catch (Exception e){
response=new BaseResponse(StatusCode.Fail.getCode(),e.getMessage());
}
return response;
}
//TODO:查詢列表
@RequestMapping(value = "query/list",method = RequestMethod.GET)
public BaseResponse queryList(@RequestParam String search){
BaseResponse response=new BaseResponse(StatusCode.Success);
Map<String,Object> resMap= Maps.newHashMap();
try {
resMap.put("數(shù)據(jù)列表-v1",jdbcTemplateService.queryListV1(search));
resMap.put("數(shù)據(jù)列表-v2",jdbcTemplateService.queryListV2(search));
}catch (Exception e){
response=new BaseResponse(StatusCode.Fail.getCode(),e.getMessage());
}
response.setData(resMap);
return response;
}
//TODO:刪除
@RequestMapping(value = "delete",method = RequestMethod.POST)
public BaseResponse delete(@RequestParam Integer id){
if (id<=0){
return new BaseResponse(StatusCode.InvalidParams);
}
BaseResponse response=new BaseResponse(StatusCode.Success);
try {
response.setData(jdbcTemplateService.delete(id));
}catch (Exception e){
response=new BaseResponse(StatusCode.Fail.getCode(),e.getMessage());
}
return response;
}
}
其中的UserDto的源碼如下所示:
@Data
public class UserDto implements Serializable{
@NotBlank(message = "name不能為空!")
private String name;
@NotBlank(message = "code不能為空!")
private String code;
@NotBlank(message = "email不能為空!")
private String email;
}
(2)最后,自然是貼出其Service的具體實(shí)現(xiàn)邏輯啦:
/**
* Spring+JdbcTemplate實(shí)戰(zhàn)
* @Author:debug (SteadyJack)
* @Link: weixin-> debug0868 qq-> 1948831260
* @Date: 2019/11/11 21:34
**/
@Service
public class JdbcTemplateService {
private static final Logger log= LoggerFactory.getLogger(JdbcTemplateService.class);
private static final String insertSql="insert into user (name, code, email) values (?,?,?)";
private static final String queryOneSql="SELECT id,`name`,`code`,email FROM `user` WHERE id=?";
private static final String queryListSql="SELECT id,`name`,`code`,email FROM `user` WHERE 1=1 AND (name LIKE ? OR `code` LIKE ? OR email LIKE ?)";
private static final String deleteSql="DELETE FROM `user` WHERE id=?";
@Resource(name = "primaryJdbcTemplate")
private JdbcTemplate primaryJdbcTemplate;
//TODO:新增
public int addUser(UserDto dto) throws Exception{
return primaryJdbcTemplate.update(insertSql, ps -> {
ps.setString(1,dto.getName());
ps.setString(2,dto.getCode());
ps.setString(3,dto.getEmail());
});
}
//TODO:查詢-一個(gè) - 結(jié)果集與實(shí)體對(duì)象映射
public User queryUserById(final Integer id){
try {
return primaryJdbcTemplate.queryForObject(queryOneSql, new Object[]{id}, new RowMapper<User>() {
@Override
public User mapRow(ResultSet rs, int i) throws SQLException {
User entity=new User();
entity.setId(rs.getInt("id"));
entity.setName(rs.getString("name"));
entity.setCode(rs.getString("code"));
entity.setEmail(rs.getString("email"));
return entity;
}
});
}catch (Exception e){
log.error("spring-jdbcTemplate-查詢用戶信息發(fā)生異常:id={}",id,e.fillInStackTrace());
}
return null;
}
//TODO:列表查詢一
public List<User> queryListV1(final String search) throws Exception{
return primaryJdbcTemplate.query(queryListSql, new Object[]{"%" + search + "%","%" + search + "%","%" + search + "%"}, new RowMapper<User>() {
User entity;
@Override
public User mapRow(ResultSet rs, int i) throws SQLException {
entity=new User();
entity.setId(rs.getInt("id"));
entity.setName(rs.getString("name"));
entity.setCode(rs.getString("code"));
entity.setEmail(rs.getString("email"));
return entity;
}
});
}
//TODO:列表查詢二
public List<User> queryListV2(final String search) throws Exception{
return primaryJdbcTemplate.query(queryListSql,
new Object[]{"%" + search + "%","%" + search + "%","%" + search + "%"}, new BeanPropertyRowMapper<>(User.class));
}
//TODO:刪除 – 物理刪除
public int delete(final Integer id){
return primaryJdbcTemplate.update(deleteSql,id);
}
}
其中的“列表實(shí)體查詢”操作,我們提供了兩種不同的API來實(shí)現(xiàn)。將項(xiàng)目跑起來,然后打開postman對(duì)相應(yīng)的請(qǐng)求接口執(zhí)行一波騷操作,體驗(yàn)體驗(yàn)Spring內(nèi)置的JdbcTemplate的魅力:
A.“新增/修改操作”的操作效果圖:
B.“查詢單一實(shí)體信息”的操作效果圖:
C.“查詢列表實(shí)體信息”的操作效果圖:
D.“刪除實(shí)體信息”的操作效果圖:
好了,本篇文章我們就介紹到這里了,其他相關(guān)的技術(shù),感興趣的小伙伴可以關(guān)注底部Debug的技術(shù)公眾號(hào),或者加Debug的微信,拉你進(jìn)“微信版”的真正技術(shù)交流群!一起學(xué)習(xí)、共同成長(zhǎng)!
補(bǔ)充:
1、本文涉及到的相關(guān)的源代碼可以到此地址,check出來進(jìn)行查看學(xué)習(xí):
https://gitee.com/steadyjack/SpringBootTechnology
2、最近Debug發(fā)布了幾門重量級(jí)的課程,感興趣的小伙伴可以前往觀看學(xué)習(xí):
(1) 緩存中間件Redis技術(shù)入門與應(yīng)用場(chǎng)景實(shí)戰(zhàn)(SpringBoot2.x + 搶紅包系統(tǒng)設(shè)計(jì)與實(shí)戰(zhàn))
https://www.fightjava.com/web/index/course/detail/12
(2) 企業(yè)權(quán)限管理平臺(tái)(SpringBoot2.0+Shiro+Vue+Mybatis)
https://www.fightjava.com/web/index/course/detail/8
3、關(guān)注一下Debug的技術(shù)微信公眾號(hào),最新的技術(shù)文章、課程以及技術(shù)專欄將會(huì)第一時(shí)間在公眾號(hào)發(fā)布哦!