SpringBoot学习笔记-6:第六章 Spring Boot 与数据访问

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: SpringBoot学习笔记-6:第六章 Spring Boot 与数据访问

第六章 Spring Boot 与数据访问

数据访问简介

JDBC

MyBatis

SpringDataJPA

JDBC&自动配置原理

依赖

<!--数据库访问-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <scope>runtime</scope>
</dependency>

配置数据源

支持的数据源

HikariDataSource
org.apache.tomcat.jdbc.pool.DataSource
org.apache.commons.dbcp2.BasicDataSource
自定义 DataSource

DataSourceInitializer

自动运行建表语句

运行插入数据的 sql 语句

文件名命名规则

scheme-*.sql
data-*.sql

或者指定文件名

application.yml

spring:
  # 配置数据源
  datasource:
    username: root
    password: 123456
    url: jdbc:mysql://localhost:3306/data
    driver-class-name: com.mysql.cj.jdbc.Driver
    # 始终执行初始化
    initialization-mode: ALWAYS
    # 指定自动建表sql
    schema:
      - classpath:schema-all.sql

schema-all.sql

create table if not exists `person` (
    `id` int,
    `name` varchar(255)
);
-- 注意需要有分号结尾

查询数据

package com.example.demo.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
import java.util.Map;
/**
 * 人物数据接口
 */
@RestController
@RequestMapping("/person")
public class PersonController {
    @Autowired
    private JdbcTemplate jdbcTemplate;
    @GetMapping("/list")
    public List<Map<String, Object>> list(){
        String sql = "select * from person";
        List<Map<String, Object>> list = jdbcTemplate.queryForList(sql);
        return list;
    }
}

整合 Druid&配置数据源监控

Druid 能够提供强大的监控和扩展功能

druid 的配置

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.slowSqlMills=500

依赖

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid</artifactId>
    <version>1.1.21</version>
</dependency>

配置

spring:
  # 配置数据源
  datasource:
    # 自定义数据源
    type: com.alibaba.druid.pool.DruidDataSource
    # 统计sql
    filters: stat,wall

自定义配置类

package com.example.demo.config;
import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.support.http.ResourceServlet;
import com.alibaba.druid.support.http.StatViewServlet;
import com.alibaba.druid.support.http.WebStatFilter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.sql.DataSource;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
@Configuration
public class DruidConfig {
    // 加载druid的自定义参数
    @ConfigurationProperties(prefix="spring.datasource")
    @Bean
    public DataSource druid(){
        return new DruidDataSource();
    }
    // 配置Druid监控
    @Bean
    public ServletRegistrationBean statViewServlet(){
        ServletRegistrationBean bean = new ServletRegistrationBean(new StatViewServlet(), "/druid/*");
        Map<String, String> params = new HashMap<>();
        params.put(ResourceServlet.PARAM_NAME_USERNAME, "admin");
        params.put(ResourceServlet.PARAM_NAME_PASSWORD, "123456");
        bean.setInitParameters(params);
        return bean;
    }
    // 配置filter
    @Bean
    public FilterRegistrationBean webStatFilter(){
        FilterRegistrationBean bean = new FilterRegistrationBean();
        bean.setFilter(new WebStatFilter());
        bean.setUrlPatterns(Arrays.asList("/*"));
        Map<String, String> params = new HashMap<>();
        params.put(WebStatFilter.PARAM_NAME_EXCLUSIONS, "*.js,*.css");
        bean.setInitParameters(params);
        return bean;
    }
}

后台监控地址

http://localhost:8080/druid/

整合 MyBatis(一)-基础环境搭建

mybatis-spring-boot-starter

<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>2.1.3</version>
</dependency>

整合 MyBatis(二)-注解版 MyBatis

src/main/java/com/example/demo/mapper/DepartmentMapper.java

package com.example.demo.mapper;
import com.example.demo.pojo.Department;
import org.apache.ibatis.annotations.*;
// 指定这是一个操作数据库的mapper
// @Mapper
public interface DepartmentMapper {
    @Select("select * from department where id = #{id}")
    public Department getById(Integer id);
    @Delete("delete from department where id = #{id}")
    public int deleteById(Integer id);
    // 插入数据后自增主键自动设置到department
    @Options(useGeneratedKeys = true, keyProperty = "id")
    @Insert("insert into department(name) values(#{name}) ")
    public int insert(Department department);
    @Update("update department set name = #{name} where id = #{id} ")
    public int update(Department department);
}

src/main/java/com/example/demo/controller/DepartmentController.java

package com.example.demo.controller;
import com.example.demo.mapper.DepartmentMapper;
import com.example.demo.pojo.Department;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class DepartmentController {
    @Autowired
    private DepartmentMapper departmentMapper;
    @GetMapping("/dept/{id}")
    public Department getDepartment(@PathVariable("id") Integer id){
        return departmentMapper.getById(id);
    }
    @GetMapping("/dept")
    public Department insertDepartment(Department department){
        departmentMapper.insert(department);
        return department;
    }
}

src/main/java/com/example/demo/DemoApplication.java

package com.example.demo;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
// 自动扫描mapper接口,不用每个mapper都添加@Mapper注解
@MapperScan(value = {"com.example.demo.mapper"})
@SpringBootApplication
public class DemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}

整合 MyBatis(二)-配置版 MyBatis

文档:

https://mybatis.org/mybatis-3/zh/index.html

application.yml

