Spring中如何操作JDBC的实现

 更新时间:2019年10月18日 11:26:51   作者:~wangweijun  
这篇文章主要介绍了Spring中如何操作JDBC的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

本篇文章介绍一下在Spring中如何使用JDBC,事实上,在Spring中使用JDBC和传统的JDBC或者一些JDBC框架,如:DBUtils的使用没有什么区别,所以Spring中使用JDBC是非常简单的。

获取数据库连接

在这之前,我们首先通过Spring获得对数据库的连接,创建一个Java项目,导入Spring、c3p0、数据库驱动的jar包即可,然后创建一个数据表做测试:

 create table user(
 id integer primary key auto_increment,
 name varchar(20),
 password varchar(20)
 );
 

接下来创建Spring的配置文件并作如下配置:

<?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.0.xsd">

 <!-- 导入资源文件 -->
 <context:property-placeholder
 location="classpath:db.properties" />

 <!-- 配置C3P0数据源 -->
 <bean id="dataSource"
 class="com.mchange.v2.c3p0.ComboPooledDataSource">
 <property name="user" value="${jdbc.user}"></property>
 <property name="password" value="${jdbc.password}"></property>
 <property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property>
 <property name="driverClass" value="${jdbc.driverClass}"></property>
 </bean>

</beans>

测试数据库连接是否能够成功获取:

public class SpringJDBCTest {

 private ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");

 @Test
 public void testConnection() throws SQLException {
 DataSource dataSource = ctx.getBean(DataSource.class);
 System.out.println(dataSource.getConnection());
 }
}

运行结果:

com.mchange.v2.c3p0.impl.NewProxyConnection@5d47c63f

能够成功获取到数据库连接。

对数据表进行更新操作

传统的JDBC用法相信大家都很熟悉,在Spring中并没有什么特别的,无非是将Bean的生命周期交给了IOC容器管理,而Spring框架独立出了一套API用于数据库操作(JDBCTemplate)。接下来分别测试一下常见的数据库操作,先将JDBCTemplate类放入容器:

 <!-- 将JDBCTemplate放入容器 -->
 <bean id="jdbcTemplate"
 class="org.springframework.jdbc.core.JdbcTemplate">
 <property name="dataSource" ref="dataSource"></property>
 </bean>

该类需要一个参数,参数值指向刚才配置的dataSource即可,这样我们就能够使用JDBCTemplate类了,先测试一下插入操作:

 @Test
 public void testInsert() {
 JdbcTemplate jdbcTemplate = (JdbcTemplate) ctx.getBean("jdbcTemplate");
 String sql = "insert into user(name,password) values(?,?)";
 Object[] args = {"zhangsan","12345"};
 jdbcTemplate.update(sql,args);
 }
 

执行代码,查询表结果,插入成功。

mysql> select * from user;
+----+----------+----------+
| id | name  | password |
+----+----------+----------+
| 1 | zhangsan | 12345 |
+----+----------+----------+
1 row in set (0.00 sec)

接着测试一下数据表的修改操作:

 @Test
 public void testUpdate() {
 JdbcTemplate jdbcTemplate = (JdbcTemplate) ctx.getBean("jdbcTemplate");
 String sql = "update user set password = ? where id = ?";
 Object[] args = {"admin","1"};
 jdbcTemplate.update(sql,args);
 }

执行代码,查询表结果,修改成功。

mysql> select * from user;
+----+----------+----------+
| id | name  | password |
+----+----------+----------+
| 1 | zhangsan | admin |
+----+----------+----------+
1 row in set (0.00 sec)

数据表的删除操作与其类似,不做重复测试,接下来我们测试一下批量操作:

 @Test
 public void testBatchInsert() {
 JdbcTemplate jdbcTemplate = (JdbcTemplate) ctx.getBean("jdbcTemplate");
 String sql = "insert into user(name,password) values(?,?)";
 List<Object[]> batchArgs = new ArrayList();
 batchArgs.add(new Object[]{"lisi","123"});
 batchArgs.add(new Object[]{"wangwu","1234"});
 batchArgs.add(new Object[]{"zhaoliu","12345"});
 jdbcTemplate.batchUpdate(sql, batchArgs);
 }
 

此时的一个对象数组即为一条记录,批量操作则需要泛型为Object数组的集合。

执行代码,查询表结果,批量插入成功。

