Spring JDBC(配置数据源,操作数据库)

r囧r小猫 2024-04-07 15:26 120阅读 0赞

Java知识点总结:想看的可以从这里进入

目录

    • 14、Spring JDBC
      • 14.1、配置数据库资源
        • 14.1.1、简单数据源
        • 14.1.2、Druid连接池
      • 14.2、JdbcTemplate

14、Spring JDBC


Spring的JDBC模块有四个包组成:

  • core:核心包,JDBC核心功能,JdbcTemplate就在此包内
  • DataSource:数据源包,访问数据源的工具类,SimpleDriverDataSource 在此包
  • Object:对象包,以面向对象的方式访问数据库,它允许执行查询,并将结果作为业务对象,处理数据表和业务对象之间的映射
  • support:支持包,含有core和object包的支持类

14.1、配置数据库资源

在Spring中,通过JDBC驱动定义数据源是最简单的配置方式。Spring提供了三个这样的数据源类(均位于org.springframework.jdbc.datasource包中)供选择:

  1. org.springframework.jdbc.datasource.DriverManagerDataSource:在每个连接请求时都会返回一个新建的连接,旧的JDBC,无池化管理。基本上已被SimpleDriverDataSource取代。
  2. org.springframework.jdbc.datasource.SimpleDriverDataSource:与DriverManagerDataSource的工作方式类似,但是它直接使用JDBC驱动。
  3. org.springframework.jdbc.datasource.SingleConnectionDataSource:它的连接不会关闭,在每个连接请求时都会返回同一个的连接。(它不是严格意义上的连接池数据源,但是可以将其视为只有一个连接的连接池)

除了这些简单的数据原外,所以我们也可以选择其他的第三方连接池使用,第三方的数据库连接池其实有很多,不过大多使用:Druid(阿里的)、HikariCP(springboot目前默认的)。

14.1.1、简单数据源

先导入MySQL相关的依赖

  1. <!-- MySQL驱动 -->
  2. <dependency>
  3. <groupId>com.mysql</groupId>
  4. <artifactId>mysql-connector-j</artifactId>
  5. <version>8.0.32</version>
  6. </dependency>
  7. <!-- Spring jdbc 连数据库 根据spring版本选择-->
  8. <dependency>
  9. <groupId>org.springframework</groupId>
  10. <artifactId>spring-jdbc</artifactId>
  11. <version>6.0.3</version>
  12. </dependency>
  13. <dependency>
  14. <groupId>org.springframework</groupId>
  15. <artifactId>spring-jdbc</artifactId>
  16. <version>5.3.21</version>
  17. </dependency>

再在 resources 文件中创建properties文件,在此文件中编写数据库连写的一些信息

5f4923b03e43b41a783fdd1bf860d30d.png

  1. driver=com.mysql.cj.jdbc.Driver
  2. url=jdbc:mysql://localhost:3306/库名?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
  3. username=root
  4. password=密码

接下来在XML文件中配置 数据库连接

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xmlns:context="http://www.springframework.org/schema/context"
  5. xmlns:tx="http://www.springframework.org/schema/tx"
  6. xsi:schemaLocation="http://www.springframework.org/schema/beans
  7. http://www.springframework.org/schema/beans/spring-beans.xsd
  8. http://www.springframework.org/schema/context
  9. https://www.springframework.org/schema/context/spring-context.xsd
  10. http://www.springframework.org/schema/tx
  11. http://www.springframework.org/schema/tx/spring-tx.xsd">
  12. <!--导入数据文件database.properties-->
  13. <context:property-placeholder location="classpath:database.properties"/>
  14. <!--配置连接DriverManagerDataSource -->
  15. <bean id="dataSource1" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
  16. <property name="driverClassName" value="${jdbc.driver}"/>
  17. <property name="url" value="${jdbc.url}"/>
  18. <property name="username" value="${jdbc.username}"/>
  19. <property name="password" value="${jdbc.password}"/>
  20. </bean>
  21. <!--配置连接 SimpleDriverDataSource -->
  22. <bean id="dataSource2" class="org.springframework.jdbc.datasource.SimpleDriverDataSource">
  23. <property name="driverClass" value="${jdbc.driver}"/>
  24. <property name="url" value="${jdbc.url}"/>
  25. <property name="username" value="${jdbc.username}"/>
  26. <property name="password" value="${jdbc.password}"/>
  27. </bean>
  28. <!--配置连接 SingleConnectionDataSource -->
  29. <bean id="dataSource3" class="org.springframework.jdbc.datasource.SingleConnectionDataSource">
  30. <property name="driverClassName" value="${jdbc.driver}"/>
  31. <property name="url" value="${jdbc.url}"/>
  32. <property name="username" value="${jdbc.username}"/>
  33. <property name="password" value="${jdbc.password}"/>
  34. </bean>
  35. </beans>

