JdbcTemplate

一. 概述

JdbcTemplate就是Spring对JDBC的封装,目的是使JDBC更加易于使用。JdbcTemplate是Spring的一部分。

JdbcTemplate处理了资源的建立和释放。他帮助我们避免一些常见的错误,比如忘了总要关闭连接。他运行核心的JDBC工作流,如PreparedStatement的建立和执行,而我们只需要提供SQL语句和提取结果。

二.jdbcTemplate核心API

方法作用
public JdbcTemplate(DataSource dataSource)构造方法,传递数据源做为参数
int update(String sql, Object…args)执行增删改
queryForMap()返回Map<String,Object>的查询结果,其中键是列名,值是表中对应的记录。
queryForObject()查询一个对象
queryForList()返回多条记录的查询结果,封装成一个List集合,但是封装的是Map
query()通用的查询方法,有多个同名方法的重载,可以自定义查询结果集封装成什么样的对象。

三.使用jdbcTemplate完成CRUD

1.开发步骤

  • 创建项目,导入jar
    在这里插入图片描述
  • 创建jdbcTemplate对象,传入连接池
  • 调用execute()、update()、queryXxx()等方法

2.JdbcTemplate实现增删改

API介绍

public int update(String sql, Object ... params);  //用于执行`INSERT`、`UPDATE`、`DELETE`等语句。
    @Test
    //使用JDBC模版进行添加用户
    public void fun01() {
        //1.创建jdbcTemplate对象(需要传入连接池)
        JdbcTemplate jdbcTemplate = new JdbcTemplate(C3p0Utils.getDataSource());
        //2.使用update,执行sql
        String sql = "insert into user values(?,?,?,?)";
//        Object[] params = {null, "tq", "123456", "田七"};
//        jdbcTemplate.update(sql, params);
        jdbcTemplate.update(sql, null, "tq", "123456", "田七");
    }
    @Test
    //使用JDBC模板进行更新用户,把id为7的用户的名字改成ww
    public void fun02() {
        //1.创建jdbcTemplate对象
        JdbcTemplate jdbcTemplate = new JdbcTemplate(C3p0Utils.getDataSource());
        //2.使用update,执行sql
//        jdbcTemplate.update("UPDATE user set username = 'ww' WHERE id = 7");
        String sql = "UPDATE USER set username = ? WHERE id = ?";
        Object[] params = {"ww", 7};
        jdbcTemplate.update(sql, params);
    }
    @Test
    //使用JDBC模版进行删除用户
    public void fun03() {
        JdbcTemplate jdbcTemplate = new JdbcTemplate(C3p0Utils.getDataSource());
        jdbcTemplate.update("delete from user where id = ?",7);
    }

3. JdbcTemplate实现查询

3.1 查询一条记录封装成Map

  • 需求: 查询id为1的用户, 封装成map对象
  • 开发步骤:
    创建JdbcTemplate对象,传入数据源
    编写SQL语句
    使用JdbcTemplate对象的==queryForMap(String sql,Object … params)==方法查询结果
    返回是一个Map对象
    @Test
    //查询id为1的用户,封装成map对象
    public void fun04() {
        //1.创建jdbcTemplate对象(需要传入连接池)
        JdbcTemplate jdbcTemplate = new JdbcTemplate(C3p0Utils.getDataSource());
        //2.执行queryForMap()的方法来查询
        String sql = "SELECT * FROM user WHERE id = ?";
        Map<String, Object> map = jdbcTemplate.queryForMap(sql, 1);
        System.out.println(map);
    }

3.2 查询一条记录封装成实体对象

  • 需求: 查询id为1的用户, 封装成user对象
    如果每个JavaBean都需要自己封装每个属性,那开发效率将大打折扣,所以Spring JDBC提供了这个接口的实现类BeanPropertyRowMapper,使用起来更加方便。只需要在构造方法中传入User.class类对象即可,它会自动封装所有同名的属性。使用BeanPropertyRowMapper实现类:
    在这里插入图片描述

  • 开发步骤

    创建JdbcTemplate对象,传入数据源

    编写查询的SQL语句

    使用JdbcTemplate对象的queryForObject方法,并传入需要返回的数据的类型

    返回是一个实体对象

    @Test
    // 查询id为1的用户, 封装成user对象
    public void fun05() {
        JdbcTemplate jdbcTemplate = new JdbcTemplate(C3p0Utils.getDataSource());
        String sql = "select * from user WHERE id = ?";
        User user = jdbcTemplate.queryForObject(sql, new BeanPropertyRowMapper<>(User.class), 1);
        System.out.println(user);
    }

