Spring-JdbcTemplate

  |   0 评论   |   0 浏览

JdbcTemplate

1.看一个实际需求

● 实际需求: 如果程序员就希望使用 spring 框架来做项目,spring 框架如何处理对数据库的 操作呢?

  1. 方案 1.自己开发 JdbcUtils 类
  2. 方案 2. 其实 spring 提供了一个操作数据库(表)功能强大的类 JdbcTemplate 。我们可以同 ioc 容器来配置一个 jdbcTemplate 对象,使用它来完成对数据库表的各种操作.

2.官方文档

JdbcTemplate APIs : /spring-framework-5.3.8/docs/javadoc-api/index.html

image-20220529154431223

3.JdbcTemplate-基本介绍

● 基本介绍

  1. 通过 Spring 可以配置数据源,从而完成对数据表的操作
  2. JdbcTemplate 是 Spring 提供的访问数据库的技术。可以将 JDBC 的常用操作封装为模板方 法。[JdbcTemplate 类图]

image-20220529160630386

4.JdbcTemplate 使用实例

1.需求说明

我们使用 spring 的方式来完成 JdbcTemplate 配置和使用

2.JdbcTemplate 使用

  1. 引入使用 JdbcTemplate 需要的 jar 包

image-20220529160735497

2.创建数据库 spring 和表 monster

-- 创建数据库
CREATE DATABASE spring;
USE spring;
-- 创建表 monster
CREATE TABLE monster ( id INT PRIMARY KEY, `name` VARCHAR ( 64 ) NOT NULL DEFAULT '', skill VARCHAR ( 64 ) NOT NULL DEFAULT '' ) CHARSET = utf8;

-- 插入数据
INSERT INTO monster
VALUES
	( 100, '青牛怪', '吐火' );
INSERT INTO monster
VALUES
	( 200, '黄袍怪', '吐烟' );
INSERT INTO monster
VALUES
	( 300, '蜘蛛怪', '吐丝' );

3.创建配置文件 src/jdbc.properties

jdbc.userName=root
jdbc.password=root
jdbc.driverClass=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3308/spring

4.创建配置文件 src/JdbcTemplate_ioc.xml

<?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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">

    <!--引入外部的jdbc.properties文件-->
    <context:property-placeholder location="classpath:jdbc.properties"/>
    <!--配置数据源对象-DataSource c3p0数据源
    com.mchange.v2.c3p0.ComboPooledDataSource
    -->
    <bean class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <!--给数据源对象配置属性值-->
        <property name="user" value="${jdbc.userName}"/>
        <property name="password" value="${jdbc.password}"/>
        <property name="driverClass" value="${jdbc.driverClass}"/>
        <property name="jdbcUrl" value="${jdbc.url}"/>
    </bean>

</beans>

5.创建测试,看能否得到数据源

public class JdbcTemplateTest {
    @Test
    public void testDataSourceByJdbcTemplate() throws SQLException {
        ApplicationContext ioc = new ClassPathXmlApplicationContext("JdbcTemplate_ioc.xml");
        DataSource dataSource = ioc.getBean(DataSource.class);
        Connection connection = dataSource.getConnection();
        System.out.println(connection);
    }
}

6.配置 JdbcTemplate_ioc.xml,将数据源分配给 JdbcTemplate bean

<bean class="org.springframework.jdbc.core.JdbcTemplate" id="jdbcTemplate">
    <!--给jdbcTemplate注入dataSource属性依赖-->
    <property name="dataSource" ref="dataSource"/>
</bean>

7.修改 JdbcTemplateTest.java,添加一个新的 monster

@Test public void addDataByJdbcTemplate() {
        ApplicationContext ioc = new ClassPathXmlApplicationContext("JdbcTemplate_ioc.xml");
        JdbcTemplate jdbcTemplate = ioc.getBean(JdbcTemplate.class);
        //1. 添加方式1
//        String sql = "INSERT INTO monster VALUES(400, '红孩儿', '枪法')";
//        jdbcTemplate.update(sql);
//        jdbcTemplate.execute(sql);

        //2.添加方式2
        String sql = "INSERT INTO monster VALUES(?,?,?)";
        int update = jdbcTemplate.update(sql, 500, "白骨精", "吸血");
        System.out.println(update);
    }

8.修改 JdbcTemplateTest.java,更新一个 monster 的 skill

@Test
public void updateDataByJdbcTemplate() {
    ApplicationContext ioc = new ClassPathXmlApplicationContext("JdbcTemplate_ioc.xml");
    //得到 JdbcTemplate bean
    JdbcTemplate jdbcTemplate = ioc.getBean(JdbcTemplate.class);
    String sql = "update monster set skill=? where id = ?";
    int affected = jdbcTemplate.update(sql, "美人计", 500);
    System.out.println(affected);
}