连接数据库进行测试

  1. @SpringJUnitConfig(locations = {
  2. "classpath:application.xml"})
  3. public class JdbcTest {
  4. /**
  5. * DriverManagerDataSource
  6. */
  7. @Resource
  8. private DataSource dataSource1;
  9. /**
  10. * SimpleDriverDataSource
  11. */
  12. @Resource
  13. private DataSource dataSource2;
  14. /**
  15. * SingleConnectionDataSource
  16. */
  17. @Resource
  18. private DataSource dataSource3;
  19. @Test
  20. public void databaseTest(){
  21. //测试DriverManagerDataSource
  22. System.out.println(dataSource1);
  23. try (Connection connection = dataSource1.getConnection();
  24. PreparedStatement ps = connection.prepareStatement("SELECT * FROM user WHERE user_id=1");
  25. ResultSet rs = ps.executeQuery();
  26. ){
  27. if (rs.next()){
  28. User user = new User();
  29. user.setUserId(rs.getInt("user_id"))
  30. .setUsername(rs.getString("username"))
  31. .setPassword(rs.getString("password"))
  32. .setDeleted(rs.getBoolean("deleted"));
  33. System.out.println(user);
  34. }
  35. } catch (SQLException e) {
  36. throw new RuntimeException(e);
  37. }
  38. //测试SimpleDriverDataSource
  39. System.out.println(dataSource2);
  40. try (Connection connection = dataSource2.getConnection();
  41. PreparedStatement ps = connection.prepareStatement("SELECT * FROM user WHERE user_id=1");
  42. ResultSet rs = ps.executeQuery();
  43. ){
  44. if (rs.next()){
  45. User user = new User();
  46. user.setUserId(rs.getInt("user_id"))
  47. .setUsername(rs.getString("username"))
  48. .setPassword(rs.getString("password"))
  49. .setDeleted(rs.getBoolean("deleted"));
  50. System.out.println(user);
  51. }
  52. } catch (SQLException e) {
  53. throw new RuntimeException(e);
  54. }
  55. //测试SingleConnectionDataSource
  56. System.out.println(dataSource3);
  57. try (Connection connection = dataSource3.getConnection();
  58. PreparedStatement ps = connection.prepareStatement("SELECT * FROM user WHERE user_id=1 ");
  59. ResultSet rs = ps.executeQuery();
  60. ){
  61. if (rs.next()){
  62. User user = new User();
  63. user.setUserId(rs.getInt("user_id"))
  64. .setUsername(rs.getString("username"))
  65. .setPassword(rs.getString("password"))
  66. .setDeleted(rs.getBoolean("deleted"));
  67. System.out.println(user);
  68. }
  69. } catch (SQLException e) {
  70. throw new RuntimeException(e);
  71. }
  72. }
  73. }

image-20230330161504506

14.1.2、Druid连接池

Druid是阿里开源的优秀的连接池,几乎已经成为现在使用最多的连接池之一。Druid连接池专为监控而生,内置强大的监控功能且不影响性能,它能防SQL注入,内置Logging能诊断Hack应用行为等。

使用 Druid 需要现在pom文件中添加依赖:

  1. <!--德鲁伊连接池-->
  2. <dependency>
  3. <groupId>com.alibaba</groupId>
  4. <artifactId>druid</artifactId>
  5. <version>1.2.15</version>
  6. </dependency>

