Spring JDBC
Spring的JDBC模块负责数据库资源管理和错误处理,大大简化了开发人员对数据库的操作,
使得开发人员可以从烦琐的数据库操作中解脱出来,从而将更多的精力投入到编写业务逻辑中。
接下来的两个小节,将针对Spring中的JDBC模块内容进行详细的讲解。
Spring JDBCTemplate的解析
针对数据库的操作,Spring框架提供了JdbcTemplate类,该类是Spring框架数据抽象层的基础,其他更高层次的抽象类却是构建于JdbcTemplate类之上。可以说,JdbcTemplate类是Spring JDBC的核心类。
Spring JDBC的配置
Spring JDBC模块主要由4个包组成,分别是core(核心包)、dataSource(数据源包)、object(对象包)和support(支持包),
关于这4个包的具体说明如表
Spring对数据库的操作都封装在了这几个包中,而想要使用Spring JDBC,就需要对其进行配置。
在Spring中,JDBC的配置是在配置文件applicationContext.xml中完成
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:p="http://www.springframework.org/schema/p" 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">
<!-- 1配置数据源 --> <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/test"></property> <!-- 连接数据库的用户名 --> <property name="username" value="root"></property> <!-- 连接数据库的密码 --> <property name="password" value="root"></property> </bean>
<!-- 2.配置JDBC模板 --> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <!-- 默认必须使用数据源 --> <property name="dataSource" ref="dataSource"></property> </bean> <!-- 定义id为accountDao的Bean --> <bean id="accountDao" class="com.spring.jdbc.AccountDaoImp"> <!-- 将jdbcTemplate注入到accountDao实例中 --> <property name="jdbcTemplate" ref="jdbcTemplate"></property>
<!--本部分三步骤是固定格式,第三步是注入类--> </bean>
</beans>
dataSource的4个属性
需要根据数据库类型或者机器配置的不同设置相应的属性值。例如,如果数据库类型不同,需要更改驱动名称;
如果数据库不在本地,则需要将地址中的localhost替换成相应的主机IP;
如果修改过MySQL数据库的端口号(默认为3306),则需要加上修改后的端口号,如果未修改,则端口号可以省略
4.2Spring JdbcTemplate的常用方法
4.2.1execute():execute(String sql)方法能够完成执行SQL语句的功能
下面以创建数据表的SQL语句为例
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:p="http://www.springframework.org/schema/p" 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"> <!-- 1配置数据源 --> <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/test"></property> <!-- 连接数据库的用户名 --> <property name="username" value="root"></property> <!-- 连接数据库的密码 --> <property name="password" value="root"></property> </bean> <!-- 2.配置JDBC模板 --> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <!-- 默认必须使用数据源 --> <property name="dataSource" ref="dataSource"></property> </bean> </beans>
编写测试程序
package com.spring.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实例 JdbcTemplate jdbcTemplate= (JdbcTemplate)applicationContext.getBean("jdbcTemplate"); //使用execute()方法执行SQL语句 String sqlString="create table account ("+ "id int primary key auto_increment,"+ "username varchar(50),"+ "balance double)"; jdbcTemplate.execute(sqlString); System.out.println("创建成功"); } }
4.2.2 update()
update()方法可以完成插入、更新和删除数据的操作。在JdbcTemplate类中,提供了一系列的update()方法,其常用方法如表
接下来,通过一个用户账户管理的案例来演示update()方法的使用,
具体步骤如下。(1)在项目的包中,创建Account类,在该类中定义id、username和balance属性,以及其对应的getter/setter方法
package com.spring.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 + "]"; } }
创建接口AccountDao,并在接口中定义添加、更新和删除账户的方法。
package com.spring.jdbc; import java.util.List; public interface AccountDao { //添加 public int addAccount(Account account); //更新 public int updateAccount(Account account); //删除 public int deleteAccount(int id); //通过id查询 public Account findAccountById(int id); //查询所有账户 public List<Account> findAllAccount(); }
创建AccountDao接口的实现类AccountDaoImpl,并在类中实现添加、更新和删除账户的方法
package com.spring.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 AccountDaoImp implements AccountDao{ //声明JdbcTemplate属性以及其setter方法 private JdbcTemplate jdbcTemplate; public void setJdbcTemplate(JdbcTemplate jdbcTemplate) { this.jdbcTemplate=jdbcTemplate; } //添加账户 public int addAccount(Account account) { //定义SQL String sql="insert into account (username,balance) values (?,?)"; //定义数组来存储SQL语句中的参数 Object[] obj=new Object[] { account.getUsername(), account.getBalance() }; //执行添加操作,返回的是受SQL语句影响的记录条数 int num=this.jdbcTemplate.update(sql,obj); return num; } //更新账户 public int updateAccount(Account account) { //定义SQL String sql="update account set username=?,balance=? where id=?"; //定义数组存储SQL语句中的参数 Object[] params =new Object[] { account.getUsername(), account.getBalance(), account.getId() }; //执行更新操作,返回的是受SQL影响的行数 int num=this.jdbcTemplate.update(sql,params); return num; } //删除账户 public int deleteAccount(int id) { //定义SQL String sql="delete from account where id=?"; //执行删除操作 int num=this.jdbcTemplate.update(sql,id); return num; } }
在applicationContext.xml中,定义一个id为accountDao的Bean,该Bean用于将jdbcTemplate注入到accountDao实例中
<!-- 定义id为accountDao的Bean --> <bean id="accountDao" class="com.spring.jdbc.AccountDaoImp"> <!-- 将jdbcTemplate注入到accountDao实例中 --> <property name="jdbcTemplate" ref="jdbcTemplate"></property> </bean>
在测试类JdbcTemplateTest中,添加一个测试方法addAccountTest(),该方法主要用于添加用户账户信息,其代码如下所示
package com.spring.test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import org.springframework.jdbc.core.JdbcTemplate; import com.spring.jdbc.Account; import com.spring.jdbc.AccountDao; public class JdbcTemplateTestDemo2 { //加载配置文件 ApplicationContext applicationContext= new ClassPathXmlApplicationContext("applicationContext.xml"); //获取AccountDao实例 AccountDao accountDao= (AccountDao) applicationContext.getBean("accountDao"); public void add() { //创建Account对象,并向Account对象中添加数据 Account account=new Account(); account.setUsername("tom"); account.setBalance(1000.00); //执行addAccount()方法,并获取返回结果 int num=accountDao.addAccount(account); if(num>0) { System.out.println("成功插入了"+num+"条数据"); }else { System.out.println("插入操作失败"); } } public void delete() { int num=accountDao.deleteAccount(2); if(num>0) { System.out.println("成功删除了"+num+"条数据"); }else { System.out.println("删除操作失败"); } } public static void main(String[] args) { JdbcTemplateTestDemo2 jdbcTemplateTestDemo2= new JdbcTemplateTestDemo2(); //jdbcTemplateTestDemo2.add(); jdbcTemplateTestDemo2.delete(); } }
4.2.3 query()
JdbcTemplate类中还提供了大量的query()方法来处理各种对数据库表的查询操作。其中,常用的几个query()方法如表4-4所示
在AccountDao中,分别创建一个通过id查询单个账户和查询所有账户的方法,其代码如下所示。
//通过id查询 public Account findAccountById(int id); //查询所有账户 public List<Account> findAllAccount();
在AccountDao接口的实现类AccountDaoImpl中,实现接口中的方法,并使用query()方法分别进行查询,其代码如下所示
public Account findAccountById(int id) { //定义SQL String sql="select *from account where id=?"; //创建一个新的BeanPropertyRowMapper对象 RowMapper<Account> rowMapper= new BeanPropertyRowMapper<Account>(Account.class); //执行静态的SQL查询,并通过RowMapper返回结果 return this.jdbcTemplate.queryForObject(sql,rowMapper,id); } //查询所有账户的信息 public List<Account> findAllAccount() { //定义SQL String sql="select *from account"; //创建一个新的BeanPropertyRowMapper对象 RowMapper<Account> rowMapper= new BeanPropertyRowMapper<Account>(Account.class); //执行静态的SQL查询,并通过RowMapper返回结果 return this.jdbcTemplate.query(sql,rowMapper); }
在上面两个方法代码中,BeanPropertyRowMapper是RowMapper接口的实现类,它可以自动地将数据表中的数据映射到用户自定义的类中(前提是用户自定义类中的字段要与数据表中的字段相对应)。创建完BeanPropertyRowMapper对象后,在findAccountById()方法中通过queryForObject()方法返回了一个Object类型的单行记录,而在findAllAccount()方法中通过query()方法返回了一个结果集合。
测试完条件查询单个数据的方法后,接下来测试查询所有用户账户信息的方法。在测试类JdbcTemplateTest中,添加一个测试方法findAllAccountTest(),其代码如下所示。
在测试类JdbcTemplateTest中,添加一个测试方法findAccountByIdTest()来测试条件查询,其代码如下所示。
package com.spring.test; import java.util.List; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import com.spring.jdbc.AccountDao; import com.spring.jdbc.Account; public class JdbcTemplateQueryTest { //加载配置文件 ApplicationContext applicationContext= new ClassPathXmlApplicationContext("applicationContext.xml"); //获取AccountDao实例 AccountDao accountDao= (AccountDao) applicationContext.getBean("accountDao"); //查询一条数据测试 public void findAccountById() { Account account=accountDao.findAccountById(1); System.out.println(account.toString()); } //查询所有的数据 public void findAllAcount() { List<Account>account =accountDao.findAllAccount(); for(Account act:account) { System.out.println(act.toString()); } } public static void main(String[] args) { JdbcTemplateQueryTest jdbcTemplateQueryTest= new JdbcTemplateQueryTest(); //jdbcTemplateQueryTest.findAccountById(); jdbcTemplateQueryTest.findAllAcount(); } }