spring 对JDBC的支持 (8)

一、jdbc的简介

  • 为了使 JDBC 更加易于使用, Spring 在 JDBC API 上定义了一个抽象层, 以此建立一个 JDBC 存取框架.

  • 作为 Spring JDBC 框架的核心, JDBC 模板的设计目的是为不同类型的 JDBC 操作提供模板方法. 每个模板方法都能控制整个过程, 并允许覆盖过程中的特定任- 务. 通过这种方式, 可以在尽可能保留灵活性的情况下, 将数据库存取的工作量降到最低.

二、jdbcTemplate 的使用

2.1 maven 引入spring - jdbc ,c3p0 ,数据库mysql驱动

    <!-- c3p0 -->
    <dependency>
        <groupId>c3p0</groupId>
        <artifactId>c3p0</artifactId>
        <version>0.9.1.2</version>
    </dependency>
    
    <!-- mysql -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.24</version>
    </dependency>  
 
    <!-- jdbc -->
    <dependency>
        <groupId>org.springframework</groupId>  
        <artifactId>spring-jdbc</artifactId>  
        <version>4.1.9.RELEASE</version>  
    </dependency>

2.2 配置 数据源以及jdbcTemplate

  <!-- 导入资源文?件 -->
  <context:property-placeholder location="classpath:db.properties"/>
  
  <!-- 配置 C3P0 数据源 -->
  <bean id="dataSource"
    class="com.mchange.v2.c3p0.ComboPooledDataSource">
    <property name="user" value="${jdbc.user}"></property>
    <property name="password" value="${jdbc.password}"></property>
    <property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property>
    <property name="driverClass" value="${jdbc.driverClass}"></property>
 
    <property name="initialPoolSize" value="${jdbc.initPoolSize}"></property>
    <property name="maxPoolSize" value="${jdbc.maxPoolSize}"></property>
  </bean>
  <!-- 配置 Spirng 的? JdbcTemplate -->
  <bean id="jdbcTemplate" 
    class="org.springframework.jdbc.core.JdbcTemplate">
    <property name="dataSource" ref="dataSource"></property>
  </bean>  

db.properties

jdbc.user=root
jdbc.password=root
jdbc.driverClass=com.mysql.jdbc.Driver
jdbc.jdbcUrl=jdbc:mysql:///spring
 
jdbc.initPoolSize=5
jdbc.maxPoolSize=10  

2.3 数据库表结构

 
drop database if exists spring;
create database spring;
use spring;
 
drop table if exists employees;
drop table if exists departments;
 
create table departments(
  id int(11) primary key auto_increment, 
  dept_name varchar(20)
);
 
create table employees(
  id int(11) primary key auto_increment, 
  last_name varchar(20),
  email varchar(20),
  dept_id int(11),
  constraint `FK_employees_dept_id` foreign key (dept_id) references departments (id) 
);
 
 

2.4 测试使用

public class JDBCTest {
  
  private ApplicationContext ctx = null;
  private JdbcTemplate jdbcTemplate;
  
  {
    ctx = new ClassPathXmlApplicationContext("beans-jdbc.xml");
    jdbcTemplate = (JdbcTemplate) ctx.getBean("jdbcTemplate");
  }
 
  /**
   * 执行批量更新: 批?量的 INSERT, UPDATE, DELETE
   * 最后一个参数是 Object[] 的 List 类型: 因为修?改一条记录需要一?个 Object 的数组, 那么多?条不就需要多个 Object 的数组吗
   */
  @Test
  public void testBatchUpdate(){
    String sql = "INSERT INTO employees(last_name, email, dept_id) VALUES(?,?,?)";
    
    List<Object[]> batchArgs = new ArrayList<>();
    
    batchArgs.add(new Object[]{"AA", "员工?1", 1});
    batchArgs.add(new Object[]{"BB", "员工?2", 2});
    batchArgs.add(new Object[]{"CC", "员工?3", 3});
    batchArgs.add(new Object[]{"DD", "员工?4", 3});
    batchArgs.add(new Object[]{"EE", "员工?5", 2});
    
    jdbcTemplate.batchUpdate(sql, batchArgs);
  }
  
