第七章 JdbcTemplate

时间:2021-6-4 作者:qvyue

target

理解为什么会有JdbcTemplate的出现
掌握 JdbcTemplate 的三种使用方式
掌握JdbcTemplate 常用API

1. 概述

JDBC已经能够满足大部分用户最基本的需求,但是在使用JDBC时,必须自己来管理数据库资源如:获取PreparedStatement,设置SQL语句参数,关闭连接等步骤。Spring对JDBC进行了封装,简化了JDBC的相关操作,这就是JdbcTemplate:

  • JdbcTemplate是Spring对JDBC的封装,目的是使JDBC更加易于使用。

  • JdbcTemplate是Spring的一部分,处理了资源的建立和释放。

  • 他帮助我们避免一些常见的错误,比如忘了总要关闭连接。

  • 他运行核心的JDBC工作流,如Statement的建立和执行,而我们只需要提供SQL语句和提取结果。

2. 使用

2.1 搭建环境

① 导入jar

 commons-dbcp-1.4.jar
 commons-logging-1.2.jar
 commons-pool-1.6.jar
 mysql-connector-java-8.0.15.jar
 spring-beans-4.3.9.RELEASE.jar
 spring-context-4.3.9.RELEASE.jar
 spring-core-4.3.9.RELEASE.jar
 spring-expression-4.3.9.RELEASE.jar
 spring-jdbc-4.3.9.RELEASE.jar
 spring-tx-4.3.9.RELEASE.jar

② 数据库相关

准备好数据库及模拟的数据:

  • 创建数据库
create database test;
  • 使用数据库
use test;
  • 创建表
create table user(
 id int primary key auto_increment,
 username varchar(30),
 password varchar(30)
)
  • 插入数据
insert into user(username,password) values('jerry','jerry1234');
insert into user(username,password) values('grace','grace1234');

③ 实体类

新建实例类,对数据库里的字段进行封装:

package com.lee.spring.bean;

public class User {
    private int id;
    private String name;
    private String password;
}

2.2 三种使用方式

jdbcTemplate提供了三种实现方式,根据自己的需求去选择合适的方式使用:

① 纯手写方式使用JdbcTemplate(不推荐)

直接在测试方法中进行测试即可:

@Test
public void test01() {
  //1.创建数据源
  BasicDataSource dataSource = new BasicDataSource();
  dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
  dataSource.setUrl("jdbc:mysql://localhost:3306/test?useSSL=false&characterEncoding=utf-8");
  dataSource.setUsername("root");
  dataSource.setPassword("root");

  //2.创建模板
  JdbcTemplate jdbcTemplate = new JdbcTemplate();
  jdbcTemplate.setDataSource(dataSource);

  //3.使用API
  String sql = "insert into user(username,password) values(?,?)";
  jdbcTemplate.update(sql , "rose" , "rose1234");
}

查看数据库,发现成功插入数据:

第七章 JdbcTemplate

这种方式是不推荐的,因为数据源的操作全部是手工编码的,尤其是数据库连接相关操作一定是放在配置文件中才是最佳的。

② 使用IoC注入方式

Dbcp数据源

  • jar包:

    commons-dbcp-1.4.jar

    commons-pool-1.6.jar

  • Dao层:

    public class UserDao {

    private JdbcTemplate jdbcTemplate;

    public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }

    public void updateUser( User user) {
        String sql = "update user set username = ? ,password=? where id = ?";
        Object[] orgs = {user.getName(),user.getPassword(),user.getId()};
        jdbcTemplate.update(sql , orgs);
    }
}

需要注意:在 Dao中需要提供jdbcTemplate和他的setter方法。

  • 配置文件:

  • 测试:
 @Test
public void test02() {
  ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
  UserDao userDao =(UserDao) context.getBean("userDao");
  User user = new User();
  user.setId(1);
  user.setName("杰瑞");
  user.setPassword("admin");
  userDao.updateUser(user );
}

除了使用Dbcp数据源,还可以使用c3p0数据源实现:

  • jar包

    c3p0-0.9.5.2.jar

    mchange-commons-java-0.2.20.jar

  • 配置文件


③ 继承JdbcDaoSupport方式

上面的方法,我们每一个dao类都需要一个JdbcTemplate属性。Spring已经为JdbcTemplate做了封装,直接继承JdbcDaoSupport就可以调用已经封装好的JdbcTemplate。

第一步:dao类继承JdbcDaoSupport

public class UserDao extends JdbcDaoSupport {

    public List> findAll(){
        String sql = "select * from user";
        List> list = this.getJdbcTemplate().queryForList(sql);
        return list;
    }
}

第二步:配置文件删掉JdbcTemplate的注入,直接把数据源注入给dao


测试:

@Test
public void test03() {
  ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
  UserDao userDao =(UserDao) context.getBean("userDao");
  List> all = userDao.findAll();
  System.out.println(all);
}

2.3 properties使用

一般情况下,我们会把数据库相关信息在一个单独的文件中配置,可以使用properties。

在src下新建db.properties:

jdbc.driverClass=com.mysql.cj.jdbc.Driver
jdbc.jdbcUrl=jdbc:mysql://localhost:3306/test
jdbc.user=root
jdbc.password=root

编写Spring配置文件applicationContext.xml:

直接使用 $ 获取db.properties中的值


注意:

如果数据库连接失败,可以在相应的属性前加 jdbc.

3. API

JdbcTemplate常用的API如下:

3.1 配置类表映射

