Spring对JDBC提供了良好的支持。可以有效的简化开发。
综述:大多数情况下Spring JDBC都与IOC容器一起使用。通过配置的方式使用Spring JDBC。
而且大部分时间都是使用JdbcTemplate类(或SimpleJdbcTemplate和NamedParameterJdbcTemplate)进行开发。Spring JDBC通过DaoSupport来支持一致的数据库访问。
Spring JDBC提供如下DaoSupport实现:
- JdbcDaoSupport : 用于支持一致的JdbcTemplate访问;
- NamedParameterJdbcDaoSupport: 继承JdbcDaoSupport,同时提供NamedParameterJdbcTemplate访问;
- SimpleJdbcDaoSupport : 继承JdbcDaoSupport,同时提供SimpleJdbcTemplate访问。
由于JdbcTemplate、NamedParameterJdbcTemplate、SimpleJdbcTemplate类使用DataSourceUtils获取及释放连接,而且连接是与线程绑定的,因此这些JDBC模板类是线程安全的,即JdbcTemplate对象可以在多线程中重用。
下面实现的访问数据库的操作是使用原始的JDBC进行访问操作。
1.新建web项目,将需要的Spring jar包全部导入。
2.建立mysql数据库表【创建了名为springdemo01的数据库,建立了数据库表】通过一下命令建立数据库表:
---------+
| customer | CREATE TABLE `customer` (
`cust_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(100) NOT NULL,
`age` int(10) unsigned NOT NULL,
PRIMARY KEY (`cust_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8
---------+
3.建立与数据库表对应的模型类
package com.hebeu.customer.model;
/**
* 顾客模型类
* @author acer
*/
public class Customer {
private int custId;
private String name;
private int age;
public Customer(int int1, String string, int int2) {
this.custId = int1;
this.name = string;
this.age = int2;
}
public int getCustId() {
return custId;
}
public void setCustId(int custId) {
this.custId = custId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
4.定义客户的相关操作以及操作的实现类
package com.hebeu.customer.dao;
import com.hebeu.customer.model.Customer;
/**
* 客户相关操作
* @author acer
*/
public interface CustomerDAO {
public void insert(Customer customer);
public Customer findByCustomerId(int custId);
}
package com.hebeu.customer.dao;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import javax.sql.DataSource;
import com.hebeu.customer.model.Customer;
public class JdbcCustomerDAO implements CustomerDAO{
private DataSource dataSource;
public void setDataSource(DataSource d) {
this.dataSource = d;
}
@Override
public void insert(Customer customer) {
String sql = "INSERT INTO CUSTOMER (CUST_ID,NAME,AGE) VALUES (?,?,?)";
Connection conn = null;
try {
conn = dataSource.getConnection();
PreparedStatement ps = conn .prepareStatement(sql);
ps.setInt(1, customer.getCustId());
ps.setString(2, customer.getName());
ps.setInt(3, customer.getAge());
ps.executeUpdate();
ps.close();
} catch (SQLException e) {
e.printStackTrace();
}finally{
if(conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
@Override
public Customer findByCustomerId(int custId) {
String sql = "SELECT * FROM CUSTOMER WHERE CUST_ID = ?";
Connection conn = null;
try {
conn = dataSource.getConnection();
PreparedStatement ps = conn.prepareStatement(sql);
ps.setInt(1, custId);
Customer customer = null;
ResultSet rs = ps.executeQuery();
if (rs.next()) {
customer = new Customer(rs.getInt("CUST_ID"), rs.getString("NAME"), rs.getInt("Age"));
}
rs.close();
ps.close();
return customer;
} catch (SQLException e) {
throw new RuntimeException(e);
} finally {
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
}
}
}
}
}
这里获取数据库的连接是使用dataSource.DataSource接口是一个更好的数据源连接的方法。
5.spring的配置文件
<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-3.0.xsd">
<!-- 配置数据源-->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="DriverClassName" value="com.mysql.jdbc.Driver"></property>
<property name="url" value="jdbc:mysql://localhost:3306/springdemo01"></property>
<property name="username" value="root"></property>
<property name="password" value=""></property>
</bean>
<bean id="customerDAO" class="com.hebeu.customer.dao.JdbcCustomerDAO">
<property name="dataSource" ref="dataSource" />
</bean>
</beans>
6.测试运行
package com.hebeu.common;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.hebeu.customer.dao.CustomerDAO;
import com.hebeu.customer.model.Customer;
public class Client {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationCOntext.xml");
CustomerDAO dao = (CustomerDAO) context.getBean("customerDAO");
Customer c = new Customer(4,"张三",12);
dao.insert(c);
Customer customer1 = dao.findByCustomerId(1);
System.out.println(customer1);
}
}
这是Spring结合传统的JDBC操作实现的数据添加与查找。这里创建大量的冗余代码(创建连接,关闭连接,处理异常)中的所有DAO数据库的操作方法 - 插入,更新和删除。它的效率并不是很高,容易出错和乏味。使用Spring JDBC我们只需要进行数据的操作,关于数据库的维护都由Spring JDBC来完成。
下面的代码我们使用Spring中的JDBC 操作的接口,其他的不需要修改,只是修改一下JdbcCustomerDAO这个类。、
package com.hebeu.customer.dao;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import javax.sql.DataSource;
import org.springframework.jdbc.core.ResultSetExtractor;
import org.springframework.jdbc.core.support.JdbcDaoSupport;
import com.hebeu.customer.model.Customer;
public class JdbcCustomerDAO extends JdbcDaoSupport implements CustomerDAO{
@Override
public void insert(Customer customer) {
String sql = "INSERT INTO CUSTOMER (CUST_ID,NAME,AGE) VALUES (?,?,?)";
super.getJdbcTemplate().update(
sql,new Object[]{customer.getCustId(),customer.getName(),customer.getAge()});
}
@Override
public Customer findByCustomerId(int custId) {
return null;
}
}
查询操作先不执行。这样就是使用Spring JDBC操作后的代码。大大的简化了操作 。 在Spring JDBC开发,它总是建议使用,总是建议使用 JdbcTemplate和JdbcDaoSupport,而不使用自己的JDBC编程代码。JdbcTemplate类是对数据库相关操作的封装。
Spring JDBC 查询实例
查询单行数据【还以上面的数据库为例】
接口的定义如下:
public interface CustomerDAO {
//根据id查询单行数据
public Customer findByIdMethod1(int id);
public Customer findByIdMethos2(int id);
}
方法1:JdbcCustomerDAO类的结构不改变。继承JdbcDaoSupport。这里使用了匿名内部类对获取到的结果集进行转换。
@SuppressWarnings("unchecked")
@Override
public Customer findByIdMethod1(int id) {
String sql = "SELECT * FROM CUSTOMER WHERE CUST_ID = ?";
Customer c = (Customer)super.getJdbcTemplate().queryForObject(
sql, new Object[]{id}, new RowMapper(){
@Override
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;
}
});
return c;
}
方法2:
@SuppressWarnings({ "unchecked", "rawtypes" })
@Override
public Customer findByIdMethos2(int id) {
String sql = "SELECT * FROM CUSTOMER WHERE CUST_ID = ?";
Customer c = super.getJdbcTemplate().queryForObject(sql, new Object[]{id}, new BeanPropertyRowMapper(Customer.class));
return c;
}
多行数据查询
package com.hebeu.customer.dao;
import java.util.List;
import com.hebeu.customer.model.Customer;
/**
* 客户相关操作
* @author acer
*/
public interface CustomerDAO {
//根据id查询单行数据
public Customer findByIdMethod1(int id);
public Customer findByIdMethos2(int id);
//多行数据查询
public List<Customer> findAllMethod1();
public List<Customer> findAllMethod2();
}
方法1:
@Override
public List<Customer> findAllMethod1() {
String sql = "select * from customer";
List<Customer> customers = new ArrayList<Customer>();
List<Map<String, Object>> list = super.getJdbcTemplate().queryForList(sql);
for(Map row : list) {
Customer customer = new Customer();
customer.setCustId((long)row.get("CUST_ID"));
customer.setName((String)row.get("NAME"));
customer.setAge((long)row.get("AGE"));
customers.add(customer);
}
return customers;
}
方法2:
@Override
public List<Customer> findAllMethod2() {
String sql = "select * from customer";
List<Customer> list = getJdbcTemplate().query(sql, new BeanPropertyRowMapper(Customer.class));
return list;
}