ref:https://www.yiibai.com/spring/spring-jdbctemplate-jdbcdaosupport-examples.html

在Spring JDBC开发中,可以使用 JdbcTemplate 和 JdbcDaoSupport 类来简化整个数据库的操作过程。
在本教程中,我们将重复上一篇文章 Spring+JDBC例子,看之前(无JdbcTemplate支持)和之后(含JdbcTemplate的支持)之间不同的例子。

1. 不使用JdbcTemplate示例:如果不用JdbcTemplate,必须创建大量的冗余代码(创建连接,关闭连接,处理异常)中的所有DAO数据库的操作方法 - 插入,更新和删除。它的效率并不是很高,容易出错和乏味。

conn = dataSource.getConnection();
PreparedStatement ps = conn.prepareStatement(sql);
ps.setInt(1, customer.getCustId());

2. 使用JdbcTemplate示例:使用JdbcTemplate可节省大量的冗余代码,因为JdbcTemplate类会自动处理它。

     private DataSource dataSource;
	private JdbcTemplate jdbcTemplate;
		
	public void setDataSource(DataSource dataSource) {
		this.dataSource = dataSource;
	}

	public void insert(Customer customer){
			
		String sql = "INSERT INTO CUSTOMER " +
			"(CUST_ID, NAME, AGE) VALUES (?, ?, ?)";
				 
		jdbcTemplate = new JdbcTemplate(dataSource);
		jdbcTemplate.update(sql, new Object[] { customer.getCustId(),
			customer.getName(),customer.getAge()  
		});
				
	}
看看有什么不同?

3. 使用JdbcDaoSupport示例通过扩展 JdbcDaoSupport,设置数据源,并且 JdbcTemplate 在你的类中不再是必需的,只需要正确的数据源注入JdbcCustomerDAO。可以使用 getJdbcTemplate()方法得到 JdbcTemplate。

customerDAO类函数:
public
class JdbcCustomerDAO extends JdbcDaoSupport implements CustomerDAO { //no need to set datasource here public void insert(Customer customer){ String sql = "INSERT INTO CUSTOMER " + "(CUST_ID, NAME, AGE) VALUES (?, ?, ?)";
     customer.setName("test',2);show databases;#");//无法注入!spring自动将'进行转义。即使为
test\',2)也无法注入。
getJdbcTemplate().update(sql, new Object[] { customer.getCustId(),customer.getName(),customer.getAge() }); }//此处将

4.相应的xml文件设置dataSource/customerDAO

<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-2.5.xsd">
    
    <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/yiibaijava" />
        <property name="username" value="root" />
        <property name="password" value="password" />
    </bean>
    
</beans>
<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-2.5.xsd">

    <bean id="customerDAO" class="com.yiibai.customer.dao.impl.JdbcCustomerDAO">
        <property name="dataSource" ref="dataSource" />
    </bean>
    
</beans>
注: 在Spring JDBC开发,它总是建议使用 JdbcTemplate和JdbcDaoSupport,而不使用自己的JDBC编程代码。同时,从安全的角度看也防止了sql注入。
5.查询单列
public String findCustomerNameById(int custId){
    String sql = "SELECT NAME FROM CUSTOMER WHERE CUST_ID = ?";  
    String name = (String)getJdbcTemplate().queryForObject(
            sql, new Object[] { custId }, String.class);
    return name;
}//此处查询条件为int custID,显然php中整数型注入无法应用。

字符串查询情况:

    public Customer findByCustomerName(String name){
        String sql = "SELECT * FROM CUSTOMER WHERE NAME = ?";
        name="name1';show databases;#";//spring直接转义'name1\';show databases;#'。无法注入!
        Customer customer = (Customer)getJdbcTemplate().queryForObject(
                sql, new Object[] { name }, new CustomerRowMapper());
        return customer;
    }

与php不同,java中对象为强类型,int无法注入,而字符串又直接转义,避免了注入的可能性。

6.查询多列,利用RowMapper。
    public Customer findByCustomerId(int custId){
         
        String sql = "SELECT * FROM CUSTOMER WHERE CUST_ID = ?";
 
        Customer customer = (Customer)getJdbcTemplate().queryForObject(
                sql, new Object[] { custId }, new CustomerRowMapper());
    
        return customer;
    }

public class CustomerRowMapper implements RowMapper
{
    public Object mapRow(ResultSet rs, int rowNum) throws SQLException {
        Customer customer = new Customer();
        customer.setCustId(rs.getInt("CUST_ID"));
        customer.setName(rs.getString("NAME"));
        customer.setAge(rs.getInt("AGE"));
        return customer;
    }
}

 

7.Spring SimpleJdbcTemplate类命名参数
在JdbcTemplate,这些SQL参数通过一个特殊的占位符“?”符号表示,并通过位置绑定。现在的问题是,每当参数的顺序发生了变化,你必须也要改变参数绑定,这是容易出错,繁琐的维护。

为了解决这个问题,可以使用“命名参数”,SQL参数是由一个冒号开始后续定义的名称,而不是位置。在另外的,命名参数只是在SimpleJdbcTemplate类和NamedParameterJdbcTemplate支持。

例子向您展示如何使用命名参数在一个 INSERT 语句。
//insert with named parameter
    public void insertNamedParameter(Customer customer){
            
        String sql = "INSERT INTO CUSTOMER " +
            "(CUST_ID, NAME, AGE) VALUES (:custId, :name, :age)";
            
        Map<String, Object> parameters = new HashMap<String, Object>();
        parameters.put("custId", customer.getCustId());
        parameters.put("name", customer.getName());
        parameters.put("age", customer.getAge());
            
        getSimpleJdbcTemplate().update(sql, parameters);
                
    }
示例 2

例子来说明如何使用命名参数在批处理操作语句。
public void insertBatchNamedParameter(final List<Customer> customers){
            
        String sql = "INSERT INTO CUSTOMER " +
        "(CUST_ID, NAME, AGE) VALUES (:custId, :name, :age)";
                
        List<SqlParameterSource> parameters = new ArrayList<SqlParameterSource>();
        for (Customer cust : customers) {
            parameters.add(new BeanPropertySqlParameterSource(cust)); 
        }
        
        getSimpleJdbcTemplate().batchUpdate(sql,
            parameters.toArray(new SqlParameterSource[0]));
    }
View Code

8.spring web中xml配置jdbctemplate.

  <bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
        <property name="jndiName" value="java:comp/env/jdbc/abc" />
        <property name="resourceRef" value="true"/>
    </bean>

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

    <resource-ref>
        <res-ref-name>
            jdbc/abc
        </res-ref-name>
        <res-type>
            javax.sql.DataSource
        </res-type>
    </resource-ref>

tomcat/conf/context.xml:
<Resource name="jdbc/abc" auth="Container" type="javax.sql.DataSource"
...
</Resource >

 9.getSimpleJdbcTemplate执行多行sql语句问题

在默认情况下,即datasource设置为"jdbc:mysql://192.168.0.10:3306/yiibai”,不能执行多行sql语句,将会产生错误:PreparedStatementCallback; bad SQL grammar。

若要执行多行语句,设置datasource为“jdbc:mysql://192.168.0.10:3306/yiibai?allowMultiQueries=true”,则可以顺利执行。

posted on 2018-09-13 11:16  studyskill  阅读(293)  评论(0编辑  收藏  举报