• Java(SpringBoot06)


    Java(SpringBoot06)

    参考视频:31. 整合JDBC使用(狂神)

    17. SpringBoot整合JDBC

    17.1 SpringData简介

    • 对于数据访问层,无论是 SQL(关系型数据库) 还是 NOSQL(非关系型数据库),Spring Boot 底层都是采用 Spring Data 的方式进行统一处理。
    • Spring Boot 底层都是采用 Spring Data 的方式进行统一处理各种数据库,Spring Data 也是 Spring 中与 Spring Boot、Spring Cloud 等齐名的知名项目。
    • Sping Data 官网:https://spring.io/projects/spring-data
    • 数据库相关的启动器 :可以参考官方文档:
      • https://docs.spring.io/spring-boot/docs/2.2.5.RELEASE/reference/htmlsingle/#using-boot-starter

    17.2 整合JDBC

    17.2.1 创建测试项目测试数据源

    1. 我去新建一个项目测试:springboot-data-jdbc ; 引入相应的模块!基础模块
      在这里插入图片描述

    2. 项目建好之后,发现自动帮我们导入了如下的启动器:

    <dependency>
        <groupId>org.springframework.bootgroupId>
        <artifactId>spring-boot-starter-jdbcartifactId>
    dependency>
    <dependency>
        <groupId>mysqlgroupId>
        <artifactId>mysql-connector-javaartifactId>
        <scope>runtimescope>
    dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    1. 编写yaml配置文件连接数据库;
    spring:
      datasource:
        username: root
        password: 123456
        #?serverTimezone=UTC解决时区的报错
        url: jdbc:mysql://localhost:3306/springboot?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8
        driver-class-name: com.mysql.cj.jdbc.Driver
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    1. 配置完这一些东西后,我们就可以直接去使用了,因为SpringBoot已经默认帮我们进行了自动配置;去测试类测试一下
    @SpringBootTest
    class SpringbootDataJdbcApplicationTests {
    
        //DI注入数据源
        @Autowired
        DataSource dataSource;
    
        @Test
        public void contextLoads() throws SQLException {
            //看一下默认数据源
            System.out.println(dataSource.getClass());
            //获得连接
            Connection connection =   dataSource.getConnection();
            System.out.println(connection);
            //关闭连接
            connection.close();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 结果:我们可以看到他默认给我们配置的数据源为 : class com.zaxxer.hikari.HikariDataSource , 我们并没有手动配置

    • 我们来全局搜索一下,找到数据源的所有自动配置都在 :DataSourceAutoConfiguration文件:

    @Import(
        {Hikari.class, Tomcat.class, Dbcp2.class, Generic.class, DataSourceJmxConfiguration.class}
    )
    protected static class PooledDataSourceConfiguration {
        protected PooledDataSourceConfiguration() {
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 这里导入的类都在 DataSourceConfiguration 配置类下,可以看出 Spring Boot 2.2.5 默认使用HikariDataSource 数据源,而以前版本,如 Spring Boot 1.5 默认使用 org.apache.tomcat.jdbc.pool.DataSource 作为数据源;

    • HikariDataSource 号称 Java WEB 当前速度最快的数据源,相比于传统的 C3P0 、DBCP、Tomcat jdbc 等连接池更加优秀;

    • 可以使用 spring.datasource.type 指定自定义的数据源类型,值为 要使用的连接池实现的完全限定名。

    • 关于数据源我们并不做介绍,有了数据库连接,显然就可以 CRUD 操作数据库了。但是我们需要先了解一个对象 JdbcTemplate

    17.2.2 JDBCTemplate

    1. 有了数据源(com.zaxxer.hikari.HikariDataSource),然后可以拿到数据库连接(java.sql.Connection),有了连接,就可以使用原生的 JDBC 语句来操作数据库;

    2. 即使不使用第三方第数据库操作框架,如 MyBatis等,Spring 本身也对原生的JDBC 做了轻量级的封装,即JdbcTemplate。

    3. 数据库操作的所有 CRUD 方法都在 JdbcTemplate 中。

    4. Spring Boot 不仅提供了默认的数据源,同时默认已经配置好了 JdbcTemplate 放在了容器中,程序员只需自己注入即可使用

    5. JdbcTemplate 的自动配置是依赖 org.springframework.boot.autoconfigure.jdbc 包下的 JdbcTemplateConfiguration 类

    • JdbcTemplate主要提供以下几类方法:
      • execute方法:可以用于执行任何SQL语句,一般用于执行DDL语句;
      • update方法及batchUpdate方法:update方法用于执行新增、修改、删除等语句;batchUpdate方法用于执行批处理相关语句;
      • query方法及queryForXXX方法:用于执行查询相关语句;
      • call方法:用于执行存储过程、函数相关语句。

    17.2.3 测试

    • 编写一个Controller,注入 jdbcTemplate,编写测试方法进行访问测试;
    package com.kuang.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.PathVariable;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    import java.util.Date;
    import java.util.List;
    import java.util.Map;
    
    @RestController
    @RequestMapping("/jdbc")
    public class JdbcController {
    
        /**
         * Spring Boot 默认提供了数据源,默认提供了 org.springframework.jdbc.core.JdbcTemplate
         * JdbcTemplate 中会自己注入数据源,用于简化 JDBC操作
         * 还能避免一些常见的错误,使用起来也不用再自己来关闭数据库连接
         */
        @Autowired
        JdbcTemplate jdbcTemplate;
    
        //查询employee表中所有数据
        //List 中的1个 Map 对应数据库的 1行数据
        //Map 中的 key 对应数据库的字段名,value 对应数据库的字段值
        @GetMapping("/list")
        public List<Map<String, Object>> userList(){
            String sql = "select * from employee";
            List<Map<String, Object>> maps = jdbcTemplate.queryForList(sql);
            return maps;
        }
        
        //新增一个用户
        @GetMapping("/add")
        public String addUser(){
            //插入语句,注意时间问题
            String sql = "insert into employee(last_name, email,gender,department,birth)" +
                    " values ('狂神说','24736743@qq.com',1,101,'"+ new Date().toLocaleString() +"')";
            jdbcTemplate.update(sql);
            //查询
            return "addOk";
        }
    
        //修改用户信息
        @GetMapping("/update/{id}")
        public String updateUser(@PathVariable("id") int id){
            //插入语句
            String sql = "update employee set last_name=?,email=? where id="+id;
            //数据
            Object[] objects = new Object[2];
            objects[0] = "秦疆";
            objects[1] = "24736743@sina.com";
            jdbcTemplate.update(sql,objects);
            //查询
            return "updateOk";
        }
    
        //删除用户
        @GetMapping("/delete/{id}")
        public String delUser(@PathVariable("id") int id){
            //插入语句
            String sql = "delete from employee where id=?";
            jdbcTemplate.update(sql,id);
            //查询
            return "deleteOk";
        }
        
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 测试请求,结果正常;

    • 到此,CURD的基本操作,使用 JDBC 就搞定了。

    18. SpringBoot整合Druid

    • 暂略。
    • 参考:https://www.bilibili.com/video/BV1PE411i7CV?p=32

    19. SpringBoot整合Mybatis

    • 官方文档:http://mybatis.org/spring-boot-starter/mybatis-spring-boot-autoconfigure/

    • Maven仓库地址:https://mvnrepository.com/artifact/org.mybatis.spring.boot/mybatis-spring-boot-starter/2.1.1
      在这里插入图片描述

    19.1 整合测试

    1. 导入 MyBatis 所需要的依赖
    <dependency>
        <groupId>org.mybatis.spring.bootgroupId>
        <artifactId>mybatis-spring-boot-starterartifactId>
        <version>2.1.1version>
    dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    1. 配置数据库连接信息(不变)
    spring:
      datasource:
        username: root
        password: 123456
        #?serverTimezone=UTC解决时区的报错
        url: jdbc:mysql://localhost:3306/springboot?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8
        driver-class-name: com.mysql.cj.jdbc.Driver
        type: com.alibaba.druid.pool.DruidDataSource
    
        #Spring Boot 默认是不注入这些属性值的,需要自己绑定
        #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,stat:监控统计、log4j:日志记录、wall:防御sql注入
        #如果允许时报错  java.lang.ClassNotFoundException: org.apache.log4j.Priority
        #则导入 log4j 依赖即可,Maven 地址:https://mvnrepository.com/artifact/log4j/log4j
        filters: stat,wall,log4j
        maxPoolPreparedStatementPerConnectionSize: 20
        useGlobalDataSourceStat: true
        connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    1. 测试数据库是否连接成功!

    2. 创建实体类,导入 Lombok!

    • Department.java
    package com.kuang.pojo;
    
    import lombok.AllArgsConstructor;
    import lombok.Data;
    import lombok.NoArgsConstructor;
    
    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    public class Department {
    
        private Integer id;
        private String departmentName;
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    1. 创建mapper目录以及对应的 Mapper 接口
    • DepartmentMapper.java
    //@Mapper : 表示本类是一个 MyBatis 的 Mapper
    @Mapper
    @Repository
    public interface DepartmentMapper {
    
        // 获取所有部门信息
        List<Department> getDepartments();
    
        // 通过id获得部门
        Department getDepartment(Integer id);
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    1. 对应的Mapper映射文件
    • DepartmentMapper.xml
    
    DOCTYPE mapper
            PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
            "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    
    <mapper namespace="com.kuang.mapper.DepartmentMapper">
    
        <select id="getDepartments" resultType="Department">
           select * from department;
        select>
    
        <select id="getDepartment" resultType="Department" parameterType="int">
           select * from department where id = #{id};
        select>
    
    mapper>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    7、maven配置资源过滤问题

    <resources>
        <resource>
            <directory>src/main/javadirectory>
            <includes>
                <include>**/*.xmlinclude>
            includes>
            <filtering>truefiltering>
        resource>
    resources>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    1. 编写部门的 DepartmentController 进行测试!
    @RestController
    public class DepartmentController {
        
        @Autowired
        DepartmentMapper departmentMapper;
        
        // 查询全部部门
        @GetMapping("/getDepartments")
        public List<Department> getDepartments(){
            return departmentMapper.getDepartments();
        }
    
        // 查询全部部门
        @GetMapping("/getDepartment/{id}")
        public Department getDepartment(@PathVariable("id") Integer id){
            return departmentMapper.getDepartment(id);
        }
        
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 启动项目访问进行测试!

    19.2 我们增加一个员工类再测试下,为之后做准备

    1. 新建一个pojo类 Employee ;
    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    public class Employee {
    
        private Integer id;
        private String lastName;
        private String email;
        //1 male, 0 female
        private Integer gender;
        private Integer department;
        private Date birth;
    
        private Department eDepartment; // 冗余设计
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    1. 新建一个 EmployeeMapper 接口
    //@Mapper : 表示本类是一个 MyBatis 的 Mapper
    @Mapper
    @Repository
    public interface EmployeeMapper {
    
        // 获取所有员工信息
        List<Employee> getEmployees();
    
        // 新增一个员工
        int save(Employee employee);
    
        // 通过id获得员工信息
        Employee get(Integer id);
    
        // 通过id删除员工
        int delete(Integer id);
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    1. 编写 EmployeeMapper.xml 配置文件
    
    DOCTYPE mapper
            PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
            "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    
    <mapper namespace="com.kuang.mapper.EmployeeMapper">
    
        <resultMap id="EmployeeMap" type="Employee">
            <id property="id" column="eid"/>
            <result property="lastName" column="last_name"/>
            <result property="email" column="email"/>
            <result property="gender" column="gender"/>
            <result property="birth" column="birth"/>
            <association property="eDepartment"  javaType="Department">
                <id property="id" column="did"/>
                <result property="departmentName" column="dname"/>
            association>
        resultMap>
    
        <select id="getEmployees" resultMap="EmployeeMap">
            select e.id as eid,last_name,email,gender,birth,d.id as did,d.department_name as dname
            from department d,employee e
            where d.id = e.department
        select>
    
        <insert id="save" parameterType="Employee">
            insert into employee (last_name,email,gender,department,birth)
            values (#{lastName},#{email},#{gender},#{department},#{birth});
        insert>
    
        <select id="get" resultType="Employee">
            select * from employee where id = #{id}
        select>
    
        <delete id="delete" parameterType="int">
            delete from employee where id = #{id}
        delete>
    
    mapper>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    1. 编写EmployeeController类进行测试
    @RestController
    public class EmployeeController {
    
        @Autowired
        EmployeeMapper employeeMapper;
    
        // 获取所有员工信息
        @GetMapping("/getEmployees")
        public List<Employee> getEmployees(){
            return employeeMapper.getEmployees();
        }
    
        @GetMapping("/save")
        public int save(){
            Employee employee = new Employee();
            employee.setLastName("kuangshen");
            employee.setEmail("qinjiang@qq.com");
            employee.setGender(1);
            employee.setDepartment(101);
            employee.setBirth(new Date());
            return employeeMapper.save(employee);
        }
    
        // 通过id获得员工信息
        @GetMapping("/get/{id}")
        public Employee get(@PathVariable("id") Integer id){
            return employeeMapper.get(id);
        }
    
        // 通过id删除员工
        @GetMapping("/delete/{id}")
        public int delete(@PathVariable("id") Integer id){
            return employeeMapper.delete(id);
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 测试结果完成,搞定收工!

     
     

    —————— THE END ——————
     
  • 相关阅读:
    ChatGPT驱动下,网站AI客服该如何进步和创新
    ADS原理图到Layout,Layout更新原理图
    基于FPGA的SD NAND图片显示实现
    Windows取证——学习笔记(二)
    21天学习挑战赛-多路平衡归并的实现
    1164 Good in C
    【Rust日报】2022-08-15 `《zero to production》` 新书翻译
    更多模型,更强功能,快来开箱新一代图像分类开源框架
    计算机中CPU、内存、缓存的关系
    时序预测 | MATLAB实现BiLSTM时间序列未来多步预测
  • 原文地址:https://blog.csdn.net/Zachsj/article/details/126225883