mybatis:
  # 指定全局配置文件路径
  config-location: classpath:mybatis/mybatis-config.xml
  # 指定mapper文件路径
  mapper-locations: classpath:mybatis/mapper/*.xml

src/main/resources/mybatis/mybatis-config.xml

<?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>
    <settings>
        <!--开启驼峰命名自动映射-->
        <setting name="mapUnderscoreToCamelCase" value="true"/>
    </settings>
</configuration>

src/main/resources/mybatis/mapper/EmployeeMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.demo.mapper.EmployeeMapper">
    <select id="getById" resultType="com.example.demo.pojo.Employee">
    select * from employee where id = #{id}
  </select>
    <insert id="insert">
        insert into employee (name, age, sex, birth, department_id)
        values (#{name}, #{age}, #{sex}, #{birth}, #{department_id})
    </insert>
    <delete id="deleteById">
        delete from employee where id = #{id}
    </delete>
</mapper>

src/main/java/com/example/demo/mapper/EmployeeMapper.java

package com.example.demo.mapper;
import com.example.demo.pojo.Employee;
// @Mapper 或@MapperScan 将接口扫描装配到容器中
public interface EmployeeMapper {
    public Employee getById(Integer id);
    public int deleteById(Integer id);
    public void insert(Employee employee);
}

src/main/java/com/example/demo/controller/DepartmentController.java

package com.example.demo.controller;
import com.example.demo.mapper.DepartmentMapper;
import com.example.demo.mapper.EmployeeMapper;
import com.example.demo.pojo.Department;
import com.example.demo.pojo.Employee;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class DepartmentController {
    @Autowired
    private EmployeeMapper employeeMapper;
    @GetMapping("/getEmp/{id}")
    public Employee getEmployee(@PathVariable("id") Integer id){
        return employeeMapper.getById(id);
    }
}

SpringData JPA

SpringData 为我们提供使用同一的 API 来对数据访问层进行操作

JPA: Java Persistence API

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
    <version>2.3.1.RELEASE</version>
</dependency>

配置文件

spring:
  jpa:
    hibernate:
      # 更新或创建表结构
      ddl-auto: update
    # 控制台打印sql
    show-sql: true

JAP:ORM Object Relation Mapping

编写实体类与数据表进行映射

package com.example.demo.entity;
import javax.persistence.*;
// 使用JPA注解配置映射关系
@Entity // 实体类
@Table(name = "tbl_user") // 指定表名
public class User {
    @Id // 主键
    @GeneratedValue(strategy = GenerationType.IDENTITY) // 自增
    private Integer id;
    @Column(name = "last_name", length = 50)
    private String lastName;
    @Column // 默认类名=属性名
    private String email;
}

创建 repository

package com.example.demo.repository;
import com.example.demo.entity.User;
import org.springframework.data.jpa.repository.JpaRepository;
// 继承JpaRepository来完成对数据库的操作
public interface UserRepository extends JpaRepository<User, Integer> {
}

Controller

package com.example.demo.controller;
import com.example.demo.entity.User;
import com.example.demo.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import java.util.Optional;
@RestController
public class UserController {
    @Autowired
    private UserRepository userRepository;
    @GetMapping("/user/{id}")
    public User getUser(@PathVariable("id") Integer id){
        Optional<User> user = userRepository.findById(id);
        if(user.isPresent()){
            return user.get();
        } else{
            return null;
        }
    }
    @GetMapping("/user")
    public User insertUser(User user){
        User savedUser = userRepository.save(user);
        return savedUser;
    }
}


相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
23天前
|
监控 Java 数据库连接
详解Spring Batch:在Spring Boot中实现高效批处理
详解Spring Batch:在Spring Boot中实现高效批处理
122 12
|
23天前
|
安全 Java 测试技术
详解Spring Profiles:在Spring Boot中实现环境配置管理
详解Spring Profiles:在Spring Boot中实现环境配置管理
70 10
|
19天前
|
负载均衡 Java 开发者
深入探索Spring Cloud与Spring Boot:构建微服务架构的实践经验
深入探索Spring Cloud与Spring Boot:构建微服务架构的实践经验
62 5
|
2月前
|
Java 测试技术 开发者
springboot学习四:Spring Boot profile多环境配置、devtools热部署
这篇文章主要介绍了如何在Spring Boot中进行多环境配置以及如何整合DevTools实现热部署,以提高开发效率。
99 2
|
2月前
|
前端开发 Java 程序员
springboot 学习十五:Spring Boot 优雅的集成Swagger2、Knife4j
这篇文章是关于如何在Spring Boot项目中集成Swagger2和Knife4j来生成和美化API接口文档的详细教程。
191 1
|
NoSQL Java 数据库连接
Idea创建SpringBoot多模块项目
我们可以定义一个维度,以此来划分模块,例如上述商城、可以划分成商品、库存和订单模块。也可以目录结构分层,`Controller`层,只不过没人这样做。这样就引申出了下一个问题`拆分策略`。
940 0
Idea创建SpringBoot多模块项目
|
Java 应用服务中间件 Maven
传统maven项目和现在spring boot项目的区别
Spring Boot:传统 Web 项目与采用 Spring Boot 项目区别
507 0
传统maven项目和现在spring boot项目的区别
|
XML Java 数据库连接
创建springboot项目的基本流程——以宠物类别为例
创建springboot项目的基本流程——以宠物类别为例
156 0
创建springboot项目的基本流程——以宠物类别为例
|
存储 机器学习/深度学习 IDE
SpringBoot 项目与被开发快速迁移|学习笔记
快速学习 SpringBoot 项目与被开发快速迁移
SpringBoot 项目与被开发快速迁移|学习笔记
|
Java Spring
自定义SpringBoot项目的启动Banner
``Banner``是``SpringBoot``框架一个特色的部分,其设计的目的无非就是一个框架的标识,其中包含了版本号、框架名称等内容,既然``SpringBoot``为我们提供了这个模块,它肯定也是可以更换的这也是``Spring``开源框架的设计理念。
下一篇
DataWorks