Spring JDBC框架概览

使用传统的JDBC连接数据库,需要编写不必要的代码来处理异常、打开和关闭数据库连接等变得非常麻烦。然而,Spring JDBC Framework从打开连接、准备和执行SQL语句、处理异常、处理事务以及最后关闭连接开始,负责所有低级别的细节。

因此,您需要做的就是定义连接参数并指定要执行的SQL语句,并在从数据库获取数据的同时为每个迭代执行所需的工作。

Spring JDBC提供了几种方法和相应不同的类来与数据库进行接口。我将采用经典且最流行的方法来使用框架的JdbcTemplate类。这是管理所有数据库通信和异常处理的中心框架类。

JdbcTemplate类

JDBC模板类执行SQL查询、更新语句、存储过程调用、对结果集执行迭代,并提取返回的参数值。它还捕获JDBC异常,并将其转换为org.springframework.dao中定义的通用的、信息更丰富的包。

一旦配置好,JdbcTemplate类的实例就是线程安全的。因此,您可以配置JdbcTemplate的一个实例,然后将这个共享引用安全地注入多个DAOs。

在使用JDBC模板类时,一个常见的做法是在Spring配置文件中配置一个数据源,然后将这个共享数据源bean注入到DAO类中,然后在数据源的setter中创建JdbcTemplate。

配置数据源

让我们在数据库测试中创建一个数据库表Student。我们假设您正在使用MySQL数据库,如果您使用任何其他数据库,那么您可以相应地更改DDL和SQL查询。

CREATE TABLE Student(
ID INT NOT NULL AUTO_INCREMENT,
NAME VARCHAR(20) NOT NULL,
AGE INT NOT NULL,
PRIMARY KEY (ID)
);

现在需要为JDBC模板提供一个DataSource,以便它可以进行配置获取数据库权限:

<bean id = "dataSource"
class = "org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name = "driverClassName" value = "com.mysql.jdbc.Driver"/>
<property name = "url" value = "jdbc:mysql://localhost:3306/TEST"/>
<property name = "username" value = "root"/>
<property name = "password" value = "password"/>
</bean>

数据访问对象(Data Access Object,DAO)

DAO表示数据访问对象,通常用于数据库交互。DAOs的存在是为了提供一种向数据库读写数据的方法,它们应该通过应用程序的其他部分访问它们的接口来公开此功能。

Spring中的DAO支持使得以一致的方式使用JDBC、Hibernate、JPA或JDO等数据访问技术变得很容易。

执行SQL命令

让我们看看如何使用SQL和JDBCTemplate对象对数据库表执行CRUD(创建、读取、更新和删除)操作。

org.springframework.jdbc.core.JdbcTemplate是JDBC核心包中的中心类。它简化了JDBC的使用,有助于避免常见错误。它执行核心JDBC工作流,让应用程序代码提供SQL并提取结果。这个类执行SQL查询或更新,在resultset上发起迭代,捕获JDBC异常,并将它们转换为org.springframework.dao中定义的更通用的、更有用的异常。

注:JdbcTemplate是线程安全的,关于线程安全,将会在后续的文章中加以介绍。

下面介绍使用到的方法,完整信息见Spring JdbcTemplate API Reference

Example

以下项目我使用Maven进行构建,创建Maven项目,更新pom.xml文件为以下内容

<?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">
<modelVersion>4.0.0</modelVersion> <groupId>top.ninwoo.spring</groupId>
<artifactId>build-demo</artifactId>
<version>1.0-SNAPSHOT</version> <dependencies>
<!-- Spring依赖 -->
<!-- 1.Spring核心依赖 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.1.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>4.1.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.1.7.RELEASE</version>
</dependency>
<!-- 2.Spring dao依赖 -->
<!-- spring-jdbc包括了一些如jdbcTemplate的工具类 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>4.1.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>4.1.7.RELEASE</version>
</dependency>
<!-- 3.Spring web依赖 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>4.1.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.1.7.RELEASE</version>
</dependency>
<!-- 4.Spring test依赖:方便做单元测试和集成测试 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
</dependency> <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>6.0.6</version>
</dependency>
</dependencies>
</project>
  • StudentDAO.java : 定义Student数据接口
public interface StudentDAO {
/**
* This is the method to be used to initialize
* database resources ie. connection.
*/
public void setDataSource(DataSource ds); /**
* This is the method to be used to create
* a record in the Student table.
*/
public void create(String name, Integer age); /**
* This is the method to be used to list down
* a record from the Student table corresponding
* to a passed student id.
*/
public Student getStudent(Integer id); /**
* This is the method to be used to list down
* all the records from the Student table.
*/
public List<Student> listStudents(); /**
* This is the method to be used to delete
* a record from the Student table corresponding
* to a passed student id.
*/
public void delete(Integer id); /**
* This is the method to be used to update
* a record into the Student table.
*/
public void update(Integer id, Integer age);
}
  • Student.java : Student类
