专栏首页程序猿的大杂烩Spring对JDBC的模板支持——JdbcTemplate

Spring对JDBC的模板支持——JdbcTemplate

Spring的JdbcTemplate是一个对JDBC的模板封装,它提供了一套JDBC的模板,能让我们写持久层代码时减少多余的代码,简化JDBC代码,使代码看起来更简洁。在介绍Spring的JdbcTemplate使用方法之前我们先来讨论一个问题,以下这是一段常见的往数据库写入数据的JDBC代码:

    public int jdbcInsert(Student student) throws SQLException {

        Connection connection = null;

        try {
            connection = dataSource.getConnection();

            String sql = "INSERT INTO student(sname,age,sex,address) VALUES (?,?,?,?)";
            PreparedStatement preparedStatement = connection.prepareStatement(sql);
            preparedStatement.setString(1, student.getName());
            preparedStatement.setInt(2, student.getAge());
            preparedStatement.setString(3, student.getSex());
            preparedStatement.setString(4, student.getAddress());

            return preparedStatement.executeUpdate();
        } finally {
            connection.close();
        }
    }

    public int jdbcUpdate(Student student) throws SQLException {

        Connection connection = null;

        try {
            connection = dataSource.getConnection();

            String sql = "UPDATE student SET sname=?,age=?,sex=?,address=?";
            PreparedStatement preparedStatement = connection.prepareStatement(sql);
            preparedStatement.setString(1, student.getName());
            preparedStatement.setInt(2, student.getAge());
            preparedStatement.setString(3, student.getSex());
            preparedStatement.setString(4, student.getAddress());

            return preparedStatement.executeUpdate();
        } finally {
            connection.close();
        }
    }

从如上的代码中,可以看到两个方法中基本99%的代码都是重复的,除了sql语句之外,都是重复的代码,重复的代码就是坏味道,会让我们的产生大量的冗余代码,不易于维护和修改,而且写起来还累。

所以Spring提供的JdbcTemplate正是用来解决这个问题的,其实Spring的JDBCTemplate有点像DBUtils,但是有时候还没有DBUitls好用。这里来学习一下使用Spring的JdbcTemplate来玩一下CRUD,毕竟JdbcTemplate在实际开发中一般不会使用,通常都是使用Mybatis、Hibernate等成熟、优秀的数据持久层框架,不过还是得知道Spring有一个这样的jdbc模板类。

Spring对不同的持久化支持:

Spring可不单止支持JDBC,Spring为各种支持的持久化技术,都提供了简单操作的模板和回调:

ORM持久化技术

模板类

JDBC

org.springframework.jdbc.core.JdbcTemplate

Hibernate5.0

org.springframework.orm.hibernate5.HibernateTemplate

IBatis(MyBatis)

org.springframework.orm.ibatis.SqlMapClientTemplate

JPA

org.springfrmaework.orm.jpa.JpaTemplate

使用JdbcTemplate需要配置的依賴:

    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>4.3.14.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>4.3.14.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.39</version>
        </dependency>
        <dependency>
            <groupId>com.mchange</groupId>
            <artifactId>c3p0</artifactId>
            <version>0.9.5.2</version>
        </dependency>
    </dependencies>

使用JdbcTemplate的基本步骤:

  1. 配置Spring的配置文件,內容如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:context="http://www.springframework.org/schema/context"
       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
       ">

    <context:annotation-config/>
    <context:component-scan base-package="org.zero01"/>

    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
          p:driverClass="com.mysql.jdbc.Driver"
          p:jdbcUrl="jdbc:mysql:///school"
          p:user="root"
          p:password="Zero-One1."
          p:loginTimeout="2000"
          p:maxPoolSize="10"
          p:minPoolSize="1"
    />
</beans>
  1. 创建数据库表格字段封装类:
package org.zero01.pojo;

import org.springframework.stereotype.Component;

@(JavaWeb)Component("stu")
public class Student {

