Spring4 JDBC详解
Spring4 JDBC详解
在之前的Spring4 IOC详解 的文章中,并没有介绍使用外部属性的知识点。现在利用配置c3p0连接池的契机来一起学习。本章内容主要有两个部分:配置c3p0(重点)和 使用 Spring JDBC模版。
准备环境
导入spring-jdbc的jar包
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>4.1.6.RELEASE</version>
</dependency>
创建数据表
SET FOREIGN_KEY_CHECKS=0;
-- ----------------------------
-- Table structure for `itdragon`
-- ----------------------------
DROP TABLE IF EXISTS `itdragon`;
CREATE TABLE `itdragon` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`account` varchar(255) NOT NULL,
`password` varchar(255) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
配置c3p0
c3p0的外部属性文件(可以在无需重启系统的情况下修改系统环境变量):db.properties。
db.properties文件中,user 和 password 分别表示 mysql连接 的账号和密码。driverClass 是加载的驱动。
jdbcUrl 是连接数据库的路径。格式是 jdbc:mysql://ip:port/数据库名(jdbc:mysql://localhost:3306/spring)
如果ip地址是本地,port是3306 是可以简写为 jdbc:mysql:///+数据库名。
initPoolSize 是 池内初始的数据连接个数,maxPoolSize是最大连接个数。和线程池是一样的概念。
如果你对这个不是很了解,可以先看看jdbc操作mysql数据库
jdbc.user=root
jdbc.password=root
jdbc.driverClass=com.mysql.jdbc.Driver
jdbc.jdbcUrl=jdbc:mysql:///spring
jdbc.initPoolSize=5
jdbc.maxPoolSize=10
核心文件applicationContext.xml ,首先要指定导入的资源context:property-placeholder , location从类路径下加载外部属性文件db.properties。
配置一个c3p0的bean,和普通bean一样。只是赋值采用el表达式${}。再配置两个jdbc的模版bean就可以了。
<?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"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.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>
<property name="initialPoolSize" value="${jdbc.initPoolSize}"></property>
<property name="maxPoolSize" value="${jdbc.maxPoolSize}"></property>
</bean>
<!-- 配置 Spirng 的 JdbcTemplate -->
<bean id="jdbcTemplate"
class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 配置 NamedParameterJdbcTemplate, 该对象可以使用具名参数 -->
<bean id="namedParameterJdbcTemplate"
class="org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate">
<constructor-arg ref="dataSource"></constructor-arg>
</bean>
</beans>
值得注意的是,在配置JdbcTemplate是用属性注入的方式,当然也可以用构造注入。但在配置NamedParameterJdbcTemplate只能通过构造注入的方式。源码如下:
/* */ public JdbcTemplate(DataSource dataSource)
/* */ {
/* 166 */ setDataSource(dataSource);
/* 167 */ afterPropertiesSet();
/* */ }
/* */ public NamedParameterJdbcTemplate(DataSource dataSource)
/* */ {
/* 89 */ Assert.notNull(dataSource, "DataSource must not be null");
/* 90 */ this.classicJdbcTemplate = new JdbcTemplate(dataSource);
/* */ }
Spring JDBC模版
先温故一下Mysql的基本语法
新增:INSERT [INTO] 表名 [(列名1, 列名2, 列名3, ...)] VALUES (值1, 值2, 值3, ...);
修改:UPDATE 表名 SET 列名=新值 WHERE 更新条件;
删除:DELETE FROM 表名 WHERE 删除条件;
查询:SELECT 列名称 FROM 表名称 [查询条件];
操作Mysql的测试方法,JdbcTemplate只是一个 JDBC的小工具。很多功能还不能实现,比如级联操作。真正的数据处理,还是交给Hibernate等ORM框架。
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import javax.sql.DataSource;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.namedparam.BeanPropertySqlParameterSource;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.jdbc.core.namedparam.SqlParameterSource;
public class MyJDBCMain {
private ApplicationContext ctx = null;
private JdbcTemplate jdbcTemplate = null; // JdbcTemplate 只是一个 JDBC的小工具,不支持级联属性
private NamedParameterJdbcTemplate namedParameterJdbcTemplate = null; // 支持具名参数,提高代码的可读性。
// 构造块,在创建对象的时候调用
{
ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
jdbcTemplate = (JdbcTemplate) ctx.getBean("jdbcTemplate");
namedParameterJdbcTemplate = (NamedParameterJdbcTemplate) ctx.getBean("namedParameterJdbcTemplate");
}
// 测试是否连上数据库连接池
@Test
public void connectionDataSource() {
System.out.println("----------- connectionDataSource ----------");
DataSource dataSource = (DataSource) ctx.getBean("dataSource");
try {
// 若能打印com.mchange.v2.c3p0.impl.NewProxyConnection 说明连接成功。
System.out.println(dataSource.getConnection());
} catch (SQLException e) {
e.printStackTrace();
}
System.out.println("^^^^^^^^^^^ connectionDataSource ^^^^^^^^^^^");
}
/**
* 直接对Mysql数据进行增,删,改,查,统计的操作
*/
@Test
public void crudMysqlOperation() {
System.out.println("----------- crudMysqlOperation ----------");
// 插入
String insertSql = "INSERT INTO ITDragon (account, password) VALUES (?,?)";
System.out.println("insert result : " + jdbcTemplate.update(insertSql, "itdragon", "pwdItdragon"));
// 修改
String updateSql = "UPDATE ITDragon SET password = ? WHERE account = ?";
System.out.println("update result : " + jdbcTemplate.update(updateSql, "passwordItdragon", "itdragon"));
// 查询
String querySql = "SELECT * FROM ITDragon";
List<Map<String, Object>> results = jdbcTemplate.queryForList(querySql);
System.out.println("query result : " + results);
// 删除
String deleteSql = "DELETE FROM ITDragon WHERE account = ?";
System.out.println("delete result : " + jdbcTemplate.update(deleteSql, "itdragon"));
// 统计
String countSql = "SELECT count(id) FROM ITDragon";
System.out.println("count result : " + jdbcTemplate.queryForObject(countSql, Long.class));
System.out.println("^^^^^^^^^^^ crudMysqlOperation ^^^^^^^^^^^");
}
/**
* 直接对Mysql数据进行批量的增,删,改的操作
*/
@Test
public void batchCrudMysqlOperation() {
System.out.println("----------- batchCrudMysqlOperation ----------");
// 批量插入
String insertSql = "INSERT INTO ITDragon (account, password) VALUES (?,?)";
List<Object[]> insertArgs = new ArrayList<>();
insertArgs.add(new Object[]{"itdragon", "pwdItdragon"});
insertArgs.add(new Object[]{"blog", "pwdBlog"});
System.out.println("batch insert result : " + jdbcTemplate.batchUpdate(insertSql, insertArgs));
// 查询
String querySql = "SELECT * FROM ITDragon";
List<Map<String, Object>> results = jdbcTemplate.queryForList(querySql);
System.out.println("query result : " + results);
// 批量修改
String updateSql = "UPDATE ITDragon SET password = ? WHERE account = ?";
List<Object[]> updateArgs = new ArrayList<>();
updateArgs.add(new Object[]{"passwordItdragon", "itdragon"});
updateArgs.add(new Object[]{"passwordBlog", "blog"});
System.out.println("batch udpate result : " + jdbcTemplate.batchUpdate(updateSql, updateArgs));
// 批量删除
String deleteSql = "DELETE FROM ITDragon WHERE account = ?";
List<Object[]> deleteArgs = new ArrayList<>();
deleteArgs.add(new Object[]{"itdragon"});
deleteArgs.add(new Object[]{"blog"});
System.out.println("batch delete result : " + jdbcTemplate.batchUpdate(deleteSql, deleteArgs));
// 统计
String countSql = "SELECT count(id) FROM ITDragon";
System.out.println("count result : " + jdbcTemplate.queryForObject(countSql, Long.class));
System.out.println("^^^^^^^^^^^ batchCrudMysqlOperation ^^^^^^^^^^^");
}
/**
* 对象的增删改查,改用 NamedParameterJdbcTemplate
* 要求:参数名要和类的属性名一样
* 好处:之前的参数用?表示,不直观,代码的可读性较差,出错率较高。
* 缺点:多敲几个字母
*/
@Test
public void crudObjectOperation() {
System.out.println("----------- crudObjectOperation ----------");
// 插入
String insertSql = "INSERT INTO ITDragon (account, password) VALUES (:account,:password)";
ITDragon itDragon = new ITDragon();
itDragon.setAccount("itdragon");
itDragon.setPassword("pwdItdragon");
SqlParameterSource paramSource = new BeanPropertySqlParameterSource(itDragon);
System.out.println("insert object result : " + namedParameterJdbcTemplate.update(insertSql, paramSource));
// 查询
String querySql = "SELECT * FROM ITDragon";
// 使用 RowMapper 指定映射结果集的行
RowMapper<ITDragon> rowMapper = new BeanPropertyRowMapper<>(ITDragon.class);
List<ITDragon> results = namedParameterJdbcTemplate.query(querySql, rowMapper);
System.out.println("query object result : " + results);
// 更新和删除 也是update方法,这里不做过多的描述
System.out.println("^^^^^^^^^^^ crudObjectOperation ^^^^^^^^^^^");
}
}
public class ITDragon {
private Integer id;
private String account;
private String password;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getAccount() {
return account;
}
public void setAccount(String account) {
this.account = account;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public String toString() {
return "ITDragon [id=" + id + ", account=" + account + ", password="
+ password + "]";
}
}
----------- connectionDataSource ----------
com.mchange.v2.c3p0.impl.NewProxyConnection@16ba2b8
^^^^^^^^^^^ connectionDataSource ^^^^^^^^^^^
----------- crudMysqlOperation ----------
insert result : 1
update result : 1
query result : [{id=4, account=itdragon, password=passwordItdragon}]
delete result : 1
count result : 0
^^^^^^^^^^^ crudMysqlOperation ^^^^^^^^^^^
----------- batchCrudMysqlOperation ----------
batch insert result : [I@3c9dd8
query result : [{id=10, account=itdragon, password=pwdItdragon}, {id=11, account=blog, password=pwdBlog}]
batch udpate result : [I@c094f6
batch delete result : [I@1917d6d
count result : 0
^^^^^^^^^^^ batchCrudMysqlOperation ^^^^^^^^^^^
----------- crudObjectOperation ----------
insert object result : 1
query object result : [ITDragon [id=12, account=itdragon, password=pwdItdragon]]
^^^^^^^^^^^ crudObjectOperation ^^^^^^^^^^^
从打印的结果可以看出,如果插入,修改,删除一条数据,成功就返回1。如果是批量操作,则返回的是一个int[] 数组。
好了!到这里,Spring4 的JDBC就讲完了。有关jdbc的事务,就放到下一章介绍。喜欢的话可以点个赞哦!
一点点成长,一点点优秀。如果有什么建议和疑问可以留言。
Spring4 JDBC详解的更多相关文章
- spring4配置文件详解
转自: spring4配置文件详解 一.配置数据源 基本的加载properties配置文件 <context:property-placeholder location="classp ...
- Spring4 AOP详解
Spring4 AOP详解 第一章Spring 快速入门并没有对Spring4 的 AOP 做太多的描述,是因为AOP切面编程概念不好理解.所以这章主要从三个方面详解AOP:AOP简介(了解),基于注 ...
- Spring4 IOC详解
Spring4 IOC详解 上一章对Spring做一个快速入门的教程,其中只是简单的提到了IOC的特性.本章便对Spring的IOC进行一个详解.主要从三个方面开始:基于xml文件的Bean配置,基于 ...
- JDBC详解系列(二)之加载驱动
---[来自我的CSDN博客](http://blog.csdn.net/weixin_37139197/article/details/78838091)--- 在JDBC详解系列(一)之流程中 ...
- JDBC详解系列(三)之建立连接(DriverManager.getConnection)
在JDBC详解系列(一)之流程中,我将数据库的连接分解成了六个步骤. JDBC流程: 第一步:加载Driver类,注册数据库驱动: 第二步:通过DriverManager,使用url,用户名和密码 ...
- JDBC详解(一)
一.相关概念介绍 1.1.数据库驱动 这里驱动的概念和平时听到的那种驱动的概念是一样的,比如平时购买的声卡,网卡直接插到计算机上面是不能用的,必须要安装相应的驱动程序之后才能够使用声卡和网卡,同样道理 ...
- Java基础-面向接口编程-JDBC详解
Java基础-面向接口编程-JDBC详解 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.JDBC概念和数据库驱动程序 JDBC(Java Data Base Connectiv ...
- JDBC详解1
JDBC详解1 JDBC整体思维导图 JDBC入门 导jar包:驱动! 加载驱动类:Class.forName("类名"); 给出url.username.password,其中u ...
- JDBC详解系列(一)之流程
---[来自我的CSDN博客](http://blog.csdn.net/weixin_37139197/article/details/78838091)--- JDBC概述 使用JDBC也挺长 ...
随机推荐
- NSOperation与GCD的如何选择?
iOS开发的多线程实现方式,大概包括C的原始方式.NSThread方式.GCD.NSOperation的方式. 其中用的最多的应该是GCD和NSOperation的方式,很多第三方库都是使用了这两种方 ...
- PE格式第六讲,导出表
PE格式第六讲,导出表 请注意,下方字数比较多,其实结构挺简单,但是你如果把博客内容弄明白了,对你受益匪浅,千万不要看到字数多就懵了,其实字数多代表它重要.特别是第五步, 各种表中之间的关系. 作者: ...
- 关于string.h中字符串的操作
string.h中字符操作的函数 注意:**对字符数组的多次操作需要进行赋初值.或者善于用memset()函数进行清空数组的操作.** 否则容易出现错误. string.h文件中函数的用法加 ...
- win10 3dmax 激活后反复激活和激活码无效问题
我也是遇到这个问题在网上找答案,像什么断网,清理注册表,删除某个.dat文件 各种试了好多都没管用 弄这个弄了五六个小时才总算成功 心累 现在我总结一下这些方法 我是第一条成功的 其他的我试着都没用 ...
- banner幻灯片
emmm本来想用js写的,但是感觉难就换了jquery. 1.把图片的位置.透明度.宽高.z-index信息用数组datas保存起来,移动的时候直接把位置等信息赋值给li. 2.点击next,即显示下 ...
- word2vec 数学原理
word2vec 是 Google 于 2013 年推出的一个用于获取词向量的开源工具包.我们在项目中多次使用到它,但囿于时间关系,一直没仔细探究其背后的原理. 网络上 <word2vec 中的 ...
- 3des用法示例,已测试
using System;using System.Data;using System.Configuration;using System.Web;using System.Web.Security ...
- .Net Web开发技术栈
有很多朋友有的因为兴趣,有的因为生计而走向了.Net中,有很多朋友想学,但是又不知道怎么学,学什么,怎么系统的学,为此我以我微薄之力总结归纳写了一篇.Net web开发技术栈,以此帮助那些想学,却不知 ...
- RabbitMQ 笔记-基本概念
ConnectionFactory.Connection.Channel ConnectionFactory.Connection.Channel,这三个都是RabbitMQ对外提供的API中最基本的 ...
- [ACdream]小晴天老师系列——竖式乘
题目链接:http://acdream.info/contest?cid=1269#problem-C Problem Description 小晴天是ACdream团队中最牛的老师之一,他最擅长数学 ...