9.修改 JdbcTemplateTest.java,批量添加二个 monster 白蛇精和青蛇精

@Test
public void addBatchDataByJdbcTemplate() {
    ApplicationContext ioc = new ClassPathXmlApplicationContext("JdbcTemplate_ioc.xml");
    //得到JdbcTemplate bean
    JdbcTemplate jdbcTemplate = ioc.getBean(JdbcTemplate.class);//添加..

    //1. 先确定,猜测API名称 batchUpdate[如果出现问题,才重新玩]
    //public int[] batchUpdate(String sql, List<Object[]> batchArgs){}
    //2. 准备参数
    String sql = "INSERT INTO monster VALUES(?, ?, ?)";
    List<Object[]> batchArgs = new ArrayList<>();
    batchArgs.add(new Object[]{600, "老鼠精", "偷吃粮食"});
    batchArgs.add(new Object[]{700, "老猫精", "抓老鼠"});
    //3. 调用
    //说明:返回结果是一个数组,每个元素对应上面的sql语句对表的影响记录数
    int[] ints = jdbcTemplate.batchUpdate(sql, batchArgs);
    //输出
    for (int anInt : ints) {
        System.out.println("anInt=" + anInt);
    }
    System.out.println("batch add ok..");
}

10.查询 id=100 的 monster 并封装到 Monster 实体对象

@Test
public void selectDataByJdbcTemplate() {
    ApplicationContext ioc = new ClassPathXmlApplicationContext("JdbcTemplate_ioc.xml");
    //得到JdbcTemplate bean
    JdbcTemplate jdbcTemplate = ioc.getBean(JdbcTemplate.class);
    //组织SQL
    //通过BeanPropertyRowMapper获取rowmapper 是一个接口,可以将查询的结果,封装到你指定的Monster对象中.

    //1. 确定API : queryForObject()
    //public <T> T queryForObject(String sql, RowMapper<T> rowMapper, @Nullable Object... args)
    //2.准备参数
    String sql = "SELECT id AS monsterId, NAME, skill FROM monster WHERE id = 100";
    //使用RowMapper 接口来对返回的数据,进行一个封装-》底层使用的反射->setter
    //这里有一个细节: 你查询的记录的表的字段需要和 Monster的对象字段名保持一致
    RowMapper<Monster> rowMapper = new BeanPropertyRowMapper<>(Monster.class);
    //jdbcTemplate
    Monster monster = jdbcTemplate.queryForObject(sql, rowMapper);
    System.out.println("monster= " + monster);
    System.out.println("查询ok");
}

11.查询 id>=200 的 monster 并封装到 Monster 实体对象

@Test
public void selectMulDataByJdbcTemplate() {
    ApplicationContext ioc =
            new ClassPathXmlApplicationContext("JdbcTemplate_ioc.xml");
    //得到JdbcTemplate bean
    JdbcTemplate jdbcTemplate = ioc.getBean(JdbcTemplate.class);
    //组织SQL
    //通过BeanPropertyRowMapper获取rowmapper 是一个接口,可以将查询的结果,封装到你指定的Monster对象中.

    //1.    确定API
    //public <T> T query(String sql, RowMapper<T> rowMapper, Object... args){}
    //2. 组织参数
    String sql = "SELECT id AS monsterId, NAME, skill FROM monster WHERE id >= ?";
    RowMapper<Monster> rowMapper = new BeanPropertyRowMapper<>(Monster.class);
    //3. 调用
    List<Monster> monsterList = jdbcTemplate.query(sql, rowMapper, 200);
    for (Monster monster : monsterList) {
        System.out.println("monster= " + monster);
    }
}

12.查询返回结果只有一行一列的值,比如查询 id=100 的怪物名

@Test
public void selectScalarByJdbcTemplate() {
    ApplicationContext ioc =
            new ClassPathXmlApplicationContext("JdbcTemplate_ioc.xml");
    //得到JdbcTemplate bean
    JdbcTemplate jdbcTemplate = ioc.getBean(JdbcTemplate.class);

    //1. 确定API
    //public <T> T queryForObject(String sql, Class<T> requiredType)
    //2. 提供参数
    String sql = "SELECT NAME FROM monster WHERE id = 100";
    //Class<T> requiredType 表示你返回的单行单列的数据类型

    String name =
            jdbcTemplate.queryForObject(sql, String.class);
    System.out.println("返回name= " + name);

}

