Spring学习之旅(十一)--JDBC
JDBC 是数据持久化的一种比较常见的方案,Spring 也对它进行了支持。
在开始 JDBC 的使用之前,我们要先做下一些准备工作。
配置数据源
在 Spring 上下文中可以数据源 Bean 有如下多种方式:
- 通过 JDBC 驱动程序定义的数据源;
- 通过 JNDI 查找的数据源;
- 连接池的数据源
我们通常使用 连接池 的方式来配置,这里也只讲解这种方案,其他两种可以自行摸索。
Spirng 并没有直接提供数据源连接池实现,但是有多种开源的实现,如:
我们这里采用阿里的 druid 连接池。
引入依赖
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>4.3.20.RELEASE</version>
</dependency>
<!-- druid连接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.16</version>
</dependency>
<!-- mysql连接驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
配置连接池对象
@Configuration
public class DataBaseConfig {
@Bean
public DataSource dataSource() {
DruidDataSource dataSource = new DruidDataSource();
// 设置驱动
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
// 设置连接 URL
dataSource.setUrl("jdbc:mysql://127.0.0.1:3306/learn?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&allowMultiQueries=true");
// 设置连接账号
dataSource.setUsername("root");
// 设置连接密码
dataSource.setPassword("sa000");
// 设置连接池初始连接数量
dataSource.setInitialSize(5);
// 设置连接池最大连接数量
dataSource.setMaxActive(10);
return dataSource;
}
}
初始化数据库
-- 创建数据库
DROP DATABASE IF EXISTS learn;
CREATE DATABASE IF NOT EXISTS learn DEFAULT CHARSET utf8 COLLATE utf8_general_ci;
-- 选择数据库
USE sugar;
SET FOREIGN_KEY_CHECKS=0;
-- 创建用户表
DROP TABLE IF EXISTS `sys_user`;
CREATE TABLE `sys_user` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键id',
`avatar` varchar(255) DEFAULT NULL COMMENT '头像',
`account` varchar(45) DEFAULT NULL COMMENT '账号',
`password` varchar(45) DEFAULT NULL COMMENT '密码',
`salt` varchar(45) DEFAULT NULL COMMENT 'md5密码盐',
`name` varchar(45) DEFAULT NULL COMMENT '名字',
`birthday` datetime DEFAULT NULL COMMENT '生日',
`sex` int(11) DEFAULT NULL COMMENT '性别(1:男 2:女)',
`email` varchar(45) DEFAULT NULL COMMENT '电子邮件',
`phone` varchar(45) DEFAULT NULL COMMENT '电话',
`role_id` varchar(255) DEFAULT NULL COMMENT '角色id',
`dept_id` int(11) DEFAULT NULL COMMENT '部门id',
`status` int(11) DEFAULT NULL COMMENT '状态(1:启用 2:冻结 3:删除)',
`createtime` datetime DEFAULT NULL COMMENT '创建时间',
`version` int(11) DEFAULT NULL COMMENT '保留字段',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=47 DEFAULT CHARSET=utf8 COMMENT='管理员表';
-- 插入
INSERT INTO `sys_user` VALUES ('1', 'girl.gif', 'admin', '871e11b8f4ce630ef302a79265fd4887', '8pgby', 'admin', '2018-05-05 00:00:00', '2', 'sn93@qq.com', '18200000000', '1', '27', '1', '2018-01-29 08:49:53', '25');
SET FOREIGN_KEY_CHECKS = 1;
实体对象
public class User {
private Long id;
private String avatar;
private String account;
private String password;
private String salt;
private String name;
private String birthday;
private Integer sex;
private String email;
private String phone;
private String roleId;
private Long deptId;
private Integer status;
private Date createtime;
private Long version;
// get/set......
}
原始 JDBC
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = RootConfig.class)
public class DaoTest {
@Autowired
private DataSource dataSource;
@Test
public void testJDBC() {
String sql = "select id,account from sys_user where id = ? ";
Connection connection = null;
PreparedStatement statement = null;
ResultSet resultSet = null;
try {
connection = dataSource.getConnection();
statement = connection.prepareCall(sql);
statement.setLong(1, 1);
resultSet = statement.executeQuery();
if (resultSet.next()) {
Long id = resultSet.getLong("id");
String account = resultSet.getString("account");
Assert.assertEquals(new Long(1), id);
Assert.assertEquals("admin", account);
}
} catch (SQLException e) {
System.out.println("异常:"+ e.getMessage());
} finally {
if(resultSet!=null){
try {
resultSet.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(statement !=null){
try {
statement.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(connection !=null){
try {
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
}
可以看到大部分的代码都是用来进行 资源管理 和 异常处理,实际的业务逻辑就只有几行。
JDBC 模板
Spring 为我们提供了 JDBC 模板 ,由它来进行资源管理和异常处理的工作,从而简化了 JDBC 代码。Spring 提供了三种模板类供我们选择:
- JdbcTemplate: 最基本的 Spring JDBC 模板,这个模板支持简单的 JDBC 数据库访问功能以及基于索引参数的查询。
- NamedParameterJdbcTemplate: 使用该模板类执行查询时可以将值以命名参数的形式绑定到 SQL 中,而不是使用简单的索引参数
- SimpleJdbcTemplate: 该模板类利用 Java5 的一些特性如自动装箱、泛型以及可变参数来简化 JDBC 模板的使用
从 Spirng 3.1 开始 SimpleJdbcTemplate 已经被废弃了,其 Java 5 的特性被转移到了 JdbcTemplate 中。所以大多数情况我们直接使用 JdbcTemplate 即可。
配置 JDBC 模板对象
@Configuration
public class DataBaseConfig {
......
@Bean
public JdbcTemplate jdbcTemplate(DataSource dataSource) {
return new JdbcTemplate(dataSource);
}
}
单元测试
@Autowired
private JdbcTemplate jdbcTemplate;
@Test
public void testJdbcTemplate() {
String sql = "select id,account,birthday from sys_user where id = ?";
User user = jdbcTemplate.queryForObject(sql, new UserRowMapper(),1);
Assert.assertEquals(new Long(1), user.getId());
Assert.assertEquals("admin", user.getAccount());
}
private static final class UserRowMapper implements RowMa pper<User>{
@Override
public User mapRow(ResultSet resultSet, int i) throws SQLException {
User user = new User();
user.setId(resultSet.getLong("id"));
user.setAccount(resultSet.getString("account"));
return user;
}
}
可以看到使用模板后代码量大幅度减少,只有业务代码存在了。
除了使用 RowMapper 外,也可以直接用 Lambda 表达式:
@Test
public void testJdbcTemplate2() {
String sql = "select id,account,birthday from sys_user where id = ?";
User user = jdbcTemplate.queryForObject(sql, (resultSet,i)->{
User u = new User();
u.setId(resultSet.getLong("id"));
u.setAccount(resultSet.getString("account"));
return u;
},1);
Assert.assertEquals(new Long(1), user.getId());
Assert.assertEquals("admin", user.getAccount());
}
Lambda 表达式比起申明一个 RowMapper 对象来更直观,但是需要 JDK 8 以上的支持。
Spring学习之旅(十一)--JDBC的更多相关文章
- Spring学习之旅(八)Spring 基于AspectJ注解配置的AOP编程工作原理初探
由小编的上篇博文可以一窥基于AspectJ注解配置的AOP编程实现. 本文一下未贴出的相关代码示例请关注小编的上篇博文<Spring学习之旅(七)基于XML配置与基于AspectJ注解配置的AO ...
- Spring学习之旅(十)--MockMvc
在之前的 Spring学习之旅(八)--SpringMVC请求参数 我们是通过在控制台输出来验证参数是否正确,但是这样做实在是太耗时间了,我们今天来学习下 MockMvc,它可以让我们不需要启动项目就 ...
- Spring学习之旅(六)--SpringMVC集成
对大多数 Java 开发来说,基于 web 的应用程序是我们主要的关注点. Spring 也提供了对于 web 的支持,基于 MVC 模式的 Spring MVC 能够帮助我们灵活和松耦合的完成 we ...
- Spring学习记录(十四)---JDBC基本操作
先看一些定义: 在Spring JDBC模块中,所有的类可以被分到四个单独的包:1.core即核心包,它包含了JDBC的核心功能.此包内有很多重要的类,包括:JdbcTemplate类.SimpleJ ...
- Spring学习之旅(十五)--SpringBoot
在使用 Spring 的过程中,有时候会出现一些 ClassNotFoundException 异常,这是因为 JAR 依赖之间的版本不匹配所导致的.而 Spring Boot 就能避免绝大多数依赖版 ...
- Spring学习之旅(十三)--使用NoSQL数据库
除了关系型数据库之外,现在还有一种 NoSQL 数据库非常流行,而 Spring 自然也没有放过对它的支持. NoSQL 数据库有很多种,如: MongoDBGenericJackson2JsonRe ...
- Spring学习之旅(十二)--持久化框架
对于本职工作来说 JDBC 就可以很好的完成,但是当我们对持久化的需求变得更复杂时,如: 延迟加载 预先抓取 级联 JDBC 就不能满足了,我们需要使用 ORM框架 来实现这些需求. Spring 对 ...
- Spring学习之旅(三)--装配Bean
装配 Bean 的方式 在 XML 中进行显式配置 在 Java 中进行显式配置 隐式的 Bean 发现机制和自动装配 Spring 提供了以上三种方式进行 Bean 的配置,可以根据自己的需求选择一 ...
- Spring学习之旅(一)--初始Spring
之前从博客.视频断断续续的学到了 Spring 的相关知识,但是都是一个个碎片化的知识.刚好最近在读 <Sprign实战(第四版)>,所以借此机会重新整理下Spring 系列的内容. Sp ...
随机推荐
- [leetcode]95 Unique Binary Search Trees II (Medium)
原题 字母题添加链接描述 一开始完全没有思路.. 百度看了别人的思路,对于这种递归构造的题目还是不熟,得多做做了. 这个题目难在构造出来.一般构造树都需要递归. 从1–n中任意选择一个数当做根节点,所 ...
- vuex的实现
源代码可以查看我的github: https://github.com/Jasonwang911/TryHardEveryDay/tree/master/Vuex/vuex-resouce 欢迎s ...
- Appium自动化测试环境搭建
前言 Appium是一个开源的自动化测试框架,支持跨平台,支持多种编程语言,可用于原生,混合和移动web应用程序,使用webdriver驱动ios,android应用程序.那么为了学习app自动化测试 ...
- ld: warning: directory not found for option ''
iOS开发中经常遇到这样的警告,如图所示: 原因是存在未用到的目录. 解决方法:选择Build Settings,找到Search Paths中的Library Search Paths,如下图 删除 ...
- Java秒杀系统实战系列~商品秒杀代码实战
摘要: 本篇博文是“Java秒杀系统实战系列文章”的第六篇,本篇博文我们将进入整个秒杀系统核心功能模块的代码开发,即“商品秒杀”功能模块的代码实战. 内容: “商品秒杀”功能模块是建立在“商品详情”功 ...
- HashMap、Hash Table、ConcurrentHashMap
这个这个...本王最近由于开始找实习工作了,所以就在牛客网上刷一些公司的面试题,大多都是一些java,前端HTML,js,jquery,以及一些好久没有碰的算法题,说实话,有点难受,其实在我不知道的很 ...
- 【故障公告】发布 .NET Core 版博客站点引起大量 500 错误
非常抱歉,今天上午的博客站点故障给大家带来了很大的麻烦,请大家谅解.这次故障是我们发布 .NET Core 版博客站点引起的,虽然我们进行了充分的准备,但还是低估了高并发下的复杂问题. 以下是故障背景 ...
- POI导入excel
前言 在做后台管理的时候经常会用到excel导入的问题,就是将excel中的内容批量导入到数据库中,正好在新项目中我也做了excel导入的功能,来分享给大家,也给自己做个记录. 核心思想 excel导 ...
- 湫湫系列故事——设计风景线 HDU - 4514
题目链接:https://vjudge.net/problem/HDU-4514 题意:判断没有没有环,如果没有环,通俗的讲就是找出一条最长的路,相当于一笔画能画多长. 思路:dfs判环. 最后就是没 ...
- RGW 学习 前言
对于CEPH的学习已经有一段的时间了,最近的一段时间都是集中在RGW网关这一方面,所以准备将学习的过程以及源代码的分析,将以随笔的形式记录下来. 每天更新一章.