![Spring Boot 2实战之旅](https://wfqqreader-1252317822.image.myqcloud.com/cover/805/26542805/b_26542805.jpg)
4.2 使用JDBC操作数据库
JDBC的全名是Java DataBase Connectivity,可能是我们最先接触到的数据库连接,通过JDBC可以直接使用Java编程来操作数据库。其实我们可以这样理解JDBC,它就是一个可以执行SQL语句的Java API。
4.1节讲了很多数据库,本节以MySQL为例介绍Spring Boot使用JDBC操作MySQL数据库。
4.2.1 JDBC依赖配置
新建项目,在pom文件中加入JDBC依赖和MySQL依赖以及Web功能的依赖,如代码清单4-17所示。
![](https://epubservercos.yuewen.com/47855F/15056703904175906/epubprivate/OEBPS/Images/Figure-T68_81004.jpg?sign=1739318858-i4aD8DMXj1GgO0O8yYoTDtzyVvinlSU9-0-ef726b1e22279b4a21fc1cf4451ccd42)
4.2.2 配置数据库信息
在配置文件中配置数据库信息,与4.1节介绍的一样,配置文件内容如代码清单4-18所示。
![](https://epubservercos.yuewen.com/47855F/15056703904175906/epubprivate/OEBPS/Images/Figure-T68_81003.jpg?sign=1739318858-ybi04M3aIcnov4TvkaeiW3pPLzGEkYCT-0-0cd6087866cc0b742184ffc2a4c25ce9)
4.2.3 创建实体类
创建一个实体类,用作接收表数据,这里省略set、get方法,代码如代码清单4-19所示。
![](https://epubservercos.yuewen.com/47855F/15056703904175906/epubprivate/OEBPS/Images/Figure-T69_81005.jpg?sign=1739318858-wuE79tFm03RtV8vAwwTe8aOdpV9Ig0iU-0-a3c6f9c035552e7571796591839215e5)
4.2.4 使用Controller进行测试
新建一个UserController,由于这个类只是用来测试使用JDBC操作数据库,因此我们在类上加入@RestController注解,熟悉Spring的人都知道,这个注解其实相当于@ResponseBody和@Controller两个注解结合起来使用。并且在UserController内注入JdbcTemplate,代码如代码清单4-20所示。
![](https://epubservercos.yuewen.com/47855F/15056703904175906/epubprivate/OEBPS/Images/Figure-T69_81006.jpg?sign=1739318858-4P4HDlmmTLPgPJCRybmwj3omF8kP7CIk-0-ea9f32e0abdc279c2b7536a91a2e24c3)
其中,@Autowired注解是Spring用于自动装配类的注解,功能和@Resource类似。刚刚我们注入的JdbcTemplate就是Spring Boot使用JDBC操作数据库的核心,接下来进一步对它进行学习。
对于操作数据库来说,其实基本上就是创建(Create)、更新(Update)、读取(Retrieve)和删除(Delete)操作。而对于JdbcTemplate操作数据库的CURD,基本上分为三种方法:
1. execute方法
execute方法用来直接执行SQL语句,是最直接的操作数据库的方法。接下来我们在UserController内写一个建表方法createTable来使用它,方法内容如代码清单4-21所示。
![](https://epubservercos.yuewen.com/47855F/15056703904175906/epubprivate/OEBPS/Images/Figure-T70_81008.jpg?sign=1739318858-NbWBhsXRkQhHTZacFyaeLb0UQsaUHLhg-0-02a2a8a0802f6897700656aece291e50)
启动项目,在浏览器上访问http://localhost:8080/createTable,显示如下。然后查看数据库,顺利地创建了User表。这里是以创建表为例,其实也可以直接执行CURD操作,就不一一举例了。
创建User表成功
2. update方法
update方法多用于增、删、改操作,update方法默认返回一个int值,了解SQL的人应该知道,方法的返回值就是影响的数据行数,比如我们数据库中存在两条性别为男的用户数据,当执行update语句修改性别为男的数据时,执行成功后,我们可以得到返回值2,这个就是我们执行update方法的返回值,新增、删除操作的原理类似。当然,也支持直接执行SQL语句,比如下面的方法saveUserSql,直接执行一个插入语句,代码如代码清单4-22所示。
![](https://epubservercos.yuewen.com/47855F/15056703904175906/epubprivate/OEBPS/Images/Figure-T70_81007.jpg?sign=1739318858-IJU30SVtUMPHV43IjMUopnojFGLNylHH-0-828b9c4b206dd96e3f824ac5a83f7bfb)
重启项目,在浏览器访问可以看到:
执行成功,影响1行
上面的场景可能并不常用,甚至基本上用不到,因为插入的数据不可能是已知的并且都是固定的。插入的数据是动态的怎么办呢?update方法中也是支持传值进去的,只需要在执行的SQL上用问号来代替参数,其中update方法内第一个参数是执行的SQL,接着对应传入动态的参数即可。下面3个方法分别列举了增、删、改的方法,代码如代码清单4-23所示。
![](https://epubservercos.yuewen.com/47855F/15056703904175906/epubprivate/OEBPS/Images/Figure-T71_81009.jpg?sign=1739318858-qoAUicJo7Omi9IesR6jl2PQLdybCGmSm-0-b1191c2428b31ab1d0d7d6a19a6ceb36)
这里就不一一测试了,感兴趣的读者可以自行测试。接下来我们继续学习update方法的延伸,其实JdbcTemplate中也提供了批处理方法batchUpdate,可以传入SQL和一个批处理的数组进行操作。比如下面的batchSaveUserSql方法,可以批量插入10条数据,代码如代码清单4-24所示。
![](https://epubservercos.yuewen.com/47855F/15056703904175906/epubprivate/OEBPS/Images/Figure-T71_81010.jpg?sign=1739318858-sjgEO4CmEhRPSHXn5HQlcknFL1GE48Ax-0-77fc9eec8983eddf812109dfa99e183f)
3. query方法
query方法看名字就能想到,用于执行有关查询的方法。
首先我们使用一个JdbcTemplate的query方法,这里可以用到之前创建的实体类User,方法如下,根据userName查询一个列表,代码如代码清单4-25所示。
![](https://epubservercos.yuewen.com/47855F/15056703904175906/epubprivate/OEBPS/Images/Figure-T72_81011.jpg?sign=1739318858-vLzguTJTy7Yv7bi8Lyjc44Z8ZD3LmYz1-0-48c881acdec17c276450b4ac5c460fe8)
重启项目,在浏览器上访问http://localhost:8080/getUserByUserName?userName=zhangsan0,如下所示:
[{"id":10,"user_name":"zhangsan0","user_password":"password0"}]
刚刚我们使用了一个返回List集合的方法,接下来使用一个返回Map的方法queryForMap,代码如代码清单4-26所示。
![](https://epubservercos.yuewen.com/47855F/15056703904175906/epubprivate/OEBPS/Images/Figure-T72_81012.jpg?sign=1739318858-nLUnIVcxDQEo3U4qRCag2uS91t8XJ0ZQ-0-d2626c6fbf7f2009b49f3ba6dd0396e9)
在浏览器访问http://localhost:8080/getMapById?id=1,如下所示:
{"id":1,"user_name":"lisi","user_password":"111"}
接下来我们查询一个数据库中不存在的数据,在浏览器访问http://localhost:8080/getMapById?id=1000,页面显示如图4-14所示。
![](https://epubservercos.yuewen.com/47855F/15056703904175906/epubprivate/OEBPS/Images/Figure-P73_22268.jpg?sign=1739318858-yIveAftSWpWgtYKvhOESyWNDvLifTpD7-0-316c86c1771e7f24335a688976b44b5d)
图4-14 JDBC项目Error图
我们回过头看一下控制台,报错如代码清单4-27所示。
![](https://epubservercos.yuewen.com/47855F/15056703904175906/epubprivate/OEBPS/Images/Figure-T73_81013.jpg?sign=1739318858-1F6SPmiBk6RDsNZxw1PrXH0DMzEuwLfb-0-a89e812503758df6b5192aa353e6d741)
![](https://epubservercos.yuewen.com/47855F/15056703904175906/epubprivate/OEBPS/Images/Figure-T74_80795.jpg?sign=1739318858-rLZeaql0n9NEXhGWqGIUIF64A7xV7aAP-0-d97abdc4344935cc189b28e3d8eccfe6)
![](https://epubservercos.yuewen.com/47855F/15056703904175906/epubprivate/OEBPS/Images/Figure-T75_80796.jpg?sign=1739318858-q9S9vSzoA2Hnm82O3SbsTRp9RKziKpme-0-c81c3b9124b952d3e9a539303a685e92)
接下来查看一下DataAccessUtils源代码,可以看到nullableSingleResult在查到空集合的时候默认抛出EmptyResultDataAccessException异常,看到就明白了。我们修改一下getMapById方法,在方法内捕获EmptyResultDataAccessException异常,方法代码修改如代码清单4-28所示。
![](https://epubservercos.yuewen.com/47855F/15056703904175906/epubprivate/OEBPS/Images/Figure-T76_81014.jpg?sign=1739318858-pPO3eJmhjVnhm44zSJ9CN27LQ54HBw4D-0-aaeeadedc8af372773c70658ae004147)
前面介绍了返回List集合、Map集合,接下来学习一个返回User实体类的方法queryForObject。基于刚刚查不到结果抛出异常的原因,吃一堑长一智,在这个方法中直接捕获这个异常,方法如代码清单4-29所示。
![](https://epubservercos.yuewen.com/47855F/15056703904175906/epubprivate/OEBPS/Images/Figure-T76_81015.jpg?sign=1739318858-1H8ywCsufJ4E2G7i5J435wOjaZAZ8slG-0-d6d3bab3570572a4faa381da636c9611)
测试就不再赘述了,和之前的方法一样。到这里,Spring Boot使用JDBC就告一段落了,毕竟在实际开发中对JDBC的使用不是很多,有一定基础就可以了。