13.使用 Map 传入具名参数完成操作,比如添加 螃蟹精.:name 就是具名参数形式需要使 用 NamedParameterJdbcTemplate 类

修改配置文件

<?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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">

    <!--配置要扫描包-->
    <context:component-scan
            base-package="com.llp.spring.jdbctemplate.dao"/>

    <!--引入外部的jdbc.properties文件-->
    <context:property-placeholder location="classpath:jdbc.properties"/>
    <!--配置数据源对象-DataSoruce-->
    <bean class="com.mchange.v2.c3p0.ComboPooledDataSource" id="dataSource">
        <!--给数据源对象配置属性值-->
        <property name="user" value="${jdbc.user}"/>
        <property name="password" value="${jdbc.pwd}"/>
        <property name="driverClass" value="${jdbc.driver}"/>
        <property name="jdbcUrl" value="${jdbc.url}"/>
    </bean>

    <!--配置JdbcTemplate对象-->
    <bean class="org.springframework.jdbc.core.JdbcTemplate" id="jdbcTemplate">
        <!--给JdbcTemplate对象配置dataSource-->
        <property name="dataSource" ref="dataSource"/>
    </bean>

    <!--配置NamedParameterJdbcTemplate对象-->
    <bean class="org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate"
          id="namedParameterJdbcTemplate">
        <!--通过构造器,设置数据源-->
        <constructor-arg name="dataSource" ref="dataSource"/>
    </bean>
</beans>
@Test
public void testDataByNamedParameterJdbcTemplate() {
    ApplicationContext ioc =
            new ClassPathXmlApplicationContext("JdbcTemplate_ioc.xml");
    //得到NamedParameterJdbcTemplate bean
    NamedParameterJdbcTemplate namedParameterJdbcTemplate =
            ioc.getBean(NamedParameterJdbcTemplate.class);

    //1. 确定使用API
    //public int update(String sql, Map<String, ?> paramMap)
    //2. 准备参数 [:my_id, :name, :skill] 要求按照规定的名字来设置参数
    String sql = "INSERT INTO monster VALUES(:id, :name, :skill)";
    Map<String, Object> paramMap = new HashMap<>();
    //给paramMap填写数据
    paramMap.put("id", 800);
    paramMap.put("name", "蚂蚁精");
    paramMap.put("skill", "喜欢打洞");
    //3. 调用
    int affected = namedParameterJdbcTemplate.update(sql, paramMap);
    System.out.println("add ok affected=" + affected);


}

14.使用 sqlparametersoruce 来封装具名参数,还是添加一个 Monster 狐狸精

@Test
public void operDataBySqlparametersoruce() {
    ApplicationContext ioc =
            new ClassPathXmlApplicationContext("JdbcTemplate_ioc.xml");
    //得到NamedParameterJdbcTemplate bean
    NamedParameterJdbcTemplate namedParameterJdbcTemplate =
            ioc.getBean(NamedParameterJdbcTemplate.class);

    //确定API
    //public int update(String sql, SqlParameterSource paramSource)
    //public BeanPropertySqlParameterSource(Object object)
    //准备参数
    String sql = "INSERT INTO monster VALUES(:monsterId, :name, :skill)";
    Monster monster = new Monster(900, "大象精", "搬运木头");
    SqlParameterSource sqlParameterSource =
            new BeanPropertySqlParameterSource(monster);
    //调用
    int affected =
            namedParameterJdbcTemplate.update(sql, sqlParameterSource);

    System.out.println("add ok affected= " + affected);
}

15.Dao 对象中使用 JdbcTemplate 完成对数据的操作

@Repository //将MonsterDao 注入到spring容器
public class MonsterDao {
    //注入一个属性
    @Resource
    private JdbcTemplate jdbcTemplate;

    //完成保存任务
    public void save(Monster monster) {
        //组织sql
        String sql = "INSERT INTO monster VALUES(?,?,?)";
        int affected = jdbcTemplate.update
                (sql, monster.getMonsterId(), monster.getName(), monster.getSkill());
        System.out.println("affected= " + affected);
    }
}
@Test
public void monsterDaoSave() {
    ApplicationContext ioc =
            new ClassPathXmlApplicationContext("JdbcTemplate_ioc.xml");

    MonsterDao monsterDao = ioc.getBean(MonsterDao.class);
    Monster monster = new Monster(1000, "小鸭精", "吃鱼");
    monsterDao.save(monster);
    System.out.println("MonsterDAO保存 ok ..");
}

标题:Spring-JdbcTemplate
作者:llp
地址:https://llinp.cn/articles/2022/05/29/1653836441234.html