先在properties文件中配置数据资源

  1. jdbc.driver=com.mysql.cj.jdbc.Driver
  2. jdbc.url=jdbc:mysql://localhost:3306/库名?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
  3. jdbc.username=root
  4. jdbc.password=密码
  5. #初始连接数
  6. jdbc.initialSize=5
  7. #最小空闲连接数
  8. jdbc.minIdle=5
  9. #最大活动连接数
  10. jdbc.maxActive=20
  11. #最大等待时间
  12. jdbc.maxWait=50000
  13. #间隔多久进行一次检测
  14. jdbc.timeBetweenEvictionRunsMillis=500000
  15. #连接在池中最小生存的时间
  16. jdbc.minEvictableIdleTimeMillis=30000
  17. #验证数据库连接的查询语句:mysql是select 1、Oracle是select 1 from dual
  18. jdbc.validationQuery=select 1
  19. #testWhileIdle、testOnBorrow都是在获取连接的时候测试连接的有效性
  20. #其中testOnBorrow优先级高,都为true时不会使用到testWhileIdle
  21. # testWhileIdle(默认true)当从连接池中获取对象时,testOnBorrow为false,连接处于空闲状态时,则验证这条连接是否可用。
  22. #jdbc.testWhileIdle=true
  23. #从连接池中获取对象时,每次都会进行验证(默认false)
  24. #jdbc.testOnBorrow=false
  25. #归还连接时,每次都会进行验证(默认false)
  26. #jdbc.testOnReturn=false
  27. # 打开PSCache,并且指定每个连接上PSCache的大小
  28. jdbc.poolPreparedStatements=true
  29. jdbc.maxPoolPreparedStatementPerConnectionSize=20
  30. # 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙
  31. jdbc.filters=stat,wall,log4j
  32. # 通过connectProperties属性来打开mergeSql功能;慢SQL记录
  33. jdbc.connectionProperties=druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000

再在XML中配置连接池:

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xmlns:context="http://www.springframework.org/schema/context"
  5. xmlns:tx="http://www.springframework.org/schema/tx"
  6. xsi:schemaLocation="http://www.springframework.org/schema/beans
  7. http://www.springframework.org/schema/beans/spring-beans.xsd
  8. http://www.springframework.org/schema/context
  9. https://www.springframework.org/schema/context/spring-context.xsd
  10. http://www.springframework.org/schema/tx
  11. http://www.springframework.org/schema/tx/spring-tx.xsd">
  12. <!-- 导入数据文件database.properties-->
  13. <context:property-placeholder location="classpath:database.properties"/>
  14. <!-- 配置druid 连接池 -->
  15. <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" destroy-method="close">
  16. <property name="driverClassName" value="${jdbc.driver}"/>
  17. <property name="url" value="${jdbc.url}"/>
  18. <property name="username" value="${jdbc.username}"/>
  19. <property name="password" value="${jdbc.password}"/>
  20. <!--初始连接数-->
  21. <property name="initialSize" value="${jdbc.initialSize}"/>
  22. <!--最小空闲连接数-->
  23. <property name="minIdle" value="${jdbc.minIdle}"/>
  24. <!--最大活动连接数-->
  25. <property name="maxActive" value="${jdbc.maxActive}"/>
  26. <!--最大等待时间-->
  27. <property name="maxWait" value="${jdbc.maxWait}"/>
  28. <!--间隔多久进行一次检测,检测需要关闭的空闲连接 -->
  29. <property name="timeBetweenEvictionRunsMillis" value="${jdbc.timeBetweenEvictionRunsMillis}"/>
  30. <!--一个连接在池中最小生存的时间-->
  31. <property name="minEvictableIdleTimeMillis" value="${jdbc.minEvictableIdleTimeMillis}"/>
  32. <!--验证数据库连接的查询语句:mysql是select 1、Oracle是select 1 from dual-->
  33. <property name="validationQuery" value="${jdbc.validationQuery}"/>
  34. </bean>
  35. </beans>

连接数据库进行测试

  1. @Resource
  2. private DataSource druidDataSource;
  3. @Test
  4. public void druidTest(){
  5. try (Connection connection = druidDataSource.getConnection();
  6. PreparedStatement ps = connection.prepareStatement("SELECT * FROM user WHERE WHERE user_id=1");
  7. ResultSet rs = ps.executeQuery();
  8. ){
  9. if (rs.next()){
  10. User user = new User();
  11. user.setUserId(rs.getInt("user_id"))
  12. .setUsername(rs.getString("username"))
  13. .setPassword(rs.getString("password"))
  14. .setDeleted(rs.getBoolean("deleted"));
  15. System.out.println(user);
  16. }
  17. } catch (SQLException e) {
  18. throw new RuntimeException(e);
  19. }
  20. System.out.println(druidDataSource);
  21. }

image-20230330163655298

14.2、JdbcTemplate

在web编程中,传统的JDBC每次执行SQL时每次都需要获取:Connection、PreparedStatement、ResultSet 这些数据库资源,然后就需要大量的try、catch、finally语句捕捉异常、关闭数据库资源。既便是专门使用一个类设置成单例进行封装,它依然是很繁琐的。

在spring 中提供了JdbcTemplate模板来解决这个问题,它是比较经典的jdbc实现方式之一,同时也是Spring 在jdbc方便最底层的方法,SimpleJdbcInsert,SimpleJdbcCall 等底层都是用了JdbcTemplate。

