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也挺长 ...
随机推荐
- git学习整理(1)git clone 理解
1.git clone 的理解 git clone默认会把远程仓库整个给clone下来 ,只能clone远程库的master分支并在本地默认创建一个master分支 ,无法clone所有分支,若想要其 ...
- Ubuntu 16.04 LTS 下安装MATLAB2015b 以及Matlab system error解决办法
下载MATLAB2015b破解版 操作系统:Ubuntu 16.o4 LTS 程序文件:Matlab2015b-glnxa64破解版 解压提取文件:在ubuntu系统下可以直接提取压缩文件,得到三个文 ...
- 如何搭建ftp的yum源
ftp的yum的搭建步骤 第一步:安装vsftpd程序包(系统已经安装) [root@station40 ~]# rpm -qa |grep vsftpd vsftpd-2.2 ...
- 【Java学习笔记之三十四】超详解Java多线程基础
前言 多线程并发编程是Java编程中重要的一块内容,也是面试重点覆盖区域,所以学好多线程并发编程对我们来说极其重要,下面跟我一起开启本次的学习之旅吧. 正文 线程与进程 1 线程:进程中负责程序执行的 ...
- 树莓派.安装Samba环境
适用于树莓派3 树莓派装好系统后, 为了方便传文件到树莓派, 建议使用Samba这类文件夹级别的应用, 比ftp方便多了 如果你想把树莓派变成Nas, Samba也是不可或缺的应用 通过samba服务 ...
- json解析eval()中文乱码问题的解决
只需要后台post请求中添加: resp.setContentType("text/html;charset=utf-8"); req.setCharacterEncoding(& ...
- MySQL常用存储引擎
MySQL存储引擎主要有两大类: 1. 事务安全表:InnoDB.BDB. 2. 非事务安全表:MyISAM.MEMORY.MERGE.EXAMPLE.NDB Cluster.ARCHIVE.CSV. ...
- px em rem的详解与区别
在前端项目开发中,px,em,以及rem都是页面布局常用的单位,虽然它们是长度单位,但是所含的意义不一样.通过复习和查阅,总结了以下知识. px像素(Pixel) 定义:相对长度单位.像素px是相对于 ...
- ../../../../.. 太low了
痛点 如果我们有这个目录: ├── webpack.config.js ├── src │ ├── view │ │ ├── index.js │ │── router │ │ ├── index.j ...
- angular指令之complie和link不得不说的故事
angular指令比较晦涩难懂的就是complie和link字段了,什么时候该用complie?什么时候该用link?总是很难分别清楚.当理解了指令的真正编译原理的时候,就会发现这相当的简单. ng怎 ...