有时候数据表的字段和实体类的属性不是一一对应的,需要手动进行匹配。怎么匹配?通过实现RowMapper接口。

🌰

UserMapper的作用就是对user数据表的字段和User类的属性匹配:

package com.lee.spring.dao;

public class UserMapper implements RowMapper {

    @Override
      public User mapRow(ResultSet rs, int rowNum) throws SQLException {
        User user = new User();
        user.setId(rs.getInt("id"));
        user.setName(rs.getString("username"));
        user.setPassword(rs.getString("password"));
        return user;
      }
}

在Dao里进行查询:

查询单个用户使用queryForObject()方法,查询多个用户使用query()方法

package com.lee.spring.dao;

public class UserDao extends JdbcDaoSupport {
    
    //  查询单个用户
    public User getUserById(int id) {
        String sql = "select * from user where id = " + id;
        User user = this.getJdbcTemplate().queryForObject(sql, new UserMapper());
        return user;
    }
    
    //  查询多个用户
    public List getAllUsers() {
        String sql = "select * from user";
        List allUsers = this.getJdbcTemplate().query(sql, new UserMapper());
        return allUsers;
    }
}

编写测试类进行测试:

@Test
public void test04() {
  ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
  UserDao userDao =(UserDao) context.getBean("userDao");
  User user = userDao.getUserById(1);
  System.out.println(user);
}

@Test
public void test05() {
  ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
  UserDao userDao =(UserDao) context.getBean("userDao");
  List allUsers = userDao.getAllUsers();
  System.out.println(allUsers);
}

3.2 query相关方法

方法 描述 参数 返回值
queryForObject(String sql, RowMapper rowMapper) 查询单个对象,以对象方式返回 第一个参数:执行的查询语句 第二个参数:一个映射类对象(比如UserMapper) T
queryForMap(String sql) 查询单个对象,以map方式返回 执行的查询语句 Map
query(String sql, RowMapper rowMapper) 查询多个对象,返回值为List 第一个参数:执行的查询语句 第二个参数:一个映射类对象(比如UserMapper) List
queryForList(String sql) 查询你多个对象,返回值为List

>
执行的查询语句 List

>

🌰

package com.lee.spring.dao;

public class UserDao extends JdbcDaoSupport {

    // queryForObject:查询单个对象,以对象方式返回
        public User queryForObject(int id) {
            String sql = "select * from user where id = " + id;
            User user = this.getJdbcTemplate().queryForObject(sql, new UserMapper());
            return user;
        }
        
        // queryForMap:查询单个对象,以map方式返回
        public Map queryForMap(int id) {
            String sql = "select * from user where id = " + id;
            Map map = this.getJdbcTemplate().queryForMap(sql);
            return map;
        }
        
    // query(String sql, RowMapper rowMapper):查询多个对象,返回值为List
        public List queryAll() {
            String sql = "select * from user";
            List allUsers = this.getJdbcTemplate().query(sql, new UserMapper());
            return allUsers;
        }
    
    // queryForList(String sql):查询多个对象,以List>返回
    public List> queryForList(){
        String sql = "select * from user";
        List> list = this.getJdbcTemplate().queryForList(sql);
        return list;
    }
}

编写测试类测试:

@Test
public void test06() {
  ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
  UserDao userDao =(UserDao) context.getBean("userDao");
  Map map = userDao.queryForMap(1);
  System.out.println(map);
  System.out.println("-------------------------");
  
  User user = userDao.queryForObject(1);
  System.out.println(user);
  System.out.println("-------------------------");
  
  List all = userDao.queryAll();
  System.out.println(all);
  System.out.println("-------------------------");
  
  List> list = userDao.queryForList();
  System.out.println(list);
}

3.3 update

方法:update(String sql, Object… args)

其中,args为更新的参数

作用:更新、修改、删除操作,返回受影响的行数 .

🌰

package com.lee.spring.dao;

public class UserDao extends JdbcDaoSupport {

    public int updateUser( User user) {
        String sql = "update user set username = ? ,password=? where id = ?";
        Object[] orgs = {user.getName(),user.getPassword(),user.getId()};
        int i = this.getJdbcTemplate().update(sql , orgs);
        return i;
    }
}

测试:

@Test
public void test07() {
  ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
  UserDao userDao =(UserDao) context.getBean("userDao");
  User user = new User();
  user.setId(1);
  user.setName("杰瑞");
  user.setPassword("admin");
  userDao.updateUser(user );
}

3.4 batchUpdate

方法:batchUpdate(SQL语句1,SQL语句2….);

作用:执行批量操作,可以是批量更新、批量插入、批量删除,参数为string数组

返回值:整形数组。数组中数字表示相应的SQL语句影响的行数。

🌰

package com.lee.spring.dao;

public class UserDao extends JdbcDaoSupport {

    public int[] batch() {
        String sql1 = "delete from  user";
        String sql2 = "insert into user values(1,'aa','aa123'),(2,'bb','bb123')";
        String sql3 = "update user set password = 'admin' where id =1";
        int[] nums = this.getJdbcTemplate().batchUpdate(sql1,sql2,sql3);
        return nums;
    }   
}

测试:

@Test
public void test08() {
  ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
  UserDao userDao =(UserDao) context.getBean("userDao");
  int[] batch = userDao.batch();
  for (int i : batch) {
    System.out.println(i);
  }
}
声明:本文内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:qvyue@qq.com 进行举报,并提供相关证据,工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。