JdbcTemplate是 org.springframework.jdbc.core 中的类,用来处理数据库资源的创建和释放, JdbcTemplate类主要包含下面这些功能:

  • 执行SQL查询语句
  • 执行更新语句和存储过程调用
  • 对 ResultSet 执行迭代并提取返回的参数值。
  • 捕获JDBC异常并进行处理

我们发现这些功能都是我们在写 JCBC时每条sql语句都会涉及到的内容,而JdbcTemplate把这些提取出来进行封装,我们只需要在XML中配置好,就可直接提供sql语句执行了。

  1. <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
  2. <!--将之前配置好的连接池加载进来 -->
  3. <property name="dataSource" ref="druidDataSource"/>
  4. </bean>

获取JdbcTemplate对象就可以直接使用,它内部的常用的方法

  • query():重载了大量 query方法来进行数据的查询操作,返回的是List,内部是自定义的Bean

    • List query(String sql, PreparedStatementSetter pss, RowMapper rowMapper):根据sql语句创建PreparedStatementSetter 对象。通过RowMapper 将结果返回到list中
    • List query(String sql, Object[] args, RowMapper rowMapper):使用Object[] 的值注入sql语句,利用RowMapper 返回数据
    • List query(String sql, RowMapper rowMapper, Object… args)

      1. jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(数据表对应的类.class),参数....);
  • queryForObject(String sql, RowMapper rowMapper, Object… args)():只能查询一行数据库记录,RowMapper自动封装,返回任意对象

    1. jdbcTemplate.queryForObject(sql, new BeanPropertyRowMapper<>(数据表对应的类.class),参数....);
  • queryForList():可以返回多行数据的结果,返回的是List数据
  • update():此方法用来进行修改、新增、删除操作

    • int update(String sql)
    • int update(String sql,Object… args)
  • int[] batchUpdate(String sql, List batchArgs, final int[] argTypes) :批量执行新增、更新、删除等语句

    sql:需要执行的 SQL 语句;argTypes:需要注入的 SQL 参数的 JDBC 类型;batchArgs:表示需要传入到 SQL 语句的参数。

  • execute():可以执行任意 SQL,一般用于执行 DDL 语句;

    @SpringJUnitConfig(locations = {

    1. "classpath:application.xml"})

    public class JDBCTest {

    1. @Resource
    2. private JdbcTemplate jdbcTemplate;
    3. @Test
    4. public void select(){
    5. Integer[] id = {
    6. 1};
    7. String sql = "select * from classes where c_id =?";
    8. //Classes classes =jdbcTemplate1.query(sql, new BeanPropertyRowMapper<>(Classes.class),id);
    9. Classes classes = jdbcTemplate.queryForObject(sql,id,(ResultSet rs,int rowNum)->{
    10. Classes classes1 = new Classes();
    11. classes1.setcId(rs.getInt("c_id"));
    12. classes1.setClassesName(rs.getString("classes_name"));
    13. classes1.setDeleted(rs.getBoolean("is_deleted"));
    14. return classes1;
    15. });
    16. if(classes!=null){
    17. System.out.println(classes.getClassesName());
    18. }
    19. }
    20. @Test
    21. public void selectAll(){
    22. String sql = "select * from classes";
    23. List<Classes> list = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(Classes.class));
    24. list.forEach(c -> System.out.println(c.getClassesName()));
    25. }
    26. @Test
    27. public void insert(){
    28. String classesName = "新增班级";
    29. String sql = "insert into classes(classes_name) values(?)";
    30. jdbcTemplate.update(sql, classesName);
    31. }
    32. @Test
    33. public void delete(){
    34. int id = 1;
    35. String sql = "delete from classes where c_id=?";
    36. jdbcTemplate.update(sql,id);
    37. }
    38. @Test
    39. public void update(){
    40. String newName = "修改班级";
    41. int id = 1;
    42. String sql = "UPDATE classes SET classes_name='?' WHERE classes.c_id = ?";
    43. jdbcTemplate.update(sql,newName,id);
    44. }

    }

image-20220913125433888

发表评论

表情:
评论列表 (有 0 条评论,120人围观)

还没有评论,来说两句吧...

相关阅读

    相关 spring配置数据

    配置一个数据源 Spring在第三方依赖包中包含了两个数据源的实现类包,其一是Apache的DBCP,其二是 C3P0。可以在Spring配置文件中利用这两者中任何一个配置