现在我们对Spring框架核心技术已经有了一定的了解,Spring框架降低了Java EE API的使用难度,其中也包括JDBC的使用难度,JDBC是Spring数据访问 / 集成中的重要模块,我们将学习Spring的数据库开发。
1. Spring JDBC
1.1 Spring JDBC模块的作用
Spring的JDBC模块负责数据库资源管理和错误处理,大大简化了开发人员对数据库的操作,使得开发人员可以从繁琐的数据库操作中解脱出来,从而将更多的精力投入到编写业务逻辑当中。
1.2 Spring JDBC的配置
Spring JDBC模块主要由4个包组成,分别是core(核心包)、dataSource(数据源包)、object(对象包)和support(支持包)。
包名 | 说明 |
---|---|
core | 包含了JDBC的核心功能,包括JdbcTemplate类、SimpleJdbcInsert 类、SimpleJdbcCall类以及NamedParameterJdbcTemplate类。 |
dataSource | 访问数据源的实用工具类,它有多种数据源的实现,可以在Java EE容器外部测试JDBC代码。 |
object | 以面向对象的方式访问数据库,它允许执行查询并将返回结果作为业务对象,可以在数据表的列和业务对象的属性之间映射查询结果。 |
support | 包含了core和object包的支持类,例如,提供异常转换功能的SQLException类。 |
配置模板如下:
2. Spring JdbcTemplate的解析以及其常用方法
2.1 Spring JdbcTemplate的解析
Spring框架提供了JdbcTemplate类,该类是Spring框架数据抽象层的基础,可以说,JdbcTemplate类是Spring JDBC的核心类。JdbcTemplate类的直接父类是JdbcAccessor(抽象类),该类为子类提供了一些访问数据库时使用的公共属性,具体如下。
• DataSource:其主要功能是获取数据库连接,还可以引入对数据库连接的缓冲池和分布式事务的支持,它可以作为访问数据库资源的标准接口。
• SQLExceptionTranslator:该接口负责对SQLException进行转译工作。通过必要的设置获取SQLExceptionTranslator中的方法,可以对JdbcTemplate在需要处理SQLException时,委托SQLExceptionTranslator的实现类来完成相关的转译工作。
• JdbcOperations接口定义了在JdbcTemplate类中可以使用的操作集合,包括添加、修改、查询和删除等操作。。
2.2 Spring JdbcTemplate的常用方法
2.2.1 execute()方法
execute(String sql)方法能够完成执行SQL语句的功能我们以创建数据表的SQL语句为例来演示。
(1).在MySQL中创建一个Student的数据库,方便起见,我在Navicat for MySQL建立的。MySQL安装以及Navicat for MySQL安装请参考我以前发过的文章。
链接:https://blog.csdn.net/weixin_43468667/article/details/88827544
(2).打开Eclipse,在SpringTest项目的src目录下,创建一个com.example.jdbc包,包中创建配置文件beans.xml。
<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>
<property name="url" value="jdbc:mysql://localhost/account_Info">property>
<property name="username" value="root">property>
<property name="password" value="root">property>
bean>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource">property>
bean>
beans>
(3).在com.example.jdbc包中,包中创建测试类JdbcTemplateTest。
package com.example.jdbc;
import org.springframework.context.ApplicationContext;
import
org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.jdbc.core.JdbcTemplate;
public class JdbcTemplateTest {
/**
* 使用execute()方法建表
*/
public static void main(String[] args) {
// 加载配置文件
ApplicationContext ac =
new ClassPathXmlApplicationContext("com/example/jdbc/beans.xml");
// 获取JdbcTemplate实例
JdbcTemplate jdTemplate =
(JdbcTemplate) ac.getBean("jdbcTemplate");
// 使用execute()方法执行SQL语句,创建用户账户管理表account
jdTemplate.execute("create table account(" +
"id int primary key auto_increment," +
"username varchar(50)," +
"balance double)");
System.out.println("账户表account创建成功!");
}
}
2.2.2 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).在com.example.jdbc包中,包中创建Account类。
package com.example.jdbc;
public class Account {
private Integer id; //账户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;
}
@Override
public String toString() {
return "Account [id=" + id + ", username=" + username + ", balance=" + balance + "]";
}
}
(2).在com.example.jdbc包中,包中创建接口AccountDao,定义添加、更新和删除的方法,再创建接口的实现类AccountDaoImpl类。
package com.example.jdbc;
public interface AccountDao {
public int addAccount(Account account);
public int updateAccount(Account account);
public int deleteAccount(int id);
}
package com.example.jdbc;
import org.springframework.jdbc.core.JdbcTemplate;
public class AccountDaoImpl implements AccountDao{
//注入JdbcTemplate,提供set方法,得到JdbcTemplate对象
private JdbcTemplate jdbcTemplate;
public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
//添加账户
@Override
public int addAccount(Account account) {
// TODO Auto-generated method stub
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) {
// TODO Auto-generated method stub
String sql = "update account set username=?,balance=? where id=?";
//String sql = "update account set username=?,balance=? where id = ?";
Object[] params = new Object[]{
account.getUsername(),
account.getBalance(),
account.getId()
};
int num = this.jdbcTemplate.update(sql, params);
return num;
}
//删除账户
@Override
public int deleteAccount(int id) {
// TODO Auto-generated method stub
String sql = "delete from account where id=?";
int num = this.jdbcTemplate.update(sql, id);
return num;
}
}
(3).在com.example.jdbc包,在配置文件beans.xml增加以下代码,定义一个id为accountDao的Bean,用于将jdbcTemplate注入到accountDao实例中。
<bean id="accountDao" class="com.example.jdbc.AccountDaoImpl">
<property name="jdbcTemplate" ref="jdbcTemplate">property>
bean>
(4).在com.example.jdbc包,添加测试类,执行插入操作。
package com.example.jdbc;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.jdbc.core.JdbcTemplate;
public class addAccountTest {
public static void main(String[] args) {
// 加载配置文件
ApplicationContext ac =
new ClassPathXmlApplicationContext("com/example/jdbc/beans.xml");
//获取AccountDao实例
AccountDao accountDao = (AccountDao) ac.getBean("accountDao");
// 获取JdbcTemplate实例
JdbcTemplate jdTemplate =
(JdbcTemplate) ac.getBean("jdbcTemplate");
Account account = new Account();
account.setUsername("zhangsan");
account.setBalance(1000.0);
int num = accountDao.addAccount(account);
if (num>0) {
System.out.println("成功插入了"+ num + "条数据!");
}else {
System.out.println("插入操作执行失败!");
}
}
}
(5).在com.example.jdbc包,添加测试类,执行更新操作。
package com.example.jdbc;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.jdbc.core.JdbcTemplate;
public class updateAccountTest {
public static void main(String[] args) {
// 加载配置文件
ApplicationContext ac =
new ClassPathXmlApplicationContext("com/example/jdbc/beans.xml");
//获取AccountDao实例
AccountDao accountDao = (AccountDao) ac.getBean("accountDao");
// 获取JdbcTemplate实例
JdbcTemplate jdTemplate =
(JdbcTemplate) ac.getBean("jdbcTemplate");
Account account = new Account();
account.setId(1);
account.setUsername("zhangsan");
account.setBalance(2000.0);
int num = accountDao.updateAccount(account);
if (num>0) {
System.out.println("成功修改了"+ num + "条数据!");
}else {
System.out.println("修改操作执行失败!");
}
}
}
(6).在com.example.jdbc包,添加测试类,执行删除操作。
package com.example.jdbc;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class deleteAccountTest {
public static void main(String[] args) {
// 加载配置文件
ApplicationContext ac =
new ClassPathXmlApplicationContext("com/example/jdbc/beans.xml");
//获取AccountDao实例
AccountDao accountDao = (AccountDao) ac.getBean("accountDao");
int num = accountDao.deleteAccount(1);
if (num>0) {
System.out.println("成功删除了"+ num + "条数据!");
}else {
System.out.println("删除操作执行失败!");
}
}
}
2.2.3 query()方法
JdbcTemplate类中还提供了大量的query()方法来处理各种对数据库表的查询操作。其中,常用的几个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 elementType) | 该方法可以返回多行数据的结果,但必须是返回列表,elementType参数返回的是List元素类型。 |
(1)向数据表中插入几条数据,我使用的是Navicat for MySQL。
(2).在com.example.jdbc包,在原有接口AccountDao的基础上,添加通过id查询单个账户和查询所有账户的方法。在AccountDaoImpl中实现接口中的方法。
package com.example.jdbc;
import java.util.List;
public interface AccountDao {
public int addAccount(Account account);
public int updateAccount(Account account);
public int deleteAccount(int id);
public Account findAccountById(int id);
public List<Account> findAllAccount();
}
下面代码中,BeanPropertyRowMapper是RowMapper接口的实现类,它可以自动地将数据表映射到用户自定义的类中。
package com.example.jdbc;
import java.util.List;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
public class AccountDaoImpl implements AccountDao{
//注入JdbcTemplate,提供set方法,得到JdbcTemplate对象
private JdbcTemplate jdbcTemplate;
public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
//添加账户
@Override
public int addAccount(Account account) {
// TODO Auto-generated method stub
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) {
// TODO Auto-generated method stub
String sql = "update account set username=?,balance=? where id=?";
//String sql = "update account set username=?,balance=? where id = ?";
Object[] params = new Object[]{
account.getUsername(),
account.getBalance(),
account.getId()
};
int num = this.jdbcTemplate.update(sql, params);
return num;
}
//删除账户
@Override
public int deleteAccount(int id) {
// TODO Auto-generated method stub
String sql = "delete from account where id=?";
int num = this.jdbcTemplate.update(sql, id);
return num;
}
@Override
public Account findAccountById(int id) {
// TODO Auto-generated method stub
//定义SQL语句
String sql = "select * from account where id = ?";
//创建新的BeanPropertyRowMapper对象
RowMapper<Account> rowMapper =
new BeanPropertyRowMapper<Account>(Account.class);
return this.jdbcTemplate.queryForObject(sql, rowMapper,id);
}
@Override
public List<Account> findAllAccount() {
// TODO Auto-generated method stub
//定义SQL语句
String sql = "select * from account";
//创建新的BeanPropertyRowMapper对象
RowMapper<Account> rowMapper =
new BeanPropertyRowMapper<Account>(Account.class);
return this.jdbcTemplate.query(sql, rowMapper);
}
}
(3).在com.example.jdbc包,创建测试类findAccountByIdTest。
package com.example.jdbc;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class findAccountByIdTest {
public static void main(String[] args) {
// 加载配置文件
ApplicationContext ac =
new ClassPathXmlApplicationContext("com/example/jdbc/beans.xml");
//获取AccountDao实例
AccountDao accountDao = (AccountDao) ac.getBean("accountDao");
Account account = accountDao.findAccountById(1);
System.out.println(account);
}
}
运行结果:
(4).在com.example.jdbc包,创建测试类findAllAccountTest。
package com.example.jdbc;
import java.util.List;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class findAllAccountTest {
public static void main(String[] args) {
// 加载配置文件
ApplicationContext ac =
new ClassPathXmlApplicationContext("com/example/jdbc/beans.xml");
//获取AccountDao实例
AccountDao accountDao = (AccountDao) ac.getBean("accountDao");
List<Account> account = accountDao.findAllAccount();
for(Account act: account){
System.out.println(act);
}
}
}
这就是Spring的数据库简单开发,若有错漏,欢迎指正,希望大家一起学习进步!!!!
如果转载以及CV操作,请务必注明出处,谢谢!