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 ...
随机推荐
- MySql 命令(命令行)
1.连接Mysql 格式: mysql -h主机地址 -u用户名 -p用户密码1.连接到本机上的MYSQL. 首先打开DOS窗口,然后进入目录mysql\bin,再键入命令mysql -u root ...
- 【数据库】postgresql数据库创建自增序列id的注意事项
1.创建一张表 CREATE TABLE "public"."tt" ( "name" varchar(128), "status ...
- 上车时机已到--.NETCore是适应时代发展的雄鹰利剑
上车时机已到--.NETCore是适应时代发展的雄鹰利剑 要起飞了 .NET Core 3.0-prevew7:https://dotnet.microsoft.com/download/dotnet ...
- 如何在 Centos7 中使用阿里云的yum源
如何在 Centos7 中使用阿里云的yum源 1. 备份原来的yum源 mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Ba ...
- linux初学者-NFS网络文件系统篇
linux初学者-NFS网络文件系统篇 在上一篇的SAMBA篇中介绍了linux系统和windows系统之间共用的网络文件系统CIFS,主要用于客户端是windows的情况.在linux系统之间,所用 ...
- 使用Redis为注册中心的Dubbo微服务架构(基于SpringBoot)
title: 使用Redis为注册中心的Dubbo微服务架构(基于SpringBoot) date: 2019-07-30 14:06:29 categories: 架构 author: mrzhou ...
- 记一次idea问题—performing vcs refresh...
01.前言 本人出现该场景是,我把本地SVN A项目删了,而A项目与B项目同在一个SVN目录下,当我修改B项目且提交代码时,出现了该问题. idea不是很懂操作,就搜索了一下得出了三种答案,但只有其一 ...
- centos7安装mongodb详解
记录一下linux下安装mongodb数据库过程. 安装mongodb #下载linux版本的tar文件# 例如笔者下载的是:mongodb-linux-x86_64-rhel70-3.4.4.tg ...
- 并发编程(4)——AbstractQueuedSynchronizer
AQS 内部类Node 等待队列是CLH有锁队列的变体. waitStatus的几种状态: static final int CANCELLED = 1; /** waitStatus value t ...
- MyBatis之#{} and ${}
#{} 和 ${} 之间最大的差别就是 #{}会在使用的时候被加上 ‘’ 引号, ${}直接传值,不做任何处理 1.#{}对传入的参数会做预编译,也就是会当做字符串来处理 select * from ...