  /**
   * 执行 INSERT, UPDATE, DELETE
   */
  @Test
  public void testUpdate(){
    String sql = "UPDATE employees SET last_name = ? WHERE id = ?";
    jdbcTemplate.update(sql, "Jack", 15);
  }
  
  @Test
  public void testDataSource() throws SQLException {
    DataSource dataSource = ctx.getBean(DataSource.class);
    System.out.println(dataSource.getConnection());
  }
}

三、jdbc使用具名参数

具名参数是什么:
举个例子:
select * from employees where id = :id
这个 :id 就是一个具名参数

1 配置具名参数?的模板 
<!-- 配置 NamedParameterJdbcTemplate, 该对象可?以使用具名参数, 其没有无参数的构?造器, 所以必须为?其构造器指定参数? -->
  <bean id="namedParameterJdbcTemplate"    class="org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate">
    <constructor-arg ref="dataSource"></constructor-arg>  
  </bean>
 
2 将jdbcTemplate改成 namedParameterJdbcTemplate
 
public class JDBCTest {
  
  private ApplicationContext ctx = null;
  private JdbcTemplate jdbcTemplate;
  private NamedParameterJdbcTemplate namedParameterJdbcTemplate;
  
  {
    ctx = new ClassPathXmlApplicationContext("beans-jdbc.xml");
    jdbcTemplate = (JdbcTemplate) ctx.getBean("jdbcTemplate");
    namedParameterJdbcTemplate = ctx.getBean(NamedParameterJdbcTemplate.class);
  }
  
  /**
   * 使用具名参数时?, 可以使用 update(String sql, SqlParameterSource paramSource) 方?法进行更新操作
   * 1. SQL 语句中的参数名?和类的属性一致!
   * 2. 使用 SqlParameterSource 的 BeanPropertySqlParameterSource 实现?类作为参数. 
   */
  @Test
  public void testNamedParameterJdbcTemplate2(){
    String sql = "INSERT INTO employees(last_name, email, dept_id) "
         + "VALUES(:lastName,:email,:dpetId)";
    
    Employee employee = new Employee();
    employee.setLastName("XYZ");
    employee.setEmail("xyz@sina.com");
    employee.setDpetId(3);
    
    SqlParameterSource paramSource = new BeanPropertySqlParameterSource(employee);
    namedParameterJdbcTemplate.update(sql, paramSource);
  }
  
  /**
   * 可以为参数起名?字. 
   * 1. 好处: 若有多个参?数, 则不用再去对?应位置, 直接对应?参数名, 便于维护?
   * 2. 缺点: 较为麻烦. 
   */
  @Test
  public void testNamedParameterJdbcTemplate(){
    String sql = "INSERT INTO employees(last_name, email, dept_id) VALUES(:ln,:email,:deptid)";
    
    Map<String, Object> paramMap = new HashMap<>();
    paramMap.put("ln", "FF");
    paramMap.put("email", "ff@atguigu.com");
    paramMap.put("deptid", 2);
    
    namedParameterJdbcTemplate.update(sql, paramMap);
  }
}

四、简化JdbcTemplate: 扩展 JdbcDaoSupport (不推荐)

  • 需要实现JdbcDaoSupport类,必须注入数据源
/**
 * 不推荐使用 JdbcDaoSupport, 而?推荐直接使用 JdbcTempate 作?为 Dao 类的成员变?量
 */
@Repository
public class DepartmentDao extends JdbcDaoSupport{
 
  @Autowired
  public void setDataSource2(DataSource dataSource){
    setDataSource(dataSource);
  }
 
  public Department get(Integer id){
    String sql = "SELECT id, dept_name name FROM departments WHERE id = ?";
    RowMapper<Department> rowMapper = new BeanPropertyRowMapper<>(Department.class);
    return getJdbcTemplate().queryForObject(sql, rowMapper, id);
  }
  
}

整个系列项目代码: http://git.oschina.net/nmc5/spring

posted @ 2016-09-18 15:36  hp柠檬茶  阅读(301)  评论(0编辑  收藏  举报