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也挺长 ...
随机推荐
- Unity 使用 陀螺仪 实现 《王者荣耀》 登入界面 背景动态效果
在 <王者荣耀> 登入界面 左右上下晃动手机(有些手机不支持)可以看到背景在变化 我使用的是iPhone SE 效果如下: 对比两张图片的左下角 可以看到差异 至于为什么要这么做: 1.使 ...
- NopCommerce 1. NopCommerce Application_Start启动过程
这里简单介绍整个启动过程,其他具体的后续讲解 从Application_Start中执行开始,一开始执行EngineContext.Initialize(false); EngineContext 是 ...
- CSS之 border 属性
特性 border-width 不支持百分比 border-color 默认颜色是 color border-color 透明值的作用:可利用增加可点击区域,利用内阴影做边框 border 应用 ...
- wpf C# 数据库 c/s 个人信息管理 wpf局域网通信
系统功能基本要求 wpf局域网通信 WPF跨线程访问线程安全的数据如解决该类型的CollectionView不支持从调度程序线程以外的线程对其SourceCollection 读取信息null 读取发 ...
- asp.net C# 实现阿里大鱼和云片网短信接口类
云片网短信通用类 public class YunpianSMS { public YunpianSMS() { } /// <summary> /// 服务器HTTP地址 /// < ...
- 正六边形网格化(Hexagonal Grids)原理与实现
在路径规划.游戏设计栅格法应用中,正六边形网格不如矩形网格直接和常见,但是正六边形具有自身的应用特点,更适用于一些特殊场景中,比如旷阔的海洋.区域或者太空.本文主要讲述如何对正六边形进行几何学分析.网 ...
- Struts2运行流程-源码剖析
本文为原创,如需转载,请标明出处:http://www.cnblogs.com/gudu1/p/7726172.html 首先说一下查看这些框架源码的感受,每一次深入探究 Spring.Struts ...
- vue.js快速搭建图书管理平台
前 言 上一期简单讲解了vue的基本语法,这一次我们做一个小项目,搭建一个简单的图书管理平台,能够让我们更深刻的理解这门语言的妙用. 1.DEMO样式 首先我们需要搭建一个简单的demo样式 ...
- Linux中main是如何执行的
Linux中main是如何执行的 这是一个看似简单的问题,但是要从Linux底层一点点研究问题比较多.找到了一遍研究这个问题的文章,但可能比较老了,还是在x86机器上进行的测试. 原文链接 开始 问题 ...
- x86-64栈帧中的“红色区域” red zone of stack frame on x86-64
前几天看System V AMD64 ABI标准的时候发现栈帧的顶部后面有一块"red zone",在学cs:app3e/深入理解操作系统的时候并没有遇到这个,总结一下. 引用标准 ...