    private int sid;
    private String name;
    private int age;
    private String sex;
    private String address;

    public int getSid() {
        return sid;
    }

    public void setSid(int sid) {
        this.sid = sid;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }
}
  1. 编写dao类:
package org.zero01.dao;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;
import org.zero01.pojo.Student;

import javax.sql.DataSource;

@Component("stuDAO")
public class StudentDAO {

    @Autowired
    private DataSource dataSource;

    public int springInsert(Student student) {
        // 实例化jdbc模板对象,并传入数据源
        JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
        String sql = "INSERT INTO student(sname,age,sex,address) VALUES (?,?,?,?)";
        // 调用update方法执行insert
        int row = jdbcTemplate.update(sql, student.getName(), student.getAge(), student.getSex(), student.getAddress());
        return row;
    }
}

可以看到,使用了JdbcTemplate之后,只需要写sql语句再调用相应的执行方法即可,不需要去关心数据库连接对象的获得、关闭以及减少了大量设置值的代码。

而且以上只是其中一种写法,我们还可以直接继承JdbcTemplate,这样就可以直接调用父类的方法了:

package org.zero01.dao;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;
import org.zero01.pojo.Student;

import javax.sql.DataSource;

@Component("stuDAO")
public class StudentDAO extends JdbcTemplate {

    @Autowired
    // 重写父类的setDataSource来设置数据源对象
    public void setDataSource(DataSource dataSource) {
        super.setDataSource(dataSource);
    }

    public int springInsert(Student student) {
        String sql = "INSERT INTO student(sname,age,sex,address) VALUES (?,?,?,?)";
        // 直接调用父类的方法即可
        int row = update(sql, student.getName(), student.getAge(), student.getSex(), student.getAddress());
        return row;
    }
}

以下通过JdbcTemplate来编写一个简单的增删查改小例题:

接口:

package org.zero01.dao;

import org.zero01.pojo.Student;

import java.util.List;

public interface DAO {

    public int insert(Student student);

    public int delete(int sid);

    public List<Student> selectAll();

    public List<Student> selectByLimit(int start, int end);

    public Student selectById(int sid);

    public long countAll();

    public int update(Student student);
}

因为JdbcTemplate不提供表格字段自动映射到对象的属性上的功能,所以我们需要自己实现它的一个接口来进行手动配置映射:

package org.zero01.dao;

import org.springframework.jdbc.core.RowMapper;
import org.zero01.pojo.Student;

import java.sql.ResultSet;
import java.sql.SQLException;

// Student对象的属性映射类
public class StudentMapper implements RowMapper<Student> {

    public Student mapRow(ResultSet resultSet, int i) throws SQLException {
        Student student = new Student();
        student.setSid(resultSet.getInt("sid"));
        student.setName(resultSet.getString("sname"));
        student.setAge(resultSet.getInt("age"));
        student.setSex(resultSet.getString("sex"));
        student.setAddress(resultSet.getString("address"));

        return student;
    }
}

StudentDAO类:

package org.zero01.dao;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;
import org.zero01.pojo.Student;

import javax.sql.DataSource;
import java.util.List;

@Component("stuDAO")
public class StudentDAO extends JdbcTemplate implements DAO {

    @Autowired
    // 重写父类的setDataSource来设置数据源对象
    public void setDataSource(DataSource dataSource) {
        super.setDataSource(dataSource);
    }

    // 插入单行数据
    public int insert(Student student) {
        String sql = "INSERT INTO student(sname,age,sex,address) VALUES (?,?,?,?)";
        int row = update(sql, student.getName(), student.getAge(), student.getSex(), student.getAddress());

        return row;
    }

    // 根据id进行删除
    public int delete(int sid) {
        return update("DELETE FROM student WHERE sid=?", sid);
    }

    // 查询多行数据
    public List<Student> selectAll() {

        // 查询多个对象就需要自己传递映射类进行映射
        List<Student> studentList = query("SELECT * FROM student", new StudentMapper());

        return studentList;
    }