mysql> select * from user;
+----+----------+----------+
| id | name  | password |
+----+----------+----------+
| 1 | zhangsan | admin |
| 2 | lisi  | 123  |
| 3 | wangwu | 1234  |
| 4 | zhaoliu | 12345 |
+----+----------+----------+
4 rows in set (0.00 sec)

最后是数据表的查询操作,首先创建数据表对应的User类:

package com.wwj.spring.jdbc;

public class User {

 private Integer id;
 private String name;
 private String password;

 public Integer getId() {
 return id;
 }

 public void setId(Integer id) {
 this.id = id;
 }

 public String getName() {
 return name;
 }

 public void setName(String name) {
 this.name = name;
 }

 public String getPassword() {
 return password;
 }

 public void setPassword(String password) {
 this.password = password;
 }

 @Override
 public String toString() {
 return "User [id=" + id + ", name=" + name + ", password=" + password + "]";
 }
}

编写测试代码:

 @Test
 public void testGet() {
 JdbcTemplate jdbcTemplate = (JdbcTemplate) ctx.getBean("jdbcTemplate");
 String sql = "select id,name,password from user where id = ?";
 RowMapper<User> rowMapper = new BeanPropertyRowMapper<User>(User.class);
 User user = jdbcTemplate.queryForObject(sql, rowMapper,1);
 System.out.println(user);
 }

运行结果如下:

User [id=1, name=zhangsan, password=admin]

在Spring中,查询的结果是交给了RowMapper来处理的,RowMapper用来指定映射结果集行数据的方式,相对于传统的ResultSet来说,RowMapper省去了遍历结果集的重复操作,从而使查询变得更简单。

而查询多条数据的方式如下:

 @Test
 public void testGetMore() {
 JdbcTemplate jdbcTemplate = (JdbcTemplate) ctx.getBean("jdbcTemplate");
 String sql = "select id,name,password from user where id > ?";
 RowMapper<User> rowMapper = new BeanPropertyRowMapper<>(User.class);
 List<User> userList = jdbcTemplate.query(sql, rowMapper,2);
 System.out.println(userList);
 }

运行结果:

[User [id=3, name=wangwu, password=1234], User [id=4, name=zhaoliu, password=12345]]

有些同学可能会想当然地认为,查询多条数据要调用queryForList()方法,事实上,调用的是query()方法。需要注意的是,JDBCTemplate提供的API不支持级联属性。

获取数据表单列的值:

@Test
 public void testSingleValue() {
 JdbcTemplate jdbcTemplate = (JdbcTemplate) ctx.getBean("jdbcTemplate");
 String sql = "select name from user where id = ?";
 String name = jdbcTemplate.queryForObject(sql, String.class,1);
 System.out.println(name);
 }
 

运行结果如下:

zhangsan

整个增删改查的过程其实都没有任何难度,这和之前学的数据库操作API区别并不大,所以也没有特别需要讲解的地方,通过一些测试代码应该就能够理解了。

使用具名参数

在经典的JDBC用法中,sql参数是用占位符"?"表示,并且受到位置的限制,定位参数的问题在于,一旦改变参数的顺序,就必须改变参数的绑定方式。

为了解决这个问题,Spring为我们提供了另一种选择:使用具名参数。

使用具名参数后,sql将按名称而不是位置进行指定,具名参数更易于后期维护,也提升了代码的可读性,具名参数只在NamedParameterJdbcTemplate类中得到支持。

要想使用具名参数,首先将NamedParameterJdbcTemplate放入容器:

 <!-- 将namedParameterJdbcTemplate放入容器 -->
 <bean id="namedParameterJdbcTemplate"
 class="org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate">
 <constructor-arg ref="dataSource"></constructor-arg>
 </bean>

该类没有无参的构造器,通常使用参数为DataSource类型的构造器。

这里以插入数据举例具名参数的使用:

 @Test
 public void testNamedParameterJdbcTemplate() {
 NamedParameterJdbcTemplate namedParameterJdbcTemplate = (NamedParameterJdbcTemplate) ctx.getBean("namedParameterJdbcTemplate");
 String sql = "insert into user(name,password) values(:name,:psd)";
 Map<String, Object> map = new HashMap<String, Object>();
 map.put("name", "wangweijun");
 map.put("psd", "112233");
 namedParameterJdbcTemplate.update(sql,map);
 }

执行代码,查询表结果,插入成功。

