(8)Spring Boot 与数据访问
简介
对于数据访问层,无论是 SQL 还是 NOSQL ,Spring Boot 默认都采用整合 Spring Data 的方式进行统一处理 ,添加大量自动配置,屏蔽了很多设置;
引入各种 xxxTemplate,xxxRepository 来简化我们对数据访问层的操作,对我们来说,只需要进行简单的设置即可。
整合基本的JDBC与数据源
引入启动器
Spring Boot有许多的场景启动器,这里就提供了spring-boot-starter-jdbc;<!--引入 JDBC-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<!--引入 mysql 驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
配置
application.yml然后在配置文件里面,告诉
Spring Boot数据库地址、用户名、密码# 配置数据库
spring:
datasource:
username: root
password: Myis03571
url: jdbc:mysql:///cms?charset=utf-8&useSSL=false&serverTimezone=GMT%2B8&allowPublicKeyRetrieval=true
driver-class-name: com.mysql.cj.jdbc.Driver
测试下数据源:
@Autowired
private DataSource dataSource;
@Test
public void contextLoads() throws SQLException {
Connection connection = dataSource.getConnection();
System.out.println(" ---- "+dataSource.getClass());
System.out.println(" ---- "+connection);
connection.close(); }
打印结果:
---- class com.zaxxer.hikari.HikariDataSource
---- HikariProxyConnection@668754554 wrapping com.mysql.cj.jdbc.ConnectionImpl@570ba13
Spring Boot2.0版本以后,默认选择的数据源是HikariDataSource,也可以在配置文件里面制定自定义的数据源类型 :spring.datasource.type,指定数据源类型;初始化数据库
可以将
sql语句放在类路径下面,其中默认的命名规则:建表语句文件起名叫schema.sql,插入语句文件起名叫data.sql;也可以设置后缀,比如你想在项目启动的时候,执行
schema-mysql.sql,则需要在配置文件里面进行配置:spring.datasource.platform = mysql,指定下;或者也可以完全自定义这些规则,在配置文件里面配置,指定位置及文件名称 :
spring:
datasource:
schema:
- classpath:xxx.sql
需要注意的事:每次应用重新启动,都会执行一次这些
sql语句,也就是表会被重建,这样里面数据会丢失;自动配置了
JdbcTemplate我们可以直接使用注入,获取到它,然后操控数据库;
可以向下面这样使用:
@Autowired
private JdbcTemplate jdbcTemplate ; @ResponseBody
@GetMapping("/users")
public List<Map<String, Object>> getUser(){
List<Map<String, Object>> mapList = jdbcTemplate.queryForList("select * from DEPARTMENT");
return mapList;
}
坑点
如果这时候你启动项目,你会发现,你的
sql语句死活都得不到执行,数据库没有任何表生成,控制台也看不到任何sql的日志,调试了半天;博主也只是个搬运工啊,看的视频,然后自己写的教程,视频老师使用
Spring Boot的版本是2.0 ↓,最后一路查到官网(2.0 ↑),发现有下面一段话:
大概意思就是说:
Spring Boot能够自动的执行schema文件,根据配置的数据源,这种自动的行为,可以通过spring.datasource.initialization-mode控制,然后重点的一句话:比如你可以使用spring.datasource.initialization-mode=always控制Spring Boot永远的执行上述操作,而不管其具体类型;这句话的潜台词,可能是想告诉我,
Spring Boot在某些情况下,会不执行schema文件,好像我们遇到了这种情况,但是啥情况它也没说,或者说了我没看见,甭管,直接配置下属性spring.datasource.initialization-mode=always再说:启动,然后控制台,我还是没找到对应的日志,真的迷,我都打开了终极日志输出了:
logging.level.* = trace
debug=true
好在,数据库里面表已经创建出来了;
总结:记得配上
spring.datasource.initialization-mode=always,如果你使用的是2.0 ↑;
整合 druid 数据源
虽然 Spring Boot 默认使用 HikariDataSource ,可能这也是它推荐 HikariDataSource 的一种手段,但是我们由于一些原因,不接受它的推荐;
HikariDataSource 性能是要优于 druid 的,但是 druid 有一整套的方案,可以监控许多东西,还有后台管理界面;
引入
Druid<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.8</version>
</dependency>
我靠,
IDEA莫名其妙,引入以后,pom文件也没爆红,然后jar包也下载到本地,但是IDEA依赖里面找不到,重启下才找到。修改依赖的数据源
# 配置数据库
spring:
datasource:
username: root
password: Myis03571
url: jdbc:mysql:///any?charset=utf-8&useSSL=false&serverTimezone=GMT%2B8&allowPublicKeyRetrieval=true
driver-class-name: com.mysql.cj.jdbc.Driver
schema:
- classpath:ssasa.sql
# 修改数据源,改为 马云 家 的
type: com.alibaba.druid.pool.DruidDataSource
启动之前的测试,这次打印出的数据源是:
---- class com.alibaba.druid.pool.DruidDataSource
配置数据源
Druid 配置讲解 ,这篇写的不错,可以看下,主要看他,那些配置项的意思;
# 配置数据库
spring:
datasource:
username: root
password: Myis03571
url: jdbc:mysql:///any?charset=utf-8&useSSL=false&serverTimezone=GMT%2B8&allowPublicKeyRetrieval=true
driver-class-name: com.mysql.cj.jdbc.Driver
schema:
# - 可以写多个,是个列表
# - classpath:ssasa.sql
type: com.alibaba.druid.pool.DruidDataSource # 配置下数据源
initialSize: 5
minIdle: 5
maxActive: 20
maxWait: 60000
timeBetweenEvictionRunsMillis: 60000
minEvictableIdleTimeMillis: 300000
validationQuery: SELECT 1 FROM DUAL
testWhileIdle: true
testOnBorrow: false
testOnReturn: false
poolPreparedStatements: true
# 配置监控统计拦截的 filters,去掉以后监控界面的 sql 无法统计,'wall' 用于防火墙
filters: stat,wall,log4j
maxPoolPreparedStatementPerConnectionSize: 20
useGlobalDataSourceStat: true
connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500然后,在配置里面,加载下
spring.datasource下面的属性,进行属性的绑定:@ConfigurationProperties(prefix = "spring.datasource")
@Bean
public DataSource dataSource(){
return new DruidDataSource();
}
然后运行,哐!报错:
Caused by: java.lang.NoClassDefFoundError: org/apache/log4j/Priority
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:264)
at com.alibaba.druid.util.Utils.loadClass(Utils.java:203)
at com.alibaba.druid.filter.FilterManager.loadFilter(FilterManager.java:104)
at com.alibaba.druid.pool.DruidAbstractDataSource.addFilters(DruidAbstractDataSource.java:1286)
at com.alibaba.druid.pool.DruidAbstractDataSource.setFilters(DruidAbstractDataSource.java:1275)
... 107 more
Caused by: java.lang.ClassNotFoundException: org.apache.log4j.Priority
at java.net.URLClassLoader.findClass(URLClassLoader.java:382)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:349)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
... 113 more一通搜索以后,找到原因所在: 由于
Spring Boot 2.xxx版本,底层将日志框架的组件换了个小零件,log4j-over-slf4j被换成了log4j-to-slf4j,但是logback + sl4j这套组合又需要log4j-over-slf4j,不然就报错,因此添加下log4j-over-slf4j,它是个中间层,承上启下,上承log4j,然后做个转换,换成logback;(切忌,不要直接添加 log4j 包,那样就打破了整个系统使用同一套日志的机制):
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>log4j-over-slf4j</artifactId>
<version>1.7.24</version>
</dependency>
打断点,再次运行,看下数据源:

属性已经注入到其中;配置监控
/**
* 配置 Druid 的监控
* 1、先配置一个管理后台的 servlet
* 2、配置一个监控后台的 filter
*
* 备注,方法名字,不可随意写,spring Boot 是根据这些去覆盖某些bean的
* @return
*/
@Bean
public ServletRegistrationBean statViewServlet() {
// 后面的参数,设置进入管理页面的url,可以随便写,但是最好写成 /druid/*
// 因为,当没有登陆以后,访问其他监控页面的时候,会自动的跳转到 ,/druid/login.html
// 如果你这里配置成其他的,则跳转发生错误了
ServletRegistrationBean bean = new ServletRegistrationBean(new StatViewServlet(), "/druid/*"); // 配置 StatViewServlet 的属性
Map<String, String> initParameters = new HashMap<>();
// 配置后台登陆的用户名和密码
initParameters.put("loginUsername", "admin");
initParameters.put("loginPassword", "123456");
// 配置允许谁登陆,默认允许任何人使用配置的用户名和密码登陆,配置成localhost,就仅仅本机能登陆了
initParameters.put("allow", "");
// 配置拒绝谁访问
initParameters.put("deny", "192.168.111.1"); bean.setInitParameters(initParameters); return bean;
}
@Bean
public FilterRegistrationBean webStatFilter() {
FilterRegistrationBean bean = new FilterRegistrationBean();
bean.setFilter(new WebStatFilter()); // 同样可以配置初始化参数
Map<String, String> initParas = new HashMap<>();
// 配置排除项,排除哪些资源,排除静态资源
initParas.put("exclusions","*.js,*.css,/druid/*"); bean.setInitParameters(initParas); // 配置拦截的 url
bean.setUrlPatterns(Arrays.asList("/*"));
return bean ;
}
然后在浏览器里面,输入你配置的进入监控页面的路径:

输入配置的用户名和密码,来到管理页面:
感觉可以拿去充当毕业设计了,后台管理系统,哈哈哈。。阿里给力啊;页面广告被 ABP 插件屏蔽了,不然每个页面都是阿里云的广告;
整合 mybatis
引入 mybatis 依赖:
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.0.0</version>
</dependency>
可以看到是由 mybatis 打头的,它是由 mybatis 官方开发的,来支持 Spring 的,也就是其实 Spring 官方根本没看上 Mybatis,其实也就是国内在大规模使用 mybatis ,国外反而使用 hibernate 为主流;其实 hibernate 也没有那么不堪,你逃不过的,如果想要玩 JPA ,hibernate 就是绕不过去的一关 ;
使用
mybatis基于注解创建一个
mapper接口,然后在接口方法上使用注解,直接写sql:
@Mapper
public interface DepartmentMapper { @Options(useGeneratedKeys = true,keyProperty = "id")
@Insert("insert into DEPARTMENT(name) values(#{name})")
public int insertDepartment(Department department); @Select("select * from DEPARTMENT where id = #{id}")
public Department getDeptById(Integer id); @Update("update DEPARTMENT set name = #{name} where id = #{id}")
public int updateDeptById(Department department); @Delete("delete from DEPARTMENT where id = #{id}")
public int deleteDeptById(Integer id);
}然后,控制层代码,
restful风格:
@RestController
public class DepartmentController { @Autowired
private DepartmentMapper departmentMapper; @GetMapping("/dept/{id}")
public Department getDeptById(@PathVariable("id") Integer id) {
return departmentMapper.getDeptById(id);
} @GetMapping("/dept")
public Department insertDept(Department department) {
departmentMapper.insertDepartment(department);
return department;
}
}在配置类里面,进行自定义
mybatis配置,比如开启驼峰命名法:/**
* 自定义mybatis的配置
*
* @return
*/
@Bean
public ConfigurationCustomizer configurationCustomizer() {
return new ConfigurationCustomizer() {
@Override
public void customize(org.apache.ibatis.session.Configuration configuration) {
// 开启驼峰命名法
configuration.setMapUnderscoreToCamelCase(true);
}
};
}
也可以使用
@MapperScan(value = "cn.hyc.demo.mapper")注解批量扫描mapper接口 ;
使用配置文件版本
跟以前学的时候,没啥差别;
这里,仅仅记录下不一样的地方;
在类路径下面创建一个
mybatis的全局配置文件,内容如下(暂时没做任何配置):<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration> </configuration>
在
spring Boot配置文件配置下mybatis的相关配置,让mybatis知道mapper文件在哪# 配置 mybatis 的相关配置
mybatis:
config-location: classpath:mybatis/mybatis-config.xml
mapper-locations: classpath:mybatis/mapper/*.xml
(8)Spring Boot 与数据访问的更多相关文章
- Spring Boot的数据访问:CrudRepository接口的使用
示例 使用CrudRepository接口访问数据 创建一个新的Maven项目,命名为crudrepositorytest.按照Maven项目的规范,在src/main/下新建一个名为resource ...
- Spring Boot实现数据访问计数器
1.数据访问计数器 在Spring Boot项目中,有时需要数据访问计数器.大致有下列三种情形: 1)纯计数:如登录的密码错误计数,超过门限N次,则表示计数器满,此时可进行下一步处理,如锁定该账户 ...
- Spring Boot的数据访问 之Spring Boot + jpa的demo
1. 快速地创建一个项目,pom中选择如下 <?xml version="1.0" encoding="UTF-8"?> <project x ...
- Spring Boot框架 - 数据访问 - 整合Mybatis
一.新建Spring Boot项目 注意:创建的时候勾选Mybatis依赖,pom文件如下 <dependency> <groupId>org.mybatis.spring.b ...
- Spring Boot框架 - 数据访问 - JDBC&自动配置
一.新建Spring Boot 工程 特殊勾选数据库相关两个依赖 Mysql Driver — 数据库驱动 Spring Data JDBC 二.配置文件application.properties ...
- Spring MVC或Spring Boot配置默认访问页面不生效?
相信在开发项目过程中,设置默认访问页面应该都用过.但是有时候设置了却不起作用.你知道是什么原因吗?今天就来说说我遇到的问题. 首先说说配置默认访问页面有哪几种方式. 1.tomcat配置默认访问页面 ...
- Spring boot未授权访问造成的数据库外联
一.spring boot 日常测试或攻防演练中像shiro,fastjson等漏洞已经越来越少了,但是随着spring boot框架的广泛使用,spring boot带来的安全问题也越来越多,本文仅 ...
- Spring Boot与数据
SpringBoot 着眼于JavaEE! 不仅仅局限于 Mybatis .JDBC. Spring Data JPA Spring Data 项目的目的是为了简化构建基于 Spring 框架应用的数 ...
- Spring boot通过JPA访问MySQL数据库
本文展示如何通过JPA访问MySQL数据库. JPA全称Java Persistence API,即Java持久化API,它为Java开发人员提供了一种对象/关系映射工具来管理Java应用中的关系数据 ...
随机推荐
- Parse发布Bolts,一个面向iOS和Android的底层库集合
转载自:http://www.infoq.com/cn/news/2014/02/parse-announces-bolts 数月前,Parse被Facebook收购.最近,它开源了一个面向iOS和A ...
- 关于密码重用参数PASSWORD_REUSE_TIME,PASSWORD_REUSE_MAX之间的关系及其演示
转自: https://blog.51cto.com/carefree/1382811 测试环境:10.2.0.2.0测试用户:SCOTT测试用的三组密码:oracle1 oracle2 oracle ...
- select,poll,epoll最简单的解释
从事服务端开发,少不了要接触网络编程.epoll 作为 Linux 下高性能网络服务器的必备技术至关重要,nginx.Redis.Skynet 和大部分游戏服务器都使用到这一多路复用技术. epoll ...
- vue+elementui搭建后台管理界面(4使用font-awesome)
使用font-awesome npm install --save font-awesome 修改 src/main.js 增加 import 'font-awesome/scss/font-awes ...
- "笨方法"学习CNN图像识别(二)—— tfrecord格式高效读取数据
原文地址:https://finthon.com/learn-cnn-two-tfrecord-read-data/-- 全文阅读5分钟 -- 在本文中,你将学习到以下内容: 将图片数据制作成tfre ...
- C/C++ #define的作用域
#define #define macro的作用域有点类似于C/C++全局静态变量 编译器处理宏的时机是预处理阶段 编译器按文本顺序处理 遇到宏时就定义一个宏变量 假设这种情况 void test() ...
- java项目代码上线
java项目代码上线 1:java项目代码上线架构图 ip地址及主机名规划 10.0.0.11 deploy 10.0.0.12 tomcat-web01 10.0.0.13 git.oldboy ...
- iptables nat表配置
- Linux 在 TOP 命令中切换内存的显示单位
顶部的内存信息可以在top运行时按E切换,每次切换转换率为1000,只是没有单位,切换的单位为 k,m,g,t,p: 1. 2. 3., 4. 底下的进程信息按e切换,每次切换转换率为1000,切换的 ...
- Jmeter全局变量设置
背景:因为BeanShell PreProcessor制造的参数是一些随机参数,每个HTTP取样器包括其他取样器拿值得时候都是单独重新取一次,所以如果当几个取样器的值都要拿同一值时,就不满足需求了,我 ...