    // 分页查询数据
    public List<Student> selectByLimit(int start, int end) {

        // 查询多个对象就需要自己传递映射类进行映射
        List<Student> studentList = query("SELECT * FROM student LIMIT " + start + "," + end, new StudentMapper());

        return studentList;
    }

    // 根据id查询单行数据
    public Student selectById(int sid) {
        // 存储参数
        Object[] objects = {sid};
        Student student = queryForObject("SELECT * FROM student where sid=?", objects, new StudentMapper());

        return student;
    }

    // 查询表的总行数
    public long countAll() {
        Long countNumber = queryForObject("SELECT count(*) FROM student", Long.class);

        return countNumber;
    }

    // 更新单行数据
    public int update(Student student) {
        String sql = "UPDATE student SET sname=?,age=?,sex=?,address=? WHERE sid=?";
        return update(sql, student.getName(), student.getAge(), student.getSex(), student.getAddress(), student.getSid());
    }
}

如上,可以看到,通过使用Spring提供的JdbcTemplate,我们只需要编写具体的sql语句即可,比起编写普通的JDBC代码要简洁许多,也没有出现多余的代码。当项目不需要使用到Mybatis、Hibernate等框架时,使用JdbcTemplate也不错。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 面向切面的Spring

    转眼间,快到夏天了,又让我想起来往年盛夏时,被空调、西瓜、冰淇淋支配的恐惧,南方的天气是真的热,在这种天气下,西瓜、冰淇淋可以没有,但是空调是必不可少的。但是空...

    端碗吹水
  • Spring使用注解配置依赖注入

    大部分情况下,使用Spring配置依赖注入时,都是使用注解来进行配置,因为注解比xml要方便和简单。不过类似于数据源对象这种配置信息容易变更的对象除外,这种对象...

    端碗吹水
  • Spring的事务管理

    Spring有一个基于AOP之上的事务管理模块,这个模块能够帮助我们在逻辑层中很方便的控制数据库的事务。在此之前我们介绍了Spring对JDBC的模板支持 以及...

    端碗吹水
  • 面向切面的Spring

    转眼间,快到夏天了,又让我想起来往年盛夏时,被空调、西瓜、冰淇淋支配的恐惧,南方的天气是真的热,在这种天气下,西瓜、冰淇淋可以没有,但是空调是必不可少的。但是空...

    端碗吹水
  • Spring使用注解配置依赖注入

    大部分情况下,使用Spring配置依赖注入时,都是使用注解来进行配置,因为注解比xml要方便和简单。不过类似于数据源对象这种配置信息容易变更的对象除外,这种对象...

    端碗吹水
  • 缓存服务的更新策略有哪些?

    在互联网项目开发中,缓存的应用是非常普遍了,缓存可以帮助页面提高加载速度,减少服务器或数据源的负载。

    纯洁的微笑
  • 缓存服务的更新策略有哪些?

    一般在项目中,最消耗性能的地方就是后端服务的数据库了。而数据库的读写频率常常都是不均匀分布的,大多情况是读多写少,并且读操作(select)还会有一些复杂的判断...

    奎哥
  • 突破Java面试(27)-如何保证缓存与数据库的数据一致性

    你只要用缓存,就可能会涉及到缓存与数据库双存储双写,你只要是双写,就一定会有数据一致性的问题,那么你如何解决一致性问题?

    JavaEdge
  • 关于Redis的几件小事 | 缓存与数据库双写时的数据一致性

    这是最经典的 缓存+数据库 读写模式,操作如下: ①读的时候,先读缓存,缓存没有就读数据库,然后将取出的数据放到缓存,同时返回请求响应。

    暴走大数据
  • C++快速补天

    (2)int型范围:-2^31~(2^31)-1,大致范围在-2*10^9~2*10^9(占用32bit/4Byte)

    lollipop72

扫码关注云+社区

领取腾讯云代金券