Spring

【Spring】10 - Spring 中的 JDBCTempl

2020-10-25  本文已影响0人  itlu

1. JdbcTemplate 概述

  1. 它是spring 框架中提供的一个对象,是对原始 Jdbc API 对象的简单封装。 spring框架为我们提供了很多的操作模板类。

  2. 操作关系型数据的:JdbcTemplate HibernateTemplate

  3. 操作 nosql 数据库的:RedisTemplate

  4. 操作消息队列的:JmsTemplate

2. SpringJDBCTemplate 的使用

2.1 创建一个项目

  1. 创建一个 不使用骨架的 Maven 项目。

2.2 导入相关依赖

    <packaging>jar</packaging>

    <dependencies>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.0.5.RELEASE</version>
        </dependency>

        <!-- mysql驱动 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.6</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.springframework/spring-tx -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-tx</artifactId>
            <version>5.0.2.RELEASE</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>5.0.2.RELEASE</version>
        </dependency>


    </dependencies>

2.3 创建需要使用的数据表

create table account(
    id int primary key auto_increment,
    name varchar(40),
    money float
)character set utf8 collate utf8_general_ci;

insert into account(name,money) values('aaa',1000);
insert into account(name,money) values('bbb',1000);
insert into account(name,money) values('ccc',1000);

2.4 创建数据库对应的实体类并实现 Serializable 接口

public class Account implements Serializable {

    private Integer id;

    private String name;

    private Float money;
    
    // 省略 setter 和 getter 方法  toString 方法 
}

2.5 编写代码进行测试

  1. 注意sql 语句的编写 :
public class SpringJdbcTemplateClient {

    public static void main(String[] args) {

        // org.springframework.jdbc.datasource.DriverManagerDataSource
        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setDriverClassName("com.mysql.jdbc.Driver");
        dataSource.setUrl("jdbc:mysql://localhost:3306/spring");
        dataSource.setUsername("root");
        dataSource.setPassword("root");
        //可以通过 JdbcTemplate 对象的set方法为其设置数据源 也可以直接通过构造方法的方式进行设置数据源
        JdbcTemplate jt = new JdbcTemplate(dataSource);
        jt.execute("insert into account (name,money) values ('ddd',123)");
    }
}

3. 为 demo 配置 IOC 容器

3.1 编写 bean.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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="datasource"/>
    </bean>

    <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/spring"/>
        <property name="username" value="root"/>
        <property name="password" value="root"/>
    </bean>
</beans>

3.2 编写代码进行测试

  1. 下面的测试代码是针对的 Spring IOC 的方式:
public class SpringJdbcTemplateClientByIOC {

    public static void main(String[] args) {
        // "insert into account (name,money) values ('ddd',123)"
        String sql = "insert into account (name,money) values ('fff',456)";
        // 1. 获取IOC容器
        ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
        // 2. 获取对象
        JdbcTemplate jt = ac.getBean("jdbcTemplate", JdbcTemplate.class);
        // 3. 执行sql语句
        jt.execute(sql);
    }
}

4. JDBCTemplateCRUD 操作

  1. 进行 CRUD 测试代码中的所有基础代码 :
public class SpringJdbcTemplateClientMethodsByIOC {

public static void main(String[] args) {
     // 1. 获取IOC容器
     ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
     // 2. 获取对象
     JdbcTemplate jt = ac.getBean("jdbcTemplate", JdbcTemplate.class);
     // 3. 执行sql语句
  }
}

4.1 保存 update

  1. 执行保存操作的代码 :
    jt.update("insert into account (name,money) values (?,?)", "fff",456.0f);

4.2 更新 update

  1. 执行更新操作的代码:
     jt.update("update account set money = ? where id = ?", 500.0f , 3);

4.3 删除 delete

  1. 执行删除的代码:
    jt.update("delete from account where id = ?", 5);

4.4 查询所有

  1. 使用自定义实现类的方式实现查询 ;
  public class SpringJdbcTemplateClientMethodsByIOC {

    public static void main(String[] args) {
        String selectAllSql = "select * from account where money > ?";
        // 1. 获取IOC容器
        ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
        // 2. 获取对象
        JdbcTemplate jt = ac.getBean("jdbcTemplate", JdbcTemplate.class);
        // 3. 执行sql语句
        // 使用自定义实现类的方式实现 查询所有
        List<Account> accounts = jt.query(selectAllSql, new AccountRowMapper(), 500.0f);
        // 使用Spring 内置实现类的方式实现
        for (Account account : accounts) {
            System.out.println(account);
        }
    }
}

/**
 * 实现 jt查询方法中的 rowMapper 接口实现查询方法
 */
