Spring +JDBC实例
JDBC 是和数据库交互最基本的的语言,在 Spring 中提供了 JdbcTemplate封装了JDBC的操作,最主要的还是 Spring IOC控制反转的特点。
参考教材:http://www.yiibai.com/spring/maven-spring-jdbc-example.html
版本信息
Tomcat 8.0
JDK 1.8
Eclipse版本 Neon.1a Release (4.6.1)
Spring 4.3.4
数据库 MySQL5.7.12
项目结构:
lib包中要有MySQL数据库连接的jar包,我导入的Spring的jar如下,其实有些包都没用到,像事务,aop。(ˇˍˇ)
源码下载:http://download.youkuaiyun.com/detail/peng_hong_fu/9695130
MySQL表
mysql> create database db_spring;
Query OK, 1 row affected (0.07 sec)
mysql> use db_spring;
Database changed
mysql> create table tb_customer(
-> CUST_ID int NOT NULL auto_increment,
-> NAME varchar(100) NOT NULL,
-> AGE int NOT NULL,
-> primary key(CUST_ID))
-> default charset=utf8;
Query OK, 0 rows affected (0.29 sec)
mysql> desc tb_customer;
+---------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------+--------------+------+-----+---------+----------------+
| CUST_ID | int(11) | NO | PRI | NULL | auto_increment |
| NAME | varchar(100) | NO | | NULL | |
| AGE | int(11) | NO | | NULL | |
+---------+--------------+------+-----+---------+----------------+
实体类Customer
Customer.java
package com.jxust.model;
/**
* 客户实体类 对应表tb_customer
* @author Peng
* @Date2016年11月27日下午8:43:03
*/
public class Customer {
private Integer custId;//id
private String name;//姓名
private Integer age;//年龄
public Customer() {
super();
}
public Customer(String name, Integer age) {
super();
this.name = name;
this.age = age;
}
public Customer(Integer custId, String name, Integer age) {
super();
this.custId = custId;
this.name = name;
this.age = age;
}
//省略 setter and getter
@Override
public String toString() {
return "Customer [custId=" + custId + ", name=" + name + ", age=" + age + "]";
}
}
数据访问对象 Dao层
CustomerDAO
package com.jxust.dao;
import java.util.List;
import com.jxust.model.Customer;
/**
* 客户管理Dao层接口
* @author Peng
* @Date2016年11月27日下午8:45:13
*/
public interface CustomerDAO {
/**
* 使用普通的JDBC操作数据库
* @param customer
*/
public void insertByJDBC(Customer customer);//添加一条客户数据
public Customer findByCustomerId(int custId);//根据ID查询客户信息
/**
* 以下方法使用JdbcTemlate
* @param customer
*/
public void insertByJdbcTemlate(Customer customer);//添加一条客户数据
public Customer findByCustomerIdByJdbcTemlate(int custId);//根据ID查询客户信息
public List<Customer> findAll();//查找所有客户信息
public void bathupdate(List<Customer> lists);//批处理添加客户数据
}
数据访问对象Dao层实现
JdbcCustomerDaoImpl.java
这是使用了普通的JDBC PreparedStatement,和spring 封装的JdbcTemplate
package com.jxust.dao.impl;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.Resource;
import javax.sql.DataSource;
import org.springframework.jdbc.core.BatchPreparedStatementSetter;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import com.jxust.dao.CustomerDAO;
import com.jxust.model.Customer;
import com.jxust.model.CustomerRowMapper;
/**
* 客户管理Dao层实现类
* @author Peng
* @Date2016年11月27日下午8:45:41
*/
public class JdbcCustomerDaoImpl implements CustomerDAO {
/**
* 这是一种装配方式 @Autowired@Qualifier("")
*/
//注入数据库连接信息,第二种装配方式
@Resource(name="dataSourceBean")
private DataSource dataSource;
public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
}
/**
* 使用JDBC的PreparedStatement 添加数据
*/
@Override
public void insertByJDBC(Customer customer) {
String sql = "INSERT INTO tb_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();
}
}
}
}
/**
* 使用JDBC的PreparedStatement查找数据
*/
@Override
public Customer findByCustomerId(int custId) {
String sql = "SELECT * FROM tb_customer WHERE CUST_ID = ?";
Connection conn = null;
Customer customer = null;
try {
conn = dataSource.getConnection();
PreparedStatement ps = conn.prepareStatement(sql);
ps.setInt(1, custId);
ResultSet rs = ps.executeQuery();
while (rs.next()) {
customer = new Customer();//这里要实例化
customer.setCustId(rs.getInt("CUST_ID"));
customer.setName(rs.getString("NAME"));
customer.setAge(rs.getInt("AGE"));
}
rs.close();
ps.close();
} catch (SQLException e) {
e.printStackTrace();
} finally {
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
return customer;
}
/**
* 使用JdbcTemplate 添加数据
*/
@Override
public void insertByJdbcTemlate(Customer customer) {
String sql = "INSERT INTO tb_customer(CUST_ID,NAME,AGE) VALUES(?,?,?)";
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
/**
* 出现以下异常
* The type org.springframework.dao.DataAccessException cannot be resolved. It is indirectly referenced from required .class files
* 导入spring-tx-4.3.4.RELEASE.jar
*/
jdbcTemplate.update(sql,new Object[]{customer.getCustId(),
customer.getName(),customer.getAge()});
}
/**
* 使用JdbcTemplate 查询数据
*/
@Override
public Customer findByCustomerIdByJdbcTemlate(int custId) {
Customer customer = new Customer();
String sql = "SELECT * FROM tb_customer WHERE CUST_ID = ?";
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
//这里可以定义一个类CustomerRowMapper实现RowMapper,封装获取Customer对象的代码
customer = (Customer) jdbcTemplate.queryForObject(sql, new Object[]{custId},new CustomerRowMapper());
//customer = (Customer) jdbcTemplate.queryForObject(sql, new Object[]{custId},new BeanPropertyRowMapper<>(Customer.class));
return customer;
}
/**
* 使用JdbcTemplate 查询所有数据
*/
@Override
public List<Customer> findAll() {
String sql = "SELECT * FROM tb_customer";
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
List<Customer> listCus = new ArrayList<>();
listCus = jdbcTemplate.query(sql, new BeanPropertyRowMapper<Customer>(Customer.class));
return listCus;
}
/**
* 使用JdbcTemplate 测试批处理
*/
@Override
public void bathupdate(List<Customer> lists) {
String sql ="INSERT INTO tb_customer(CUST_ID,NAME,AGE) VALUES(?,?,?) ";
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
jdbcTemplate.batchUpdate(sql,new BatchPreparedStatementSetter() {
@Override
public void setValues(PreparedStatement ps, int i) throws SQLException {
Customer customer = lists.get(i);
ps.setLong(1, customer.getCustId());
ps.setString(2, customer.getName());
ps.setInt(3, customer.getAge() );
}
@Override
public int getBatchSize() {
//批处理的语句个数
return lists.size();
}
});
}
}
在上面的类中,通过new JdbcTemplate类的得到实例,写这个类主要是说明继承JdbcDaoSupport,得到JdbcTemplate,在类中,直接通过getJdbcTemplate()就能得到JdbcTemplate实例。
JdbcJdbcDaoSupport.java
package com.jxust.dao.impl;
import java.util.ArrayList;
import java.util.List;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.support.JdbcDaoSupport;
import com.jxust.dao.CustomerDAO;
import com.jxust.model.Customer;
/**
* 测试采用继承JdbcDaoSupport的方式的到jdbcTemplate,在xml文件中注入dataSource
* http://www.yiibai.com/spring/spring-jdbctemplate-querying-examples.html
*
* @author Peng
* @Date2016年11月24日下午5:05:49
*/
public class JdbcJdbcDaoSupport extends JdbcDaoSupport implements CustomerDAO {
@Override
public void insertByJDBC(Customer customer) {
// TODO Auto-generated method stub
}
@Override
public Customer findByCustomerId(int custId) {
// TODO Auto-generated method stub
return null;
}
@Override
public void insertByJdbcTemlate(Customer customer) {
// TODO Auto-generated method stub
}
/**
* 查找指定列的客户信息
*/
@Override
public Customer findByCustomerIdByJdbcTemlate(int custId) {
String sql = "SELECT NAME FROM tb_customer WHERE CUST_ID = ?";
String name = (String) getJdbcTemplate().queryForObject(sql, new Object[] { custId }, String.class);
Customer cu = new Customer();
cu.setName(name);
return cu;
}
/**
* 查询所有客户信息
*/
@Override
public List<Customer> findAll() {
String sql = "SELECT * FROM tb_customer";
List<Customer> listCus = new ArrayList<>();
/**
* 方式一 /*List<Map<String,Object>> rows =
* getJdbcTemplate().queryForList(sql); for (Map row : rows) { Customer
* customer = new Customer(); customer.setCustId((Integer)
* row.get("CUST_ID")); customer.setName((String)row.get("NAME"));
* customer.setAge((Integer)row.get("AGE")); listCus.add(customer); }
*/
// 方式二
listCus = getJdbcTemplate().query(sql, new BeanPropertyRowMapper<Customer>(Customer.class));
return listCus;
}
@Override
public void bathupdate(List<Customer> lists) {
}
}
CustomerRowMapper.java
这个类主要是对数据库查询返回的结果集,你也可以不封装出来,直接写在查询方法下。
package com.jxust.model;
import java.sql.ResultSet;
import java.sql.SQLException;
import org.springframework.jdbc.core.RowMapper;
/**
* 在数据库查询中,如果返回的类型是用户自定义的类型则需要包装
* RowMapper可以将数据中的每一行封装成用户定义的类,
* @author Peng
* @Date2016年11月27日下午9:51:48
*/
public class CustomerRowMapper implements RowMapper<Object> {
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;
}
}
Spring bean配置
配置 customerDAO
Spring-Customer.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"
>
<!-- default-autowire="byName" 在头文件上配置,说明整个bean都是按name值装配属性-->
<bean id="customerDAO" class="com.jxust.dao.impl.JdbcCustomerDaoImpl" autowire="byType">
<!-- 在类中让这个属性自动装配,这里不需要配置 -->
<!-- <property name="dataSource" ref="dataSource"></property> -->
</bean>
<bean id="customerDAObyDaoSupport" class="com.jxust.dao.impl.JdbcJdbcDaoSupport">
<property name="dataSource" ref="dataSourceBean"></property>
</bean>
</beans>
配置数据源
Spring-Datesource.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="dataSourceBean"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://127.0.0.1:3306/db_spring?useSSL=false" />
<property name="username" value="root" />
<property name="password" value="root" />
</bean>
</beans>
引入上面两个Bean配置文件,测试的时候,取这个xml的数据,得到Bean。
application.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"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.3.xsd">
<!--这种方式只能用@Autowried -->
<!-- <bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor" /> -->
<!--<context:annotation-config></context:annotation-config> -->
<import resource="customer/Spring-Customer.xml"/>
<import resource="database/Spring-Datasource.xml"/>
</beans>
Junit测试
TestSpringJDBC.java
package test;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.jxust.dao.CustomerDAO;
import com.jxust.model.Customer;
/**
* 测试dao层实现类方法的类,即使是同名的方法,getBean获取不同的bean,也是不同的实现内容
* @author Peng
* @Date2016年11月24日下午5:24:14
*/
public class TestSpringJDBC {
/**
* 普通的jdbc添加、查询客户数据
*/
@Test
public void testByJDBC(){
ApplicationContext context = new
ClassPathXmlApplicationContext("application.xml");
CustomerDAO dao = (CustomerDAO) context.getBean("customerDAO");
Customer customer = new Customer(7,"李勃",21);
dao.insertByJDBC(customer);
/*根据id查询客户数据
* Customer customer = dao.findByCustomerId(6);
System.out.println(customer.toString());*/
}
/**
* JdbcTemplate
*/
@Test
public void testByJdbcTemplate(){
ApplicationContext context = new
ClassPathXmlApplicationContext("application.xml");
CustomerDAO dao = (CustomerDAO) context.getBean("customerDAO");
/*JdbcTemplate添加数据
* Customer customer = new Customer(2,"白居易",24);
dao.insertByJdbcTemlate(customer);*/
/*JdbcTemplate查找数据
* Customer customer1 = dao.findByCustomerIdByJdbcTemlate(2);
System.out.println(customer1.toString());*/
/*JdbcTemplate查找所有数据
* List<Customer> listc= dao.findAll();
for(int i=0;i<listc.size();i++){
Customer c = listc.get(i);
System.out.println(c.toString());
}*/
//测试批处理 添加数据
Customer customer1 = new Customer(3, "王维",41);
Customer customer2 = new Customer(4, "岑参",42);
Customer customer3 = new Customer(6, "陶渊明",63);
List<Customer>lists = new ArrayList<Customer>();
lists.add(customer1);
lists.add(customer2);
lists.add(customer3);
dao.bathupdate(lists);
}
/**
* 继承jdbcDaoSupport得到的JdbcTemplate
*/
@Test
public void testByjdbcDaoSupport(){
ApplicationContext context = new
ClassPathXmlApplicationContext("application.xml");
//取得bean有所不同
CustomerDAO dao = (CustomerDAO) context.getBean("customerDAObyDaoSupport");
/*-------------------------*/
List<Customer> listc= dao.findAll();
Iterator<Customer> it = listc.iterator();
while(it.hasNext()){
Customer customer = it.next();
System.out.println(customer.toString());
}
/*-------------------------*/
//Customer cu = dao.findByCustomerIdByJdbcTemlate(5);
//System.out.println(cu.getName());
}
}
关于批处理
这是一个JDBC批处理的方法
JdbcCustomerDaoImpl.java
.
.
@Override
public void bathUpdateByJDBC(List<Customer> lists) {
String sql = "INSERT INTO tb_customer(CUST_ID,NAME,AGE) VALUES(?,?,?)";
Connection conn = null;
Customer customer = null;
try {
conn = dataSource.getConnection();
PreparedStatement ps = conn.prepareStatement(sql);
for(int i=0;i<lists.size();i++){
customer = lists.get(i);
ps.setLong(1, customer.getCustId());
ps.setString(2, customer.getName());
ps.setInt(3, customer.getAge() );
ps.addBatch();
}
int [] n = ps.executeBatch();
/**
* 数组的长度就是执行成功的语句条数
* 数组内容是执行的结果,表示这条sql语句,影响了数据表,几行数据
* 大于等于0,表示执行成功
* SUCCESS_NO_INFO 执行成功 受影响的行数是未知
* EXECUTE_FAILED 执行失败
*/
System.out.println("数组n的长度"+n.length);
for(int i=0;i<n.length;i++){
System.out.println(n[i]);
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
.
.
执行这个方法
.
.
@Test
public void testbathUpdateByJDBC() {
ApplicationContext context = new ClassPathXmlApplicationContext("application.xml");
CustomerDAO dao = (CustomerDAO) context.getBean("customerDAO");
// 测试批处理 添加数据
Customer customer1 = new Customer(8, "王维", 41);
Customer customer2 = new Customer(9, "岑参", 42);
Customer customer3 = new Customer(10, "陶渊明", 63);
List<Customer> lists = new ArrayList<Customer>();
lists.add(customer1);
lists.add(customer2);
lists.add(customer3);
dao.bathUpdateByJDBC(lists);
}
.
.
数组n的长度3
1
1
1
成功执行了3条添加数据的指令,每条语句影响的行数都是1
源码下载
源码下载:http://download.youkuaiyun.com/detail/peng_hong_fu/9695130