Spring的JDBC模板使用之三--对数据表进行CRUD的操作
本文介绍使用JdbcTemplate对数据表进行CURD的操作。
1.建立数据库spring,在其中有物理表Account,还是以上两篇博文(Spring的数据库开发之一--JDBC模板的使用,Spring的JdbcTemplate使用二--使用spring配置文件)的数据表为例,表结构如下,因为上两篇已经加了2条记录了。
CREATE TABLE `account` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(50) DEFAULT NULL,
`balance` double DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
2.为了方便,这次测试的所有类和接口以及配置文件都放在cn.zdxh.jdbc.demo2的包中
引入的所有jar如下图所示
(1)Account类
package cn.zdxh.jdbc.demo2;
public class Account {
private Integer id;
private String username;
private double balance;
public Account() {
}
public Account(Integer id, String username, double balance) {
this.id = id;
this.username = username;
this.balance = balance;
}
@Override
public String toString() {
return "Account [id=" + id + ", username=" + username + ", balance=" + balance + "]";
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public double getBalance() {
return balance;
}
public void setBalance(double balance) {
this.balance = balance;
}
}
(2)IAccountDao接口
package cn.zdxh.jdbc.demo2;
import java.util.List;
//Account操作的接口
public interface IAccountDao {
int add(Account account);
int update(Account account);
int delete(Integer id);
//查询id为id的账号信息
Account findById(Integer id);
//查询所有账号的信息
List<Account> findAll();
//查询id为id的账号的Username
String findNameById(Integer id);
//统计记录数
int findNum();
}
(3)AccountDao类,该类实现了IAccountDao接口
package cn.zdxh.jdbc.demo2;
import java.util.List;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
//IAccountDao的实现类
public class AccountDao implements IAccountDao {
//使用JdbcTemplate模板进行CURD的操作,需要先声明该类属性
private JdbcTemplate jdbcTemplate;
//在配置文件中使用setter属性注入的方式,需要有无参构造方法和set方法
public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
private String sql;
@Override
public int add(Account account) {
sql="insert into account values(null,?,?)";
int num = jdbcTemplate.update(sql,account.getUsername(),account.getBalance());
if(num>0) {
System.out.println("插入记录成功");
}
else {
System.out.println("插入记录失败");
}
return num;
}
@Override
public int update(Account account) {
sql="update account set username=? ,balance=? where id=?";
int num = jdbcTemplate.update(sql,account.getUsername(),account.getBalance(),account.getId());
if(num>0) {
System.out.println("修改了id为 "+account.getId()+" 的记录成功");
}
else {
System.out.println("修改记录失败");
}
return num;
}
@Override
public int delete(Integer id) {
sql="delete from account where id=?";
int num = jdbcTemplate.update(sql,id);
if(num>0) {
System.out.println("删除id为 "+id+" 记录成功");
}
else {
System.out.println("删除d为 "+id+" 的记录失败");
}
return num;
}
@Override
public Account findById(Integer id) {
sql="select * from account where id=?";
RowMapper<Account> rowMapper = new BeanPropertyRowMapper<Account>(Account.class);
Account account = jdbcTemplate.queryForObject(sql, rowMapper, id);
return account;
}
@Override
public List<Account> findAll() {
sql="select * from account";
RowMapper<Account> rowMapper = new BeanPropertyRowMapper<Account>(Account.class);
List<Account> list = jdbcTemplate.query(sql,rowMapper);
return list;
}
@Override
public String findNameById(Integer id) {
sql="select username from account where id=?";
String username = jdbcTemplate.queryForObject(sql, String.class, id);
return username;
}
@Override
public int findNum() {
sql="select count(*) from account";
int num=jdbcTemplate.queryForObject(sql, Integer.class);
return num;
}
}
3.引入配置文件,该文件为bean2.xml,也在cn.zdxh.jdbc.demo2的包中
<?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="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql:///spring?useUnicode=true&characterEncoding=UTF-8"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</bean>
<!-- 配置jdbcTemplate -->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"/>
</bean>
<!-- 配置VO -->
<bean id="account" class="cn.zdxh.jdbc.demo2.Account"/>
<!-- 配置Dao -->
<bean id="accountDao" class="cn.zdxh.jdbc.demo2.AccountDao">
<property name="jdbcTemplate" ref="jdbcTemplate"/>
</bean>
</beans>
4.对实现类的方法进行测试AccountTest
使用Spring整合Junit进行测试,需要另外添加spring-test-4.3.6.RELEASE.jar
同普通的Unit Test不一样,需要在类上添加两个注解,另外,在类中使用@Resource注解需要使用的对象。如下图所示
(1)测试增加记录的方法
//对增加记录的方法进行测试
@Test
public void testAdd() {
account.setUsername("刘备");
account.setBalance(1000d);
accountDao.add(account);
}
测试结果:
(2)修改方法测试 代码
//测试修改方法
@Test
public void testUpdate() {
account.setId(2);
account.setUsername("诸葛亮");
account.setBalance(1200d);
accountDao.update(account);
}
测试结果
a.存在id为指定id的记录
b.不存在id为指定id的记录
//测试修改方法
@Test
public void testUpdate2() {
account.setId(5);
account.setUsername("诸葛亮");
account.setBalance(1200d);
accountDao.update(account);
}
(3)删除方法测试
a.不存在id为指定id的记录
//删除方法测试
@Test
public void testDelete() {
//不存在id号为5的记录,删除失败
account.setId(5);
accountDao.delete(account.getId());
}
b.存在id为指定id的记录
//删除方法测试
@Test
public void testDelete2() {
//存在id号为2的记录,删除成功
account.setId(2);
accountDao.delete(account.getId());
}
(4)查询
a.查询id为3的记录
b.查询所有记录
c.查询某个id号的username
d.查询记录数
测试类的代码
package cn.zdxh.jdbc.demo2;
import static org.junit.Assert.*;
import java.util.List;
import javax.annotation.Resource;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:cn/zdxh/jdbc/demo2/bean2.xml")
public class AccountTest {
@Resource(name="accountDao")
private IAccountDao accountDao;
@Resource(name="account")
private Account account;
//对增加记录的方法进行测试
@Test
public void testAdd() {
account.setUsername("刘备");
account.setBalance(1000d);
accountDao.add(account);
}
//测试修改方法
@Test
public void testUpdate() {
account.setId(2);
account.setUsername("诸葛亮");
account.setBalance(1200d);
accountDao.update(account);
}
//测试修改方法
@Test
public void testUpdate2() {
account.setId(5);
account.setUsername("诸葛亮");
account.setBalance(1200d);
accountDao.update(account);
}
//删除方法测试
@Test
public void testDelete() {
//不存在id号为5的记录,删除失败
account.setId(5);
accountDao.delete(account.getId());
}
//删除方法测试
@Test
public void testDelete2() {
//存在id号为2的记录,删除成功
account.setId(2);
accountDao.delete(account.getId());
}
//按id查询
@Test
public void testFindById() {
account.setId(3);//该id存在
Account obj=accountDao.findById(account.getId());
System.out.println(obj);
}
//查询所有记录
@Test
public void testFindAll() {
List<Account> list = accountDao.findAll();
for (Account account : list) {
System.out.println(account);
}
}
@Test
public void testFindNameById() {
account.setId(3);
String username = accountDao.findNameById(account.getId());
System.out.println("Id号为"+account.getId()+"的名字为:"+username);
}
@Test
public void testFindNum() {
System.out.println("account表的记录数为:"+accountDao.findNum());;
}
}
说明:上面的这些查询操作,如果查询结果为空,会抛出异常,org.springframework.dao.EmptyResultDataAccessException: Incorrect result size: expected 1, actual 0,并且会在控制台打印异常和trace,这是因为在JdbcTemplate 的queryForXxx方法中,如果出现异常就抛出,解决办法是,写一个JdbcTemplate的子类并且重写queryForXxx方法,让如果查询结果为空,返回Null而不是抛出异常。
总结:本文对JdbcTemplate的常用方法进行了简单的演示,该类中还有许多方法没有介绍,如果想进一步学习,建议看JdbcTemplate的源代码。