public class Student {
private Integer age;
private String name;
private Integer id; public void setAge(Integer age) {
this.age = age;
}
public Integer getAge() {
return age;
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setId(Integer id) {
this.id = id;
}
public Integer getId() {
return id;
}
}
  • StudentMapper.java : 将数据库条目映射到Student对象,关于RowMapper接口的介绍将在文末进行补充。
public class StudentMapper implements RowMapper<Student> {
public Student mapRow(ResultSet rs, int rowNum) throws SQLException {
Student student = new Student();
student.setId(rs.getInt("id"));
student.setName(rs.getString("name"));
student.setAge(rs.getInt("age")); return student;
}
}

这是一个函数接口,因此可以用作lambda表达式或方法引用的赋值目标。

RowMapper必须实现mapRow方法来映射ResultSet中的每一行数据。这个方法不应该调用ResultSet上的next();它只应该映射当前行的值。

@Nullable
T mapRow(java.sql.ResultSet rs,
int rowNum)
throws java.sql.SQLException
Parameters:
rs - the ResultSet to map (pre-initialized for the current row)
rowNum - the number of the current row
Returns:
the result object for the current row (may be null)
Throws:
java.sql.SQLException - if a SQLException is encountered getting column values (that is, there's no need to catch SQLException)
  • StudentJDBCTemplate.java : Student数据接口的具体实现
public class StudentJDBCTemplate implements StudentDAO {
private DataSource dataSource;
private JdbcTemplate jdbcTemplateObject; public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
this.jdbcTemplateObject = new JdbcTemplate(dataSource);
}
public void create(String name, Integer age) {
String SQL = "insert into Student (name, age) values (?, ?)";
jdbcTemplateObject.update( SQL, name, age);
System.out.println("Created Record Name = " + name + " Age = " + age);
return;
}
public Student getStudent(Integer id) {
String SQL = "select * from Student where id = ?";
Student student = jdbcTemplateObject.queryForObject(SQL,
new Object[]{id}, new StudentMapper()); return student;
}
public List<Student> listStudents() {
String SQL = "select * from Student";
List <Student> students = jdbcTemplateObject.query(SQL, new StudentMapper());
return students;
}
public void delete(Integer id) {
String SQL = "delete from Student where id = ?";
jdbcTemplateObject.update(SQL, id);
System.out.println("Deleted Record with ID = " + id );
return;
}
public void update(Integer id, Integer age){
String SQL = "update Student set age = ? where id = ?";
jdbcTemplateObject.update(SQL, age, id);
System.out.println("Updated Record with ID = " + id );
return;
}
}

构造函数:

  • JdbcTemplate()
  • JdbcTemplate(javax.sql.DataSource dataSource)

update:

public int update(java.lang.String sql,
@Nullable
java.lang.Object... args)
throws DataAccessException

queryForObject

<T> T queryForObject(java.lang.String sql,
java.lang.Object[] args,
RowMapper<T> rowMapper)
throws DataAccessException
  • MainApp.java : 主函数
import java.util.List;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.tutorialspoint.StudentJDBCTemplate; public class MainApp {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml"); StudentJDBCTemplate studentJDBCTemplate =
(StudentJDBCTemplate)context.getBean("studentJDBCTemplate"); System.out.println("------Records Creation--------" );
studentJDBCTemplate.create("Zara", 11);
studentJDBCTemplate.create("Nuha", 2);
studentJDBCTemplate.create("Ayan", 15); System.out.println("------Listing Multiple Records--------" );
List<Student> students = studentJDBCTemplate.listStudents(); for (Student record : students) {
System.out.print("ID : " + record.getId() );
System.out.print(", Name : " + record.getName() );
System.out.println(", Age : " + record.getAge());
} System.out.println("----Updating Record with ID = 2 -----" );
studentJDBCTemplate.update(2, 20); System.out.println("----Listing Record with ID = 2 -----" );
Student student = studentJDBCTemplate.getStudent(2);
System.out.print("ID : " + student.getId() );
System.out.print(", Name : " + student.getName() );
System.out.println(", Age : " + student.getAge());
}
}
  • Beans.xml
<?xml version = "1.0" encoding = "UTF-8"?>
<beans xmlns = "http://www.springframework.org/schema/beans"
xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation = "http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd "> <!-- Initialization for data source -->
<bean id="dataSource"
class = "org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name = "driverClassName" value = "com.mysql.jdbc.Driver"/>
<property name = "url" value = "jdbc:mysql://localhost:3306/TEST"/>
<property name = "username" value = "root"/>
<property name = "password" value = "password"/>
</bean> <!-- Definition for studentJDBCTemplate bean -->
<bean id = "studentJDBCTemplate"
class = "com.tutorialspoint.StudentJDBCTemplate">
<property name = "dataSource" ref = "dataSource" />
</bean> </beans>
  • 输出
------Records Creation--------
Created Record Name = Zara Age = 11
Created Record Name = Nuha Age = 2
Created Record Name = Ayan Age = 15
------Listing Multiple Records--------
ID : 1, Name : Zara, Age : 11
ID : 2, Name : Nuha, Age : 2
ID : 3, Name : Ayan, Age : 15
----Updating Record with ID = 2 -----
Updated Record with ID = 2
----Listing Record with ID = 2 -----
ID : 2, Name : Nuha, Age : 20

