MySQL学习笔记(8) -- JDBCTemplate 模板

大部分情况下JDBC已经能够满足大部分用户的需求,但是再使用JDBC时,必须自己来管理数据库资源:例如获取PreparedStatement,设置SQL语句,关闭连接等步骤。jdbcTemplate就是Spring对JDBC的封装,目的是使JDBC更加容易使用。jdbcTemplate时Spring的一部分。

jdbcTemplate处理了资源的简历和释放。它帮助我们便面一些常见的错误,比如忘记关闭连接。运行核心的JDBC工作流,如Statement的建立和执行,而我们只需要提供SQL语句和提取结果。

在jdbcTemplate中执行SQL语句的方法大致分为3类:

1.excute:可以执行所有的SQL语句,一般用于执行DDL语句。

2.update:用于执行insertupdatedelete等DML语句。

3.QueryXxx:用于DQL数据查询语句。

准备数据:
假设在mydb数据库中创建一张emp表,用它记录员工的基本信息:

员工编号(idint(11),主键,自增长)
员工姓名(name carchar(20),非空)
员工工资(salary double default 5000

现在需要插入一些员工的信息

id name salary
1 花花 5000
2 美丽 6000
3 jack 7000
4 翠花 8000

案例代码:

1.准备c3p0-config.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<c3p0-config>
    <!-- 默认配置,c3p0框架默认加载这段默认配置 -->
    <default-config>
        <!-- 配置JDBC 四个基本属性 -->
        <property name="driverClass">com.mysql.cj.jdbc.Driver</property>
        <property name="jdbcUrl">jdbc:mysql://localhost:3306/mydb?serverTimezone=UTC&amp;characterEncoding=utf-8</property>
        <property name="user">root</property>
        <property name="password">123</property>
    </default-config>
</c3p0-config>

2.准备JDBCUtils工具类

public class JDBCUtils {

    private static final ComboPooledDataSource dataSource = new ComboPooledDataSource();

    public static ComboPooledDataSource getDataSource() {
        return dataSource;
    }

    //获取连接
    public static Connection getConnection() throws SQLException {
        return dataSource.getConnection();
    }

    public static void release(Connection conn, Statement stmt, ResultSet rs) {

        if (rs != null) {
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
            rs = null; //clear to let GC do its work
        }
        release(conn, stmt);
    }

    public static void release(Connection conn, Statement stmt) {

        if (stmt != null) {
            try {
                stmt.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
            stmt = null; //clear to let GC do its work
        }

        if (conn != null) {
            try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
            conn = null; //clear to let GC do its work
        }
    }
}


实现需求

一 、void execute(sql)

此方法可以执行所有的sql语句,方法执行后没有返回值。一般用于执行DDL语句

1.创建表格:

@Test
    public void test1(){

        //创建核心类对象
        JdbcTemplate jdbcTemplate = new JdbcTemplate(JDBCUtils.getDataSource());

        //创建emp表
        String sql = "create table emp(" +
                "id int primary key auto_increment," +
                "name varchar(20) not null," +
                "salary double default 5000" +
                ");";
        jdbcTemplate.execute(sql);

    }

这里写图片描述

2.删除表格

String sql2 = "drop table emp2;";
jdbcTemplate.execute(sql2);

3.修改表表格

alter table emp change id pid int not null auto_increment; 

这里写图片描述


二 、int updte(sql,Object … args)

此方法一般用来对数据库数据进行增、删、改操作,返回int类型结果,代表的是影响记录数。常用于执行DML语句。

1.增

@Test
    public void test2(){

        //创建核心类
        JdbcTemplate jdbcTemplate = new JdbcTemplate(JDBCUtils.getDataSource());

        //插入数据
        String sql = "insert into emp values(?,?,?)";
        int count = jdbcTemplate.update(sql, null, "花花", 5000);
        count +=jdbcTemplate.update(sql, null, "美丽", 6000);
        count +=jdbcTemplate.update(sql, null, "jack", 7000);
        count +=jdbcTemplate.update(sql, null, "翠花", 8000);
        count +=jdbcTemplate.update(sql, null, "如花", 88888);
        System.out.println("count = " + count);
    }

这里写图片描述

2.删

@Test
    public void test3(){

        //1.创建核心类
        JdbcTemplate jdbcTemplate = new JdbcTemplate(JDBCUtils.getDataSource());

        //2.删除数据
        String sql = "delete from emp where name = '如花'";
        int count = jdbcTemplate.update(sql);
        System.out.println("count = " + count);

    }

这里写图片描述

3.改

    @Test
    public void test4(){
        //创建核心类
        JdbcTemplate jdbcTemplate = new JdbcTemplate(JDBCUtils.getDataSource());

        //2.修改数据
        String sql = "update emp set salary = 88888 where pid = ?";
        int count = jdbcTemplate.update(sql, 4);
        System.out.println("count = " + count);
    }

这里写图片描述


三 、 queryForXxx(sql,Object … args)

方法名 作用 返回值类型 备注
queryForObject() 单行单列查询 Object
queryForMap() 单行多列 Map
queryForList() 多行单列 List List存放多个Map,map中存在一个键值对
queryForList() 多行多列 LIst List存放多个Map
query() 将查询数据包装成对象返回结果 List 将数据库的每一行当作一个对象,需要创建实体类来保存数据,实体类属性就是数据表的列名

1. queryForObject – 查询单行单列数据

public <T> T queryForObject(String sql, Class<T> requiredType, @Nullable Object... args)

方法的参数说明:
1:必须要有一条sql执行语句;
2:必须要指定方法的返回值类型
3:省略参数根据实际情况选择

方法的返回值说明:
返回值类型跟随参数列表中参数2指定的类型

实现代码:

@Test
    public void test5(){

        //创建核心类对象
        JdbcTemplate jdbcTemplate = new JdbcTemplate(JDBCUtils.getDataSource());

        //查找单个数据:
        //pid=1的员工名字
        String sql = "select name from emp where pid = 1";
        String name = jdbcTemplate.queryForObject(sql, String.class);//省略参数
        System.out.println("name = "+ name);

        //名字为翠花的员工编号
        String sql2 = "select pid from emp where name = ?";
        int pid = jdbcTemplate.queryForObject(sql2, int.class,"翠花");//不省略参数
        System.out.println("pid = " + pid);
    }

这里写图片描述

2. queryForMap – 查询单行多列数据

public Map<String, Object> queryForMap(String sql, @Nullable Object... args)

方法的参数说明:
1:必须要有一条sql执行语句;
2:省略参数根据实际需要选择

方法的返回值说明:
方法返回一个Map映射集,其中key对应数据表的列名,value对应数据表的值。

代码实现:

@Test
    public void test6(){

        //创建核心类对象
        JdbcTemplate jdbcTemplate = new JdbcTemplate(JDBCUtils.getDataSource());

        //查找单行多个数据
        String sql = "select * from emp where name = ?";
        Map<String, Object> map = jdbcTemplate.queryForMap(sql, "翠花");
        System.out.println("map = " + map);
    }

这里写图片描述

3. queryForList – 查询多行单列、多行多列数据

public List<Map<String, Object>> queryForList(String sql, @Nullable Object... args)

方法的参数说明:
1:必须要有一条sql执行语句;
2:省略参数根据实际情况选择

方法的返回值说明:
方法返回值类型是List类型,里面保存的是map映射表,引射表中的key对应数据表的列名,value对应值;当查询多行单列的时候,list集合中可以存在多个map,但是map中只存在一个键值对数据;查询多行多列的时候,list集合中存放多个map,map中的键值对数量和列数量一致。

多行单列代码实现:

    @Test
    public void test7(){

        //创建核心类对象
        JdbcTemplate jdbcTemplate = new JdbcTemplate(JDBCUtils.getDataSource());

        //查找多行单列数据
        String sql = "select name from emp where salary >= 7000";
        List<Map<String, Object>> list = jdbcTemplate.queryForList(sql);

        //遍历集合
        for(Map<String, Object> map:list){
            System.out.println(map);
        }
    }

这里写图片描述

多行多列代码实现:

@Test
    public void test8(){

        //创建核心类对象
        JdbcTemplate jdbcTemplate = new JdbcTemplate(JDBCUtils.getDataSource());

        //查找多行多列数据
        String sql = "select * from emp where salary >= ? and pid >2";
        List<Map<String, Object>> list = jdbcTemplate.queryForList(sql, 7000);

        //遍历集合
        for(Map<String, Object> map:list){
            System.out.println(map);
        }
    }

这里写图片描述


四 、query使用RowMapper做映射返回对象

通过上面的代码,我们发现:queryForList方法其实就是返回每一行中的某些列或者全部列的值,如果我们把每一行都当成一个对象,那么列的值就是对象的属性了。我们就可以通过查询对象来查找我们需要的数据了。

public <T> List<T> query(String sql, RowMapper<T> rowMapper, @Nullable Object... args) 

方法的参数说明:
1:必须要有一条sql执行语句;
2:RowMapper 接口的实现类对象
在匿名内部类中将结果集中的一行记录转成一个Product对象
3:省略参数根据实际情况选择

方法返回值说明:
返回的是List集合,里面存储的是实体类对象。

定义实体类:

public class Employee {
    private int pid;
    private String name;
    private double salsry;

    @Override
    public String toString() {
        return "Employee{" +
                "pid=" + pid +
                ", name='" + name + '\'' +
                ", salsry=" + salsry +
                '}';
    }

    public Employee(int pid, String name, double salsry) {
        this.pid = pid;
        this.name = name;
        this.salsry = salsry;
    }

    public Employee() {
    }

    public int getPid() {
        return pid;
    }

    public void setPid(int pid) {
        this.pid = pid;
    }

    public String getName() {
        return name;
    }

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

    public double getSalsry() {
        return salsry;
    }

    public void setSalsry(double salsry) {
        this.salsry = salsry;
    }
}

实例代码:

@Test
    public void test9(){

        //创建核心类对象
        JdbcTemplate jdbcTemplate = new JdbcTemplate(JDBCUtils.getDataSource());

        //查找多行多列数据
        String sql = "select * from emp ";
        List<Employee> list = jdbcTemplate.query(sql, new RowMapper<Employee>() {
            @Override
            public Employee mapRow(ResultSet rs, int i) throws SQLException {

                //从结果集中取出数据
                int pid = rs.getInt("pid");
                String name = rs.getString("name");
                double salary = rs.getDouble("salary");
                //包装成对象并返回
                return new Employee(pid,name,salary);
            }
        });

        //遍历集合
        for(Employee employee:list){
            System.out.println(employee);
        }
    }

这里写图片描述

五 、query使用BeanPropertyRowMapper做映射返回对象

Sping 中提供了一个便利的RowMapper实现—–BeanPropertyRowMapper,通过这个类我们可以更加方便的将数据库的数据包装成对象:

代码实现:

@Test
    public void test10(){

        //创建核心类对象
        JdbcTemplate jdbcTemplate = new JdbcTemplate(JDBCUtils.getDataSource());

        //查找多行多列数据
        String sql = "select * from emp ";
        List<Employee> list = jdbcTemplate.query(sql,new BeanPropertyRowMapper(Employee.class));

        //遍历集合
        for(Employee employee:list){
            System.out.println(employee);
        }
    }

这里写图片描述

猜你喜欢

转载自blog.csdn.net/zyrdfly/article/details/82710328