class AccountRowMapper implements RowMapper {

    public Object mapRow(ResultSet resultSet, int i) throws SQLException {
        Account account = new Account();
        account.setId(resultSet.getInt("id"));
        account.setName(resultSet.getString("name"));
        account.setMoney(resultSet.getFloat("money"));
        return account;
    }
}
  1. 使用内置的实现类的方式
public class SpringJdbcTemplateClientMethodsByIOC {

    public static void main(String[] args) {
        String selectAllSql = "select * from account where money > ?";
        // 1. 获取IOC容器
        ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
        // 2. 获取对象
        JdbcTemplate jt = ac.getBean("jdbcTemplate", JdbcTemplate.class);
        // 3. 执行sql语句
        // 使用Spring 内置实现类的方式实现
        List<Account> accounts = jt.query(selectAllSql, new BeanPropertyRowMapper<Account>(Account.class), 500.0f);
        for (Account account : accounts) {
            System.out.println(account);
        }
    }
}

4.5 查询一个

    // 查询一个
        List<Account> accounts = jt.query("select * from account where id = ?", new BeanPropertyRowMapper<Account>(Account.class), 1);
        System.out.println(accounts.get(0));

4.6 查询返回一行一列 (使用聚合函数,但是不加 group by

        // 查询一行或一列
        Integer count = jt.queryForObject("select count(*) from account", Integer.class);
        System.out.println("数据表中所有数据 : " + count);

5. JDBCTemplateDao 中使用

  1. 编写Account持久层接口 AccountDao :
public interface AccountDao {

    /**
     * 根据id查询账户信息
     * @param id
     * @return
     */
   Account findById(Integer id);

    /**
     * 根据name查询账户信息
     * @param name
     * @return
     */
    Account findByName(String name);

    /**
     * 更新账户信息
     * @param account
     */
    void update(Account account);
}
  1. 编写持久层实现类 : AccountDaoImpl
    public class AccountDaoImpl implements AccountDao {

    private JdbcTemplate jt;

    /**
     * 使用setter方法注入 JdbcTemplate 对象
     *
     * @param jt
     */
    public void setJt(JdbcTemplate jt) {
        this.jt = jt;
    }

    public Account findById(Integer id) {
        List<Account> accounts = jt.query("select * from account where id = ?", new BeanPropertyRowMapper<Account>(Account.class), id);
        return accounts.isEmpty() ? null : accounts.get(0);
    }

    public Account findByName(String name) {
        List<Account> accounts = jt.query("select * from account where name = ?", new BeanPropertyRowMapper<Account>(Account.class), name);
        if (accounts.isEmpty()) {
            return null;
        }
        if (accounts.size() > 1) {
            throw new RuntimeException("结果集不唯一。");
        }
        return accounts.get(0);
    }

    public void update(Account account) {
        jt.update("update account set money = ? where id = ? ", account.getMoney(), account.getId());
    }
}
  1. 修改 bean.xml配置 添加如下代码:
    <bean id="accountDao" class="com.lyp.dao.impl.AccountDaoImpl">
        <property name="jt" ref="jdbcTemplate"/>
    </bean>

5.1 以上代码中存在的问题

  1. 如果按照上面代码的写法,使用 xml配置的方式进行配置,有很多的 Dao时将会出现很多重复的setter方式注入的代码。

5.2 优化

  1. 编写一个 JdbcTemplateSupport类 ,将dao中重复的代码抽取到其中,作为父类。dao作为子类对其进行继承。
public class JdbcTemplateSupport {

    private JdbcTemplate jt;

    /**
     * 使用setter方法注入 JdbcTemplate 对象
     *
     * @param jt
     */
    public void setJt(JdbcTemplate jt) {
        this.jt = jt;
    }

    JdbcTemplate getJt() {
        return jt;
    }

    public void setDataSource(DataSource dataSource) {
        createJdbcTemplate(dataSource);
    }

    private void createJdbcTemplate(DataSource dataSource) {
        if (jt == null) {
            jt = new JdbcTemplate(dataSource);
        }
    }
}
继承JdbcTemplateSupport
  1. 修改 bean.xml文件配置
修改bean.xml中的配置
  1. 但是以上方式的抽取适用于使用 xml 方式进行配置。而不适用于注解的配置方式。

  2. 其实Spring 也内置了 JdbcDaoSupport类,只需要使用dao实现类对其进行继承即可;

继承自Spring内置的 JdbcDaoSupport 类

6. demo地址

  1. demo 地址 : Spring 中的 JdbcTemplate
上一篇下一篇

猜你喜欢

热点阅读