5.数据库访问

本文是读《Spring Boot2精髓-从构件小系统到架构分布式大系统》的读书笔记。

本章介绍 Spring JDBC Template 和 BeetlSQL 两种数据库访问方式, JDBC Template 是 Spring自带的,在 JDBC 的基础上做了 一定封装,而 BeetlSQL 是作者开发的这里不做介绍。都是以 SQL 为核心 。
SQL 为中心或者以对象为中心,两种访问方式没有绝对的好坏, 一般来说,以 SQL 为
核心的数据库访问更为灵活,更能适应大型的互联网和企业应用,学习门槛较低 。 以对象方式访问数据库更适合较为简单的系统或者工具类系统,学习门槛刚开始较低,但因为 ORM(ObjectRelational Mapping)持久化上下文等概念过于复杂,导致后期深入学习较为困难 。

5.1 配置数据源

本章将使用号称最快的数据库连接池 HikariCP 来说明 JDBC Template 和 BeetlSQL,集成
HikariCP 到 Spring Boot,首先在 porn 中加入如下依赖:

<dependency>
	<groupId>com.zaxxer</groupId>
	<artifactId>HikariCP</artifactId>
</dependency>

本例使用了问ySQL ,你也可以使用任何其他驱动来完成本章的例子 , 使用 MySQL需要在 porn 中配置 MySQL 驱 动 依赖 。

		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<version>6.0.5</version>
		</dependency>

配置好上述依赖包和配置文件后,需要写一个 Java Config 来创建一个数据源,代码如下:

package com.bee.sample.ch5.conf;

import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;

import com.zaxxer.hikari.HikariDataSource;

@Configuration
public class DataSourceConfig {
	
	@Bean(name = "dataSource")
	public DataSource datasource(Environment env) {
		HikariDataSource ds = new HikariDataSource();
		ds.setJdbcUrl(env.getProperty("spring.datasource.url"));
		ds.setUsername(env.getProperty("spring.datasource.username"));
		ds.setPassword(env.getProperty("spring.datasource.password"));
		ds.setDriverClassName(env.getProperty("spring.datasource.driver-class-name"));
		return ds;
	}
}

以上代码创建了 一个叫 dataSource 的数据源,我们使用 HikariDataSource 。

CREATE TABLE `user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(45) COLLATE utf8_bin DEFAULT NULL COMMENT '名称',
  `department_id` int(11) DEFAULT NULL,
  `create_time` date DEFAULT NULL COMMENT '创建时间',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;

CREATE TABLE `department` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(45) COLLATE utf8_bin DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;


INSERT INTO `user` VALUES (1, 'helo', 1, '2017-4-21 11:52:41');
INSERT INTO `department` VALUES ('1', '研发部门');

5.2 Spring JDBC Template

Spring 提供了 JdbcTemplate 对数据库访问技术 JDBC 做了 一定封装 ,包括管理数据库连接,简单查询结果映射成 Java 对象,复杂的结果集通过实现 RowMapper 接口来映射到 Java 对象 。
在 Spring Boot 中 ,只要配置好数据源 DataSource , 就能自动使用 JdbcTemplate .

查询
一个简单的返回总数的查询:

int rowCount = this.jdbcTemplate.queryForObject (” select count (*) from user” ,Integer.class) ;

一个带参数绑定的查询:

String rowCount = this . jdbcTemplate.queryForOb] ect (” select count(*) from user where department id=?, Integer . class ,l);

如果期望返回 POJO 实例, JdbcTemplate 需要一个 RowMapper , 将查询结果集 ResultSet 映射成一个对象:
通常 RowMapp巳r 可以被其他查询复用,因此最好的办法是在 DAO 中创建一个内部类,然后在 user 的查询中使用此类:

public class UserDao{
static class UserRowMapper implements RowMapper<User> {
		public User mapRow(ResultSet rs, int rowNum) throws SQLException {
			User user = new User();
			user.setId(rs.getInt("id"));
			user.setName(rs.getString("name"));
			user.setDepartmentId(rs.getInt("department_id"));
			return user;
		}
	}
}	

JdbcTemplate 查询如果期望返回的是列表 ,则 需要使用 query 方法 :

	public List<User> getUserByDepartmentId(Long departmenetId) {
		String sql = "select * from user where department_id=? ";
		List<User> user = jdbcTempalte.query(sql, new UserRowMapper(), 1);
		return user;
	}

修改
JdbcTempalte 提供 update 方法来实现 SQL 的修改语旬,包括新增、修改、删除、执行存储过程等。

String sql =”update user set name=? and departmet_id=? where id = ?;
jdbcTempalte.update(sql,user.getName(),user.getDepartmentid(),user.getid()) ;

如果是数据库插入,操作同上面的 update,对于 MySQL、 SQL Server等数据库,含有自增序列 , 则需要提供一个 KeyHolder 来放置返回的序列 :

	public Integer insertUser(final User user) {
		final String sql = "insert into user (name, departmet_id ) values (?,?)";
		KeyHolder keyHolder = new GeneratedKeyHolder();
		jdbcTempalte.update(new PreparedStatementCreator() {
			public PreparedStatement createPreparedStatement(Connection connection) throws SQLException {
			//指出自增主键的列名
				PreparedStatement ps = connection.prepareStatement(sql, new String[] { "id" });
				ps.setString(1, user.getName());
				ps.setInt(2, user.getDepartmentId());
				return ps;
			}
		}, keyHolder);
		return keyHolder.getKey().intValue();
	}

JdbcTemplate
N amedParameterJdbcTemplate 继承了 JdbcTemplate , 不同于 JdbcTemplate , 对 SQL 中的参数只支持传统的“?”占位符。NamedParameterJdbcTemplate 允许 SQL 中使用参数的名字作为占位符
Spring Boot 己经自动配置了 NamedParameterJdbcTemplate,可以自动注入使用 :

@Autowired
NamedParameterJdbcTemplate namedParameterJdbcTemplate ;
	public Integer totalUserInDepartment2(Long departmentId) {
		String sql = "select count(1) from user where department_id=:deptId";
		MapSqlParameterSource namedParameters = new MapSqlParameterSource();
	    namedParameters.addValue("deptId", departmentId);
		Integer count = namedParameterJdbcTemplate.queryForObject(sql, namedParameters,  Integer.class) ;
		return count;
	}

MapSqlParameterSource 是一个类似 Map 风格的类,包含 Key-Value, Key 就是 SQL 中的参数名字,在 SQL 语句中,不再使用“?”,而是使用了“:”开头的参数名字 ,如“:deptld ”。

BeetlSQL介绍

这里不作说明
针对 Spring JDBC Template存在 的一些问题,可以引申学习一下Mybatis框架。
JPA具有内置多种DAO操作功能的优点
MyBatis具有SQL集中管理的优点
JdbcTemplate 和 mybatis 的对比
谈jdbcTemplate与mybatis
这两篇博文可以看一下

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值