使用Spring组件JDBC Template 简化持久化操作

为了简化持久化操作,Spring在JDBC API之上提供了JDBC Template组件. JDBC Template 是在JDBC API 基础上完成的. JDBC Template提供统一的模版方法,在保留代码灵活性的基础上,尽量减少持久化代码 JDBC Template 与 MyBatis

环境配置

配置spring-jdbc依赖

  1. <!-- 引入Spring jdbc -->
  2. <dependency>
  3. <groupId>org.springframework</groupId>
  4. <artifactId>spring-jdbc</artifactId>
  5. <version>${spring.version}</version>
  6. </dependency>
  7. <dependency>
  8. <groupId>org.springframework</groupId>
  9. <artifactId>spring-tx</artifactId>
  10. <version>${spring.version}</version>
  11. </dependency>

在applicationContext.xml进行配置jdbc template

<?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:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       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/aop
       http://www.springframework.org/schema/aop/spring-aop.xsd
       http://www.springframework.org/schema/tx
       http://www.springframework.org/schema/tx/spring-tx.xsd">

    <!-- 配置数据源 -->
    <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/t_jdbc_template?useUnicode=true&amp;characterEncoding=utf-8"/>
        <property name="username" value="root"/>
        <property name="password" value="root"/>
    </bean>

    <!-- 配置JDBC Template 设置数据源 -->
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="dataSource"/>
    </bean>

</beans>

基本操作

jdbc Template如何实现对数据增删改操作,如下所示:jdbcTemplate其实就是封装了jdbc


private JdbcTemplate jdbcTemplate;

    {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        //拿到jdbcTemplate
        jdbcTemplate = (JdbcTemplate) applicationContext.getBean("jdbcTemplate");
    }
    @Test
    public void testExecute() {
        //简化了jdbc的操作
        //execute
        jdbcTemplate.execute("create table user1(id int,name varchar(20))");
        //实现对数据对增删改操作
        //update 对数据增删改操作
        //插入一条数据
        int update = jdbcTemplate.update("insert into student(name, sex) values (?,?)", new Object[]{"张三", "男"});
        System.out.println("JdbcTest.testExecute" + update);

        //更新一条数据
        jdbcTemplate.update("update student set sex = ? where id=?", "女", 1);

        //batchUpdate 批量增删改操作
        jdbcTemplate.batchUpdate(new String[]{
                "insert into student(name, sex) values ('关羽','女')",
                "insert into student(name, sex) values ('刘备','男')",
                "update  student set sex='女' where id=3",
        });
        //另一种方式
        List<Object[]> list = new ArrayList<>();
        list.add(new Object[]{1, 1001});
        list.add(new Object[]{1, 1003});
        int[] ints = jdbcTemplate.batchUpdate("insert into elective(sid, cid) VALUES (?,?)",
                list);
    }

下面在来看一下查询操作: 如下使用都非常简单,如果要返回自己封装的实体对象需要实现RowMapper接口

    @Test
    public void testQuery() {
        //查询一个
        Integer integer = jdbcTemplate.queryForObject("select count(*) from student", Integer.class);
        System.out.println("JdbcTest.testQuery:" + integer);

        //查询多个
        List<String> stringList = jdbcTemplate.queryForList("select name from student where sex=?", String.class, "女");
        System.out.println("JdbcTest.testQuery:" + stringList);

        //查询复杂对象 Map
        //获取一个
        Map<String, Object> map = jdbcTemplate.queryForMap("select * from student where id=?", 2);
        System.out.println("JdbcTest.testQuery:" + map);

        //获取多个
        List<Map<String, Object>> maps = jdbcTemplate.queryForList("select * from student");
        System.out.println("JdbcTest.testQuery:" + maps);

        //复杂对象 封装为实体对象
        //RowMapper接口
        Student student = jdbcTemplate.queryForObject("select * from student where id=?", new StudentRowMapper(), 1);
        System.out.println("JdbcTest.testQuery:" + student);

        //查询多个对象 query
        List<Student> students = jdbcTemplate.query("select * from student", new StudentRowMapper());
        System.out.println("JdbcTest.testQuery:" + students);
    }
    private static class StudentRowMapper implements RowMapper<Student> {

        @Override
        public Student mapRow(ResultSet resultSet, int i) throws SQLException {
            Student student1 = new Student();
            student1.setId(resultSet.getInt("id"));
            student1.setName(resultSet.getString("name"));
            student1.setSex(resultSet.getString("sex"));
            student1.setBorn(resultSet.getDate("birthday"));
            return student1;
        }
    }

image.png

持久层

下面来看一下JdbcTemplate在持久层的应用,也是比较简单的和之前的JDBC类似

@Repository
public class StudentDaoImpl implements StudentDao {
    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Override
    public void insert(Student student) {
        String sql = "insert into student(name,sex,birthday) values(?,?,?)";
        jdbcTemplate.update(sql, student.getName(), student.getSex(), student.getBorn());
    }

    @Override
    public void update(Student student) {
        String sql = "update student set name=?,sex=?,birthday=? where id = ?";
        jdbcTemplate.update(sql, student.getName(), student.getSex(), student.getBorn(), student.getId());

    }

    @Override
    public void delete(int id) {
        String sql = "delete from student where id =?";
        jdbcTemplate.update(sql, id);
    }

    @Override
    public Student findOne(int id) {
        String sql = "select * from student where id=?";
        return jdbcTemplate.queryForObject(sql, new StudentRowMapper(), id);
    }

    @Override
    public List<Student> findAll() {
        String sql = "select * from student";
        return jdbcTemplate.query(sql, new StudentRowMapper());
    }

    private static class StudentRowMapper implements RowMapper<Student> {

        @Override
        public Student mapRow(ResultSet resultSet, int i) throws SQLException {
            Student student1 = new Student();
            student1.setId(resultSet.getInt("id"));
            student1.setName(resultSet.getString("name"));
            student1.setSex(resultSet.getString("sex"));
            student1.setBorn(resultSet.getDate("birthday"));
            return student1;
        }
    }
}

分析

Jdbc Template 简单灵活,但是SQL与Java代码参杂,功能不够丰富. 那么既然JDBC Template不够完美和强大,为什么还需要学习呢?

  1. JDBC Template是Spring对一个组件,是Spring对JDBC对封装.不需要集成直接可以使用.在一些简单的场合还尚有用武之地.
  2. JDBC Template的设计思想趋近于ORM(持久层框架),而MyBatis的设计思想是ORM,学习它有利于掌握MyBatis以及如何与Spring集成.
  3. 只需要进行了解,在未来的一些老代码中可能会遇到,学习还是有必要的.
  • 持久化操作特点
    • 必须
    • 机械性
  • ORM
    • 对象-关系 映射
  • JDBC Template是Spring框架对JDBC操作的封装,简单、灵活但不够强大
  • 实际应用中还需要和其他ORM框架混合使用