zoukankan      html  css  js  c++  java
  • springjdbc

    摘自http://www.cnblogs.com/jokerjason/p/5891323.html

    Spring JDBC 可以理解为对于JDBC的封装使用,简化了不少重复代码并减少了SQL错误问题。

    一、概述

    在Spring JDBC模块中,所有的类可以被分到四个单独的包:
    1)core
    即核心包,它包含了JDBC的核心功能。此包内有很多重要的类,包括:JdbcTemplate类、SimpleJdbcInsert类,SimpleJdbcCall类,以及NamedParameterJdbcTemplate类。
    2)datasource
    即数据源包,访问数据源的实用工具类。它有多种数据源的实现,可以在JavaEE容器外部测试JDBC代码。
    3)object
    即对象包,以面向对象的方式访问数据库。它允许执行查询并返回结果作为业务对象。它可以在数据表的列和业务对象的属性之间映射查询结果。
    4)support
    即支持包,是core包和object包的支持类。例如提供了异常转换功能的SQLException类。

    二、配置
    以MySQL数据库为例,开始简单的数据源配置:

    复制代码
    @Configuration
    @ComponentScan("com.ch.myalbumjdbc")
    public class SpringJdbcConfig {
        @Bean
        public DataSource mysqlDataSource() {
            DriverManagerDataSource dataSource = new DriverManagerDataSource();
            dataSource.setDriverClassName("com.mysql.jdbc.Driver");
            dataSource.setUrl("jdbc:mysql://localhost:3306/springjdbc");
            dataSource.setUsername("guest_user");
            dataSource.setPassword("guest_password");
    
    
            return dataSource;
        }
    }
    复制代码

    也可以使用XML配置来实现前面的注释配置的效果:

    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" 
      destroy-method="close">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/springjdbc"/>
        <property name="username" value="guest_user"/>
        <property name="password" value="guest_password"/>
    </bean>

    三、JdbcTemplate的使用和运行查询
    1、基本的查询
    JDBC模板是Spring JDBC模块中主要的API,它提供了常见的数据库访问功能:

    int result = jdbcTemplate.queryForObject(
    "SELECT COUNT(*) FROM EMPLOYEE", Integer.class);

    下面是简单的插入功能:

    public int addEmplyee(int id) {
        return jdbcTemplate.update(
            "INSERT INTO EMPLOYEE VALUES (?, ?, ?, ?)", 5, "Bill", "Gates", "USA");
    }

    2、查询与命名参数
    要获得命名参数的支持,我们需要使用Spring JDBC提供的其它JDBC模板——NamedParameterJdbcTemplate。
    此类封装了JbdcTemplate,并提供了使用“?”来替代指定参数的传统语法。它使用传递的参数来替换占位符“?”,以执行传参的查询:

    SqlParameterSource namedParameters = new MapSqlParameterSource().addValue("id", 1);
    return namedParameterJdbcTemplate.queryForObject(
    "SELECT FIRST_NAME FROM EMPLOYEE WHERE ID = :id", namedParameters, String.class);

    请注意,我们使用的是MapSqlParameterSource来提供值的命名参数。
    下面是使用bean类的属性来确定命名参数简单例子:

    复制代码
    Employee employee = new Employee();
    employee.setFirstName("James");
    
    String SELECT_BY_ID = "SELECT COUNT(*) FROM EMPLOYEE WHERE FIRST_NAME = :firstName";
    
    SqlParameterSource namedParameters = new BeanPropertySqlParameterSource(employee);
    return namedParameterJdbcTemplate.queryForObject(SELECT_BY_ID, namedParameters, Integer.class);
    复制代码

    3、把查询结果映射到Java对象

    还有一个非常有用的功能是把查询结果映射到Java对象——通过实现RowMapper接口。
    例如,对于查询返回的每一行结果,Spring会使用该行映射来填充Java bean:

    复制代码
    public class EmployeeRowMapper implements RowMapper<Employee> {
        @Override
        public Employee mapRow(ResultSet rs, int rowNum) throws SQLException {
            Employee employee = new Employee();
    
    
            employee.setId(rs.getInt("ID"));
            employee.setFirstName(rs.getString("FIRST_NAME"));
            employee.setLastName(rs.getString("LAST_NAME"));
            employee.setAddress(rs.getString("ADDRESS"));
    
    
            return employee;
        }
    }
    复制代码

    现在,我们传递行映射器给查询API,并得到完全填充好的Java对象:

    String query = "SELECT * FROM EMPLOYEE WHERE ID = ?";
    List<Employee> employees = jdbcTemplate.queryForObject(
    query, new Object[] { id }, new EmployeeRowMapper());

    四、使用SimpleJdbc类实现JDBC操作
    SimpleJdbc类提供简单的方法来配置和执行SQL语句。这些类使用数据库的元数据来构建基本的查询。 SimpleJdbcInsert类和SimpleJdbcCall类提供了更简单的方式来执行插入和存储过程的调用。
    1、SimpleJdbcInsert类
    下面,让我们来看看执行简单的插入语句的最低配置,基于SimpleJdbcInsert类的配置产生的INSERT语句。
    所有您需要提供的是:表名、列名和值。让我们先创建SimpleJdbcInsert:

    SimpleJdbcInsert simpleJdbcInsert = new SimpleJdbcInsert(dataSource).withTableName("EMPLOYEE");

    现在提供列名和值,并执行操作:

    复制代码
    public int addEmplyee(Employee emp) {
        Map<String, Object> parameters = new HashMap<String, Object>();
        parameters.put("ID", emp.getId());
        parameters.put("FIRST_NAME", emp.getFirstName());
        parameters.put("LAST_NAME", emp.getLastName());
        parameters.put("ADDRESS", emp.getAddress());
    
    
        return simpleJdbcInsert.execute(parameters);
    }
    复制代码

    为了让数据库生成主键,我们可以使用executeAndReturnKey() API,我们还需要配置的实际自动生成的列:

    复制代码
    SimpleJdbcInsert simpleJdbcInsert = new SimpleJdbcInsert(dataSource)
                                            .withTableName("EMPLOYEE")
                                            .usingGeneratedKeyColumns("ID");
    
    
    Number id = simpleJdbcInsert.executeAndReturnKey(parameters);
    System.out.println("Generated id - " + id.longValue());
    复制代码

    2、用SimpleJdbcCall调用存储过程
    执行存储过程——使用SimpleJdbcCall的抽象:

    复制代码
    SimpleJdbcCall simpleJdbcCall = new SimpleJdbcCall(dataSource)
                                 .withProcedureName("READ_EMPLOYEE");
    
    
    public Employee getEmployeeUsingSimpleJdbcCall(int id) {
        SqlParameterSource in = new MapSqlParameterSource().addValue("in_id", id);
        Map<String, Object> out = simpleJdbcCall.execute(in);
    
    
        Employee emp = new Employee();
        emp.setFirstName((String) out.get("FIRST_NAME"));
        emp.setLastName((String) out.get("LAST_NAME"));
    
    
        return emp;
    }
    复制代码

    五、批处理操作
    另一个简单的用例——把多种操作合在一起实现批处理
    1、使用JdbcTemplate执行基本的批处理操作
    使用JdbcTemplate类,通过batchUpdate() API来执行基本的批处理操作:
    注意BatchPreparedStatementSetter实现是很有趣的。

    复制代码
    public int[] batchUpdateUsingJdbcTemplate(List<Employee> employees) {
        return jdbcTemplate.batchUpdate("INSERT INTO EMPLOYEE VALUES (?, ?, ?, ?)",
            new BatchPreparedStatementSetter() {
                @Override
                public void setValues(PreparedStatement ps, int i) throws SQLException {
                    ps.setInt(1, employees.get(i).getId());
                    ps.setString(2, employees.get(i).getFirstName());
                    ps.setString(3, employees.get(i).getLastName());
                    ps.setString(4, employees.get(i).getAddress();
                }
                @Override
                public int getBatchSize() {
                    return 50;
                }
            });
    }
    复制代码

    2、使用NamedParameterJdbcTemplate执行批处理操作
    对于批处理操作,还可以选择使用NamedParameterJdbcTemplate的batchUpdate() API来执行。
    此API比先前的更简单——无需实现任何额外的接口来设置参数,因为它有一个内部的预准备语句的setter来传递预设的参数值。
    参数值可以通过batchUpdate()方法传递给SqlParameterSource的数组。

    SqlParameterSource[] batch = SqlParameterSourceUtils.createBatch(employees.toArray());
    int[] updateCounts = namedParameterJdbcTemplate.batchUpdate(
        "INSERT INTO EMPLOYEE VALUES (:id, :firstName, :lastName, :address)", batch);
    return updateCounts;
  • 相关阅读:
    JAVA基础 (三)反射 深入解析反射机制
    JAVA基础 (二)反射 深入解析反射机制
    JAVA注解引发的思考
    深入理解jsonp解决跨域访问
    设计模式之简单工厂模式
    设计模式之接口隔离原则
    设计模式之迪米特法则
    设计模式之依赖倒置原则
    设计模式之里氏替换原则
    设计模式之开放封闭原则
  • 原文地址:https://www.cnblogs.com/zipon/p/5891439.html
Copyright © 2011-2022 走看看