mysql> select * from user;
+----+------------+----------+
| id | name  | password |
+----+------------+----------+
| 1 | zhangsan | admin |
| 2 | lisi  | 123  |
| 3 | wangwu  | 1234  |
| 4 | zhaoliu | 12345 |
| 5 | wangweijun | 112233 |
+----+------------+----------+
5 rows in set (0.00 sec)

虽然具名参数有很多好处,但无形中也增加了很多代码,可以说比之前的方式更加复杂。

当然,它还有更简单的实现方式:

 @Test
 public void testSimpleNamedParameterJdbcTemplate() {
 NamedParameterJdbcTemplate namedParameterJdbcTemplate = (NamedParameterJdbcTemplate) ctx.getBean("namedParameterJdbcTemplate");
 String sql = "insert into user(name,password) values(:name,:password)";
 User user = new User();
 user.setName("zhaoliu");
 user.setPassword("223344");
 SqlParameterSource paramSource = new BeanPropertySqlParameterSource(user);
 namedParameterJdbcTemplate.update(sql, paramSource);
 }

执行代码,查询表结果,插入成功。

mysql> select * from user;
+----+------------+----------+
| id | name  | password |
+----+------------+----------+
| 1 | zhangsan | admin |
| 2 | lisi  | 123  |
| 3 | wangwu  | 1234  |
| 4 | zhaoliu | 12345 |
| 5 | wangweijun | 112233 |
| 6 | zhaoliu | 223344 |
+----+------------+----------+
6 rows in set (0.00 sec)

这种方式实现了通过对象自动匹配具名参数,前提是具名参数的参数名要和类中的属性名相同,该方式相对于第一种方式要更合理一些,因为从前台传递过来的就是对象,这样就可以直接通过对象进行处理而无需其它操作。

项目源码
https://github.com/blizzawang/spring_jdbc

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • java实现斗地主游戏

    java实现斗地主游戏

    这篇文章主要为大家详细介绍了java实现斗地主游戏,洗牌、发牌、看牌,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-01-01
  • mybatis如何使用Map接收返回值

    mybatis如何使用Map接收返回值

    这篇文章主要介绍了mybatis如何使用Map接收返回值问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-12-12
  • Java异常处理运行时异常(RuntimeException)详解及实例

    Java异常处理运行时异常(RuntimeException)详解及实例

    这篇文章主要介绍了 Java异常处理运行时异常(RuntimeException)详解及实例的相关资料,需要的朋友可以参考下http://time.qq.com/?pgv_ref=aiotime
    2017-05-05
  • 封装jndi操作ldap服务器的工具类

    封装jndi操作ldap服务器的工具类

    这篇文章主要介绍了封装JNDI操作LDAP服务器的工具类,使用者只需要会使用List,Map 数据结构,大家参考使用吧
    2014-01-01
  • 基于java集合中的一些易混淆的知识点(详解)

    基于java集合中的一些易混淆的知识点(详解)

    下面小编就为大家带来一篇基于java集合中的一些易混淆的知识点(详解)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-09-09
  • IntelliJ IDEA 统一设置编码为utf-8编码的实现

    IntelliJ IDEA 统一设置编码为utf-8编码的实现

    这篇文章主要介绍了IntelliJ IDEA 统一设置编码为utf-8编码的实现,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2020-06-06
  • Springboot错误页面和错误信息定制操作

    Springboot错误页面和错误信息定制操作

    这篇文章主要介绍了Springboot错误页面和错误信息定制操作,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-10-10
  • Spring Boot中进行 文件上传和 文件下载功能实现

    Spring Boot中进行 文件上传和 文件下载功能实现

    开发Wb应用时,文件上传是很常见的一个需求,浏览器 通过 表单形式 将 文件 以 流的形式传递 给 服务器,服务器再对上传的数据解析处理,下面将通过一个案例讲解使用 SpringBoot 实现 文件上传,感兴趣的朋友一起看看吧
    2024-07-07
  • Java foreach循环是否可以修改数据的值问题解决方法

    Java foreach循环是否可以修改数据的值问题解决方法

    最近在做项目的时候,需要修改一个数组里面各个元素的值,foreach循环迭代数组元素时,不能改变数组元素的值,这篇文章给大家介绍Java foreach循环是否可以修改数据的值的问题及解决方法,感兴趣的朋友一起看看吧
    2024-02-02
  • idea 无法debug调试的解决方案

    idea 无法debug调试的解决方案

    这篇文章主要介绍了idea 无法debug调试的解决方案,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-09-09

最新评论