Spring入门学习笔记(4)——JDBC的使用的更多相关文章

  1. [Spring入门学习笔记][静态资源]

    遗留问题 在上一节课的作业中,我们一定遇到了一点问题——虽然将页面内容正确的返回给了浏览器,但是浏览器显示的样式却是不正确的,这是因为在HTML的\标签中我们这样引入了CSS资源: <link ...

  2. [Spring入门学习笔记][创建网站URL]

    设计网站的URL 现代的Web站点都会设计一套拥有明确意义,方便用户记忆的URL,不论是域名还是路径,以天码营为例: http://tianmaying.com/courses表示网站下所有的课程列表 ...

  3. [spring入门学习笔记][spring的IoC原理]

    什么叫IoC 控制反转(Inversion of Control,缩写为IoC),是面向对象编程中的一种设计原则,可以用来减低计算机代码之间的耦合度.其中最常见的方式叫做依赖注入(Dependency ...

  4. [Spring入门学习笔记][Spring Boot]

    什么是Spring Boot Spring Boot正是在这样的一个背景下被抽象出来的开发框架,它本身并不提供Spring框架的核心特性以及扩展功能,只是用于快速.敏捷地开发新一代基于Spring框架 ...

  5. Spring入门学习笔记(1)

    目录 Spring好处 依赖注入 面向面编程(AOP) Spring Framework Core Container Web Miscellaneous 编写第一个程序 IoC容器 Spring B ...

  6. [Spring入门学习笔记][Spring的AOP原理]

    AOP是什么? 面向切面编程 软件工程有一个基本原则叫做“关注点分离”(Concern Separation),通俗的理解就是不同的问题交给不同的部分去解决,每部分专注于解决自己的问题.这年头互联网也 ...

  7. Spring入门学习笔记(3)——事件处理类

    目录 Spring中的事件处理 Spring内建事件 监听Context事件 Example 自定义Spring事件 Spring中的事件处理 ApplicationContext 是Spring的核 ...

  8. Spring入门学习笔记(2)——基于Java的配置

    目录 基于Java的配置 @Configuration & @Bean Annotations Example 注入Bean依赖 @Import注解 Lifecycle Callbacks(声 ...

  9. [Spring入门学习笔记][maven]

    什么是maven? 我的理解: 一个项目有一大堆依赖包的时候,没必要下下来,可以利用maven中的pom.xml 指定需要那些依赖包,让maven去本地中央库(如果没找到)->网上仓库库帮你调用 ...

随机推荐

  1. java面向切面编程总结-面向切面的本质

    面向切面的本质:定义切面类并将切面类的功能织入到目标类中: 实现方式:将切面应用到目标对象从而创建一个新的代理对象的过程.替换: 使用注解@Aspect来定义一个切面,在切面中定义切入点(@Point ...

  2. 常用的npm命令

    npm ls -g 列出全局安装的所有模块 npm ls webpack -g 查看全局安装的模块版本信息 npm view webpack versions 查看npm服务器上的全部版本信息 npm ...

  3. leetcode 217. Contains Duplicate 287. Find the Duplicate Number 442. Find All Duplicates in an Array 448. Find All Numbers Disappeared in an Array

    后面3个题都是限制在1-n的,所有可以不先排序,可以利用巧方法做.最后两个题几乎一模一样. 217. Contains Duplicate class Solution { public: bool ...

  4. 模糊控制——(4)Sugeno模糊模型

    1.Sugeno模糊模型 传统的模糊系统为Mamdani模糊模型,输出为模糊量. Sugeno模糊模型输出隶属函数为constant或linear,其函数形式为: 它与Mamdani模型的区别在于: ...

  5. JDBC 使用common-dbutiles

    一:第三方jar mysql-connector-java-5.1.45-bin.jar,需要关注的核心类: 1.DbUtils----操作数据库的连接注册和释放. 2:.QueryRunner--- ...

  6. Appium移动自动化测试(一)--Mac安装Appium

    一.Appium安装 1. 直接安装:Appium官网下载:https://bitbucket.org/appium/appium.app/downloads/ 这里mac系统升级到 Sierra后, ...

  7. js遍历添加栏目类添加css 再点击其它删除css

    //js遍历添加栏目类添加css 再点击其它删除css $(".radio-group .ckselect").each(function(index) { $(this).cli ...

  8. bootstrap-treeview使用

    1.数据 var tree = [{ text: "车型A", nodes: [{ text: "车系1", }, { text: "车系2" ...

  9. 嵌入式C语言自我修养 02:Linux 内核驱动中的指定初始化

    2.1 什么是指定初始化 在标准 C 中,当我们定义并初始化一个数组时,常用方法如下: ] = {,,,,,,,,}; 按照这种固定的顺序,我们可以依次给 a[0] 和 a[8] 赋值.因为没有对 a ...

  10. 【11.18总结】从SAML出发在重定向中发现的XSS漏洞

    Write-up地址:How I Discovered XSS that Affects around 20 Uber Subdomains 作者:fady mohammed osman 总算回家了, ...