Spring的数据库开发
Spring JDBC
Spring的JDBC模块负责数据库资源管理和错误处理,大大简化了开发人员对数据库的操作,使得开发人员可以从繁琐的数据库中解脱出来,从而将更多精力投入到编写业务逻辑中
Spring JdbcTemplate的解析
针对数据库的操作,Spring框架提供了JdbcTemplate类,该类是Spring框架数据抽象层的基础,其他更高层次的抽象类却是构建于JdbcTemplate类之上。可以说,JdbcTemplate类是Spring JDBC的核心类。
JdbcTemplate类的继承关系十分简单。它继承自抽象类JdbcAccessor,同时实现了JdbcOperations接口。
JdbcTemplate类的直接父类是JdbcAccessor,该类为子类提供了一些访问数据库时使用的公共属性。
1、DataSource:其主要功能是获取数据库连接,具体实现时还可以引入对数据库连接的缓冲池和分布式事务支持,它可以作为访问数据库资源的标准接口。
2、SQLExceptionTranslator:org.springframework.jdbc.support.SQLExceptionTranslator接口负责对SQLException进行转译工作。通过必要的设置或者获取SQLExceptionTranslator中的方法,可以使JdbcTemplate在需要处理SQLException时,委托SQLExceptionTranslator的实现类来完成相关的转义工作。
JdbcOperations接口定义了在JdbcTemplate类中可以使用操作集合,包括添加、修改、查询和删除等操作。
Spring JDBC的配置
Spring JDBC模块主要由4个包组成,分别是core(核心包)、dataSource(数据源包)、object(对象包)、support(支持包)
包名 | 说明 |
---|---|
core | 包含了JDBC的核心功能,包括JdbcTemplate类、SimpleJdbcInsert类、SimpleJdbcCall类以及NamedParameterJdbcTemplate类 |
dataSource | 访问数据源的实用工具包,他有多种数据源的实现,可以在Java EE容器的外部测试JDBC代码 |
object | 以面向对象的方式访问数据库,它允许执行查询并将返回结果作为业务对象,可以在数据表的列和业务对象的属性之间映射查询结果 |
support | 包含了core和object的支持类,例如,提供异常转换的SQLException类 |
想要使用Spring JDBC,就需要对其进行配置,在Spring中,JDBC的配置是在配置文件applicationContext中完成的。
<?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://localhost/spring"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</bean>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"/>
</bean>
<bean id="xxx" class="Xxx">
<property name="jdbcTemplate" ref="jdbcTemplate"/>
</bean>
</beans>
上述代码中,定义了3个Bean,分别是dataSource、jdbcTemplate和需要注入类的Bean。其中dataSourece对应对应的org.springframework.jdbc.datasource.DriverManagerDataSource类用于对数据源进行配置,jdbcTemplate对应的org.springframework.jdbc.core.JdbcTemplate类中定义了JdbcTemplate的相关配置。上述代码中dataSource的配置就是JDBC连接数据库时所需的4个属性。
属性名 | 含义 |
---|---|
diverClassName | 所使用的驱动名称,对应驱动JAR包中的Driver类 |
url | 数据源所在地址 |
username | 访问数据库的用户名 |
password | 访问数据库的密码 |
Spring JdbcTemplate的常用方法
在JdbcTemplate类中,提供了大量的更新和查询数据库的方法,我们就是使用这些方法来操作数据库的。
execute()
execute(String sql)方法能够完成执行SQL语句的功能。
1)在MySQL中,创建一个名为spring的数据库
2)创建一个chapter04项目、在项目中将Spring框架所需的5个基础JAR包、MySQL数据库的驱动JAR包、Spring JDBC的JAR包以及Spring事务处理的JAR包导入
3)在目录下,创建配置文件applicationContext.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="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost/spring"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</bean>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"/>
</bean>
</beans>
4)在目录下,创建一个jdbc包,在该包中创建测试类JdbcTemplateTest
package jdbc;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.jdbc.core.JdbcTemplate;
public class JdbcTemplateTest {
public static void main(String[] args){
ApplicationContext applicationContext=new ClassPathXmlApplicationContext("applicationContext.xml");
JdbcTemplate jdTemplate=(JdbcTemplate)applicationContext.getBean("jdbcTemplate");
jdTemplate.execute("create table account("
+ "id int primary key auto_increment,"
+ "username varchar(50),"
+ "balance double)");
System.out.println("账户表account创建成功!");
}
}
update()
update()方法可以完成插入、更新和删除数据的操作。在JdbcTemplate类中,提供了一系列的update()方法。
方法 | 说明 |
---|---|
int update(String sql) | 该方法是最简单的update方法重载形式,它直接执行传入的SQL语句,并返回受影响的行数 |
int update(PreparedStatementCreator psc) | 该方法执行从PreparedStatementCreator返回的语句,然后返回受影响的行数 |
int update(String sql,PreparedStatementSetter pss) | 该方法通过PreparedStatementSetter 设置SQL语句中的参数,并返回受影响的行数 |
int update(String sql,Object… args) | 该方法使用Object…设置SQL语句中的参数,要求参数不能为NULL,并返回受影响的行数 |
1)在项目中jdbc包中,创建Account类
package jdbc;
public class Account {
private Integer id;
private String username;
private Double 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;
}
public String toString(){
return "Account [id="+id+","
+ "username="+username+
",balance="+balance+"]";
}
}
2)创建接口AccountDao
package jdbc;
public interface AccountDao {
public int addAccount(Account account);
public int updateAccount(Account account);
public int deleteAccount(int id);
}
3)创建AccountDao接口的实现类AccountDaoImpl
package jdbc;
import org.springframework.jdbc.core.JdbcTemplate;
public class AccountDaoImpl implements AccountDao{
private JdbcTemplate jdbcTemplate;
public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
@Override
public int addAccount(Account account) {
String sql="insert into account(username,balance)value(?,?)";
Object[] obj=new Object[]{
account.getUsername(),
account.getBalance()
};
int num=this.jdbcTemplate.update(sql, obj);
return num;
}
@Override
public int updateAccount(Account account) {
String sql="update account set username=? , balance=? where id=?";
Object[] obj=new Object[]{
account.getUsername(),
account.getBalance(),
account.getId()
};
int num=this.jdbcTemplate.update(sql, obj);
return num;
}
@Override
public int deleteAccount(int id) {
String sql="delete from account where id=?";
int num=this.jdbcTemplate.update(sql, id);
return num;
}
}
4)在applicationContext.xml中定义一个Bean
<bean id="accountDao" class="jdbc.AccountDaoImpl">
<property name="jdbcTemplate" ref="jdbcTemplate"/>
</bean>
5)在测试类JdbcTemplateTest中,添加一个测试方法addAccountTest(),该方法用于主要用于添加用户账户信息
package jdbc;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.jdbc.core.JdbcTemplate;
public class JdbcTemplateTest {
public static void main(String[] args){
ApplicationContext applicationContext=new ClassPathXmlApplicationContext("applicationContext.xml");
JdbcTemplate jdTemplate=(JdbcTemplate)applicationContext.getBean("jdbcTemplate");
jdTemplate.execute("create table account("
+ "id int primary key auto_increment,"
+ "username varchar(50),"
+ "balance double)");
System.out.println("账户表account创建成功!");
}
@Test
public void addAccountTest(){
ApplicationContext applicationContext=new ClassPathXmlApplicationContext("applicationContext.xml");
AccountDao accountDao=(AccountDao)applicationContext.getBean("accountDao");
Account account=new Account();
account.setUsername("tom");
account.setBalance(1000.00);
int num=accountDao.addAccount(account);
if(num>0){
System.out.println("成功插入了"+num+"条数据!");
}else{
System.out.println("插入操作执行失败!");
}
}
}
6)添加一个测试方法updateAccountTest()
@Test
public void updateAccountTest(){
ApplicationContext applicationContext=new ClassPathXmlApplicationContext("applicationContext.xml");
AccountDao accountDao=(AccountDao)applicationContext.getBean("accountDao");
Account account=new Account();
account.setId(1);
account.setUsername("tom");
account.setBalance(2000.00);
int num=accountDao.updateAccount(account);
if(num>0){
System.out.println("成功修改了"+num+"条数据!");
}else{
System.out.println("修改操作执行失败!");
}
}
7)添加一个测试方法deleteAccountTest()
@Test
public void deleteAccountTest(){
ApplicationContext applicationContext=new ClassPathXmlApplicationContext("applicationContext.xml");
AccountDao accountDao=(AccountDao)applicationContext.getBean("accountDao");
int num=accountDao.deleteAccount(1);
if(num>0){
System.out.println("成功删除了"+num+"条数据!");
}else{
System.out.println("删除操作执行失败!");
}
}
query()
JdbcTemplate类中还提供了大量的query()方法来处理各种对数据库表的查询操作
方法 | 说明 |
---|---|
List query(String sql,RowMapper rowMapper) | 执行String类型参数提供的SQL语句,并通过RowMapper返回一个List类型的结果 |
List query(String sql,PreparedStatementSetter pss,RowMapper rowMapper) | 根据String类型参数提供的SQL语句创建PreparedStatement对象,通过RowMapper将结果返回到List中 |
List query(String sql,Object[] args,RowMapper rowMapper) | 使用Object[]的值来设置SQL语句中的参数值,采用RowMapper回调方法可以直接返回List类型的数据 |
queryForObject(String sql,RowMapper rowMapper,Object… args) | 将args参数绑定到SQL语句中,并通过RowMapper返回一个Object类型的单行记录 |
queryForList(String sql,Object[] args,class<T> elementType) | 该方法可以返回多行数据的结果,但必须是返回列表,elementType参数返回的是List元素类型 |
1)向数据表account中插入几条数据
2)在AccountDao中,分别创建一个通过id查询单个账户和查询所有账户的方法
public Account findAccountById(int id);
public List<Account> findAllAccount();
3)在AccountDaoImpl中实现接口方法
@Override
public Account findAccountById(int id) {
String sql="select * from account where id=?";
RowMapper<Account> rowMapper=new BeanPropertyRowMapper<Account>(Account.class);
return this.jdbcTemplate.queryForObject(sql, rowMapper, id);
}
@Override
public List<Account> findAllAccount() {
String sql="select * from account";
RowMapper<Account> rowMapper=new BeanPropertyRowMapper<Account>(Account.class);
return this.jdbcTemplate.query(sql, rowMapper);
}
BeanPropertyRowMapper是RowMapper接口的实现类,它可以自动地将数据表中的数据映射到用户自定义的类中(前提是用户自定义类中的字段要与数据表中的字段相对应)。
4)添加一个测试方法findAccountByidTest()
@Test
public void findAccountByidTest(){
ApplicationContext applicationContext=new ClassPathXmlApplicationContext("applicationContext.xml");
AccountDao accountDao=(AccountDao)applicationContext.getBean("accountDao");
Account account=accountDao.findAccountById(1);
System.out.println(account);
}
5)添加一个测试方法findAllAccountTest()
@Test
public void findAllAccountTest(){
ApplicationContext applicationContext=new ClassPathXmlApplicationContext("applicationContext.xml");
AccountDao accountDao=(AccountDao)applicationContext.getBean("accountDao");
List<Account> account=accountDao.findAllAccount();
for(Account act:account){
System.out.println(act);
}
}