Spring JDBC

image.png

Spring JDBC

 <dependency>
     <groupId>org.springframework</groupId>
     <artifactId>spring-jdbc</artifactId>
     <version>${spring.version}</version> <!-- 5.1.17.RELEASE -->
 </dependency>


Spring 为了提供对 Jdbc 的支持,在 JDBC API 的基础上封装了一套实现,以此建立一个简单的 JDBC 存取框架。

( 作为 Spring JDBC 框架的核心 )JdbcTemplate 的设计目的主要是两个:

  1. 简化 JDBC 的操作代码。

  2. 可以将事务的管理工作委托给 Spring,进一步简化代码。

JdbcTemplate 使用很简单:要求 Spring『帮』我们创建一个 JdbcTemplate 的单例对象,随后,我们在代码( DAO )中,注入这个 JdbcTemplate 单例对象,使用它即可。

需要注意的是,Spirng 创建 JdbcTemplte 单例对象时,需要传入 DataSource 单例对象。传入DataSource 的目的在于,JdbcTempate 会自己从 DataSource 中取 Connection 对象进行数据库操作。从而不再需要我们从 Service 层中传入 Connection 对象。

1.配置文件

 <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context
 http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
 
 <!-- for Service -->
 <context:component-scan base-package="xxx.yyy.zzz.service"/>
 <tx:annotation-driven transaction-manager="transactionManager"/>
 <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
  <property name="dataSource" ref="ds"/>
 </bean>
 <!-- for DAO -->
 <context:component-scan base-package="xxx.yyy.zzz.dao" />
 <bean id="ds" class="com.zaxxer.hikari.HikariDataSource" destroy-method="close">
     <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
     <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/scott? useUnicode=true&amp;characterEncoding=utf8&amp;useSSL=false&amp;serverTimezone=Asia/Shanghai"/>
     <property name="username" value="root"/>
     <property name="password" value="123456"/>
 </bean>
 <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
  <property name="dataSource" ref="ds"/>
 </bean>
 </beans>

2. Dao

 @Slf4j 
 @Repository
 public class DepartmentDAO {
     
  @Autowired
  private JdbcTemplate template;
     
 
  public void delete(int id) { 
         log.info("DAO: delete");
   template.update("delete from department where id = ?", id); 
         if (id % 2 == 0)
   throw new RuntimeException();
  }
 }

3.Spring-JDBC API:增删改

JdbcTemplate 为 DAO 中的 增删改操作提供了 .update 方法。

 public void demo1(){
         //增加
         System.out.println(jdbcTemplate.update("insert into department value(null,?,?)","hello","world"));
         //更新
         System.out.println(jdbcTemplate.update("update department set location=? where name=?", "1111", "hello"));
         //删除
         System.out.println(jdbcTemplate.update("delete from department where name=?", "hello"));
     }

4.Spring-JDBC API:查询

  /**
      * 实体类对象的字段名和数据库是一致或者是驼峰命名法都可以自动转换
      */
     @Test
     void demo2(){
         jdbcTemplate.query("select * from department", new BeanPropertyRowMapper<>         (DepartmentPo.class)).forEach(System.out::println);
     }
  /**
      * 手动映射
      */
     @Test
     void demo3(){
         List<DepartmentPo> query = jdbcTemplate.query("select * from department", (resultSet, n) -> {
             DepartmentPo departmentPo = new DepartmentPo();
             departmentPo.setId(resultSet.getInt(1));
             departmentPo.setName(resultSet.getString(2));
             departmentPo.setLocation(resultSet.getString(3));
             return departmentPo;
         });
         for (DepartmentPo departmentPo : query) {
             System.out.println(departmentPo);
         }
     }

在 JavaBean 的属性名与数据库名一致的情况下,Spring Jdbc 提供了自带的一个

BeanPropertyRowMapper 类,用于将 ResultSet 中的数据库数据「映射/转换」成 JavaBean 。

JdbcTemplate#queryForObject 方法有一个『问题』,由于涉及到 ResultSet 到 JavaBean 的转换, JdbcTemplate#queryForObject 方法强制要求查询结果『必须』有数据。如果你的 SQL 语句在数据库中查不到任何数据(也许本来就没有这样的一条数据),那么 JdbcTemplate#queryForObject 方法会抛出异常: EmptyResultDataAccessException 。

当然,你也可以全部使用 JdbcTemplate#query 方法查询,得到一个 List 后,再通过 List

List#size 方法的返回结果来确定查没查到数据,并进行后续处理。

5. 自定义映射结果集

对于数据库中的字段的名字与 JavaBean 的属性名『不一致』的情况,如果无法将其两者统一,那么在使用 .query 方法和 .queryForObject 方法时,就需要自己『定制』ResultSet 到 JavaBean 的转换规则, 即,实现 RowMapper 接口。

 template.query("...", (resultSet, n) -> { User user = new User(); 
     user.setUid(resultSet.getLong("uid"));
  user.setUsername(resultSet.getString("username"));
  user.setPassword(resultSet.getString("password")); 
     return user;
 });

spring-jdbc 会循环遍历 ResultSet,对于每一轮循环它将调用你这里的第二个参数,并将 ResultSet 和当前的『轮数』传入进去。

6.Spring Boot 中使用 spring-jdbc

   <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-data-jpa</artifactId>
         </dependency>

用法和前面一致

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值