3.3 查询多条记录封装成 List<Map<String,Object>>

  • 需求: 查询所有的用户, 封装成 List<Map<String,Object>> list
  • 开发步骤:
    创建JdbcTemplate对象,传入数据源
    编写SQL语句
    使用JdbcTemplate对象的==queryForList(String sql,Objec…params)==方法查询结果
    @Test
    // 查询所有的用户, 封装成 List<Map<String,Object>> list
    public void fun06() {
        JdbcTemplate jdbcTemplate = new JdbcTemplate(C3p0Utils.getDataSource());
        String sql = "SELECT * FROM user";
        List<Map<String, Object>> mapList = jdbcTemplate.queryForList(sql);
        System.out.println(mapList);
    }

3.4 查询多条记录封装成 List

  • 需求: 查询所有的用户, 封装成 List list
  • 开发步骤:
    创建JdbcTemplate对象,传入数据源
    编写SQL语句
    使用JdbcTemplate对象的==query(String sql,new BeanPropertyRowMapper<>,Object … params)==方法查询结果
    @Test
    //  查询所有的用户, 封装成 List<JavaBean> list
    public void fun07() {
        JdbcTemplate jdbcTemplate = new JdbcTemplate(C3p0Utils.getDataSource());
        String sql = "SELECT * FROM user";
        List<User> list = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(User.class));
        System.out.println(list);
    }

3.5 统计总记录数

  • 需求: 统计user的总记录数
  • 开发步骤:
    创建JdbcTemplate对象,传入数据源
    编写SQL语句
    使用JdbcTemplate对象的使用==queryForObject()==方法,指定参数为Integer.class或者Long.class
    @Test
    //统计user的总记录数
    public void fun08() {
        JdbcTemplate jdbcTemplate = new JdbcTemplate(C3p0Utils.getDataSource());
        String sql = "select  COUNT(*) from user ";
        
        Long count = jdbcTemplate.queryForObject(sql, Long.class);
        System.out.println(count);
        
        //int count2 = jdbcTemplate.queryForObject(sql, Integer.class);
        //System.out.println(count2);
    }

4.JDBCTemplate总结

  • 创建JDBCTemplate
JdbcTemplate jdbcTemplate = new JdbcTemplate(C3P0Utils.getDataSource());
  • 增删改
jdbcTemplate.update(String sql,Object... params);
  • 查询
  • 查询一条数据,封装成JavaBean对象
jdbcTemplate.queryForObject(String sql,BeanPropertyRowMapper bean,Object... params);
  • 查询一条数据,封装成Map对象
jdbcTemplate.queryForMap(String sql,Object... params);
  • 统计数量
jdbcTemplate.queryForObject(String sql,Long.class,Object... params);
  • 查询多条数据, 封装成List
jdbcTemplate.query(String sql,BeanPropertyRowMapper bean,Object... params);
  • 查询多条数据, 封装成List
jdbcTemplate.queryForList(String sql,Object... params);

四.元数据

1.概述

元数据(MetaData),即定义数据的数据。打个比方,就好像我们要想搜索一首歌(歌本身是数据),而我们可以通过歌名,作者,专辑等信息来搜索,那么这些歌名,作者,专辑等等就是这首歌的元数据。因此数据库的元数据就是一些注明数据库信息的数据。

简单来说: 数据库里面元数据就是数据库、表、列的定义信息。

元数据在建立框架和架构方面是特别重要的知识,我们可以使用数据库的元数据来创建自定义JDBC框架, 模仿jdbcTemplate.

  • 由PreparedStatement对象的getParameterMetaData ()方法获取的是ParameterMetaData对象。

  • 由ResultSet对象的getMetaData()方法获取的是ResultSetMetaData对象。

2. 通过JDBC获得元数据

2.1 ParameterMetaData

ParameterMetaData是由preparedStatement对象通过getParameterMetaData方法获取而来,ParameterMetaData可用于获取有关PreparedStatement对象和其预编译sql语句 中的一些信息. eg:参数个数,获取指定位置占位符的SQL类型在这里插入图片描述
获得ParameterMetaData:

ParameterMetaData parameterMetaData =  preparedStatement.getParameterMetaData ()

ParameterMetaData相关的API

  • int getParameterCount(); 获得参数个数
  • int getParameterType(int param) 获取指定参数的SQL类型。 (注:MySQL不支持获取参数类型)
    @Test
    //参数元数据
    public void fun01() throws Exception {
        //1.获得连接
        Connection connection = C3p0Utils.getConnection();
        //2.创建预编译的sql语句对象
        String sql = "SELECT * FROM user WHERE username = ? and password = ?";
        PreparedStatement preparedStatement = connection.prepareStatement(sql);

        //3.从preparedStatement中获得参数元数据对象
        ParameterMetaData parameterMetaData = preparedStatement.getParameterMetaData();

        //4.获得参数的个数
        System.out.println(parameterMetaData.getParameterCount());
//        System.out.println(parameterMetaData.getParameterType(1));//MySQL不支持获取参数类型
    }

2.2ResultSetMetaData

ResultSetMetaData是由ResultSet对象通过getMetaData方法获取而来,ResultSetMetaData可用于获取有关ResultSet对象中列的类型和属性的信息。在这里插入图片描述
获得ResultSetMetaData:

 	ResultSetMetaData resultSetMetaData =  resultSet.getMetaData()

resultSetMetaData 相关的API

  • getColumnCount(); 获取结果集中列项目的个数
  • getColumnName(int column); 获得数据指定列的列名
  • getColumnTypeName();获取指定列的SQL类型
  • getColumnClassName();获取指定列SQL类型对应于Java的类型
    @Test
    //结果元数据
    public void fun02() throws Exception {
        //1.获得连接
        Connection connection = C3p0Utils.getConnection();
        //2.创建预编译的sql语句对象
        String sql = "SELECT * FROM user ";
        PreparedStatement preparedStatement = connection.prepareStatement(sql);
        //3.执行sql语句,获得ResultSet
        ResultSet resultSet = preparedStatement.executeQuery();
        //4.创建结果的元数据对象
        ResultSetMetaData resultSetMetaData = resultSet.getMetaData();

        //获得结果集中列的数量
        int columnCount = resultSetMetaData.getColumnCount();
        System.out.println(columnCount);

        //获得数据指定列的列名
        String columnName = resultSetMetaData.getColumnName(2);
        System.out.println(columnName);

        //获得指定列的sql类型
        String columnTypeName = resultSetMetaData.getColumnTypeName(2);
        System.out.println(columnTypeName);

        //获得指定列sql类型的对应于java的类型
        String columnClassName = resultSetMetaData.getColumnClassName(3);
        System.out.println(columnClassName);

        //列在数据库中的类型(数值编号)
        int columnType = resultSetMetaData.getColumnType(1);
        System.out.println(columnType);

    }

3.自定义JDBC模版

package com.custom;

import com.utils.C3p0Utils;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.ParameterMetaData;
import java.sql.PreparedStatement;


public class MyJdbcTemplate {
    private DataSource dataSource;

    public MyJdbcTemplate(DataSource dataSource) {
        this.dataSource = dataSource;
    }

    /**
     * 增删改
     * 封装了JDBC操作数据库的步骤+元数据,释放资源(使用者不需要关注释放资源了)
     * @param sql
     * @param params
     * @return
     */
    public int update(String sql, Object... params) {
        Connection connection = null;
        PreparedStatement preparedStatement = null;
        try {
            //1.非空判断
            if (dataSource == null){
                throw new RuntimeException("dataSource must not be null...");
            }

            if (sql == null){
                throw new RuntimeException("sql must not be null...");
            }

            //2.获得连接
            connection = dataSource.getConnection();
            //3.创建预编译的sql语句对象
            preparedStatement = connection.prepareStatement(sql);
            //4.获得参数元数据对象
            ParameterMetaData parameterMetaData = preparedStatement.getParameterMetaData();
            //5.获得参数的个数(?的个数)
            int parameterCount = parameterMetaData.getParameterCount();
            //6.给每一个?赋值
            for (int i = 0; i < parameterCount; i++) {
                preparedStatement.setObject(i+1,params[i]);
            }

            //7.执行
            return preparedStatement.executeUpdate();
        } catch (Exception e) {
            e.printStackTrace();
            return -1;
        }finally {
            C3p0Utils.release(null,preparedStatement,connection);
        }
    }

}

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值