SpringBoot(九) -- SpringBoot与数据访问

一.简介
  对于数据访问层,无论是SQL还是NOSQL,Spring Boot默认采用整合Spring Data的方式进行统一处理,添加大量自动配置,屏蔽了很多设置。引入各种xxxTemplate,xxxRepository来简化我们对数据访问层的操作。对我们来说只需要进行简单的设置即可。

二.整合JDBC和数据源
  1.查看POM依赖:

   2.配置datasource:

   3.观察其自动装配:

   4.在其运行时,具有一个DataSourceConfiguration的类,可以实现自定义的数据源配置,默认启用tomcat.jdbc数据源,同时还支持HikariDataSource,dbcp,dbcp2等数据源,我们还可以自定义数据源:

 1     /**
 2      * Generic DataSource configuration.
 3      */
 4     @ConditionalOnMissingBean(DataSource.class)
 5     @ConditionalOnProperty(name = "spring.datasource.type")
 6     static class Generic {
 7 
 8         @Bean
 9         public DataSource dataSource(DataSourceProperties properties) {
10             return properties.initializeDataSourceBuilder().build();
11         }
12 
13

  4.自定义的数据源使用DataSourceBulider来实现自定义数据源的装配,使用反射去创建我们自定义的数据源:

1     public DataSource build() {
2         Class<? extends DataSource> type = getType();
3         DataSource result = BeanUtils.instantiate(type);
4         maybeGetDriverClassName();
5         bind(result);
6         return result;
7     }

  5.在DataSourceInitializer类中定义了一个 DataSourceInitializer implements ApplicationListener<DataSourceInitializedEvent>,该类主要可以帮助我们在程序初始化的时候自动云运行 schema-*.sql data-*.sql:

 1     @PostConstruct
 2     public void init() {
 3         if (!this.properties.isInitialize()) {
 4             logger.debug("Initialization disabled (not running DDL scripts)");
 5             return;
 6         }
 7         if (this.applicationContext.getBeanNamesForType(DataSource.class, false,
 8                 false).length > 0) {
 9             this.dataSource = this.applicationContext.getBean(DataSource.class);
10         }
11         if (this.dataSource == null) {
12             logger.debug("No DataSource found so not initializing");
13             return;
14         }
15         runSchemaScripts();
16     }

  6.可以在程序运行时帮助我们执行建表语句;
  7.运行插入数据的sql语句:

 1     @Override
 2     public void onApplicationEvent(DataSourceInitializedEvent event) {
 3         if (!this.properties.isInitialize()) {
 4             logger.debug("Initialization disabled (not running data scripts)");
 5             return;
 6         }
 7         // NOTE the event can happen more than once and
 8         // the event datasource is not used here
 9         if (!this.initialized) {
10             runDataScripts();
11             this.initialized = true;
12         }
13     }

  8.其默认规则只需要将这些文件命名为scheme-*.sql(建表语句),data-*.sql(数据形式的sql文件);将建表语句的sql文件放置在resources文件夹下命名为schema-all(schema).sql,则将在程序运行时自动创建我们的建表语句:

  9.我们也可以在配置属性文件中直接指定schema:

  10.如果我们要操作数据库,SpringBoot还具有一个默认的自动配置:JdbcTemplateAutoConfiguration:自动配置了JdbcTemplate操纵数据库

三.数据库操纵演示
  自定义一个Controller实现数据查询:

 1 package com.skykuqi.springboot.datajdbc.controller;
 2 
 3 import org.springframework.beans.factory.annotation.Autowired;
 4 import org.springframework.jdbc.core.JdbcTemplate;
 5 import org.springframework.stereotype.Controller;
 6 import org.springframework.web.bind.annotation.GetMapping;
 7 import org.springframework.web.bind.annotation.ResponseBody;
 8 
 9 import java.util.List;
10 import java.util.Map;
11 
12 /**
13  * @author : S K Y
14  * @version :0.0.1
15  */
16 @Controller
17 public class HelloController {
18 
19     @Autowired
20     JdbcTemplate template;
21 
22     @ResponseBody
23     @GetMapping("/query")
24     public Map<String, Object> map() {
25         List<Map<String, Object>> list = template.queryForList("select * from department");
26         return list.get(0);
27     }
28 }

四.整合使用druid数据源
  1.引入druid:

1         <!--引入druid数据源-->
2         <dependency>
3             <groupId>com.alibaba</groupId>
4             <artifactId>druid</artifactId>
5             <version>1.1.8</version>
6         </dependency>

  2.配置druid数据源

 1 package com.skykuqi.springboot.datajdbc.condig;
 2 
 3 import com.alibaba.druid.pool.DruidDataSource;
 4 import com.alibaba.druid.support.http.StatViewServlet;
 5 import com.alibaba.druid.support.http.WebStatFilter;
 6 import org.springframework.boot.context.properties.ConfigurationProperties;
 7 import org.springframework.boot.web.servlet.FilterRegistrationBean;
 8 import org.springframework.boot.web.servlet.ServletRegistrationBean;
 9 import org.springframework.context.annotation.Bean;
10 import org.springframework.context.annotation.Configuration;
11 
12 import javax.sql.DataSource;
13 import java.util.Collections;
14 import java.util.HashMap;
15 import java.util.Map;
16 
17 /**
18  * @author : S K Y
19  * @version :0.0.1
20  */
21 @Configuration
22 public class DruidConfig {
23     @Bean
24     @ConfigurationProperties(prefix = "spring.datasource")
25     public DataSource druid() {
26         return new DruidDataSource();
27     }
28 
29     //配置Durid的监控
30     //1. 配置一个管理后台的Service
31     @Bean
32     public ServletRegistrationBean statViewServlet() {
33         ServletRegistrationBean bean = new ServletRegistrationBean(new StatViewServlet(), "/druid/*");
34         Map<String, String> initParameters = new HashMap<>();
35         //配置登录后台时的用户名
36         initParameters.put("loginUsername", "admin");
37         //配置登录后台的密码
38         initParameters.put("loginPassword", "123456");
39         //默认允许所有访问,配置只允许本地登录
40         initParameters.put("allow", "127.0.0.1");
41         //阻止该地址的访问
42         initParameters.put("deny", "192.168.1.108");
43         bean.setInitParameters(initParameters);
44         return bean;
45     }
46 
47     //2.配置一个监控的filter
48     @Bean
49     public FilterRegistrationBean webStartFilter() {
50         FilterRegistrationBean bean = new FilterRegistrationBean();
51         bean.setFilter(new WebStatFilter());
52         Map<String, String> initParameters = new HashMap<>();
53         //设置不拦截以下请求
54         initParameters.put("exclusions","*.js,*.css,/druid");
55         //设置拦截以下所有请求
56         bean.setInitParameters(initParameters);
57         bean.setUrlPatterns(Collections.singletonList("/*"));
58         return bean;
59     }
60 }
 1 spring:
 2   datasource:
 3     username: root
 4     password: 123456
 5     url: jdbc:mysql://192.168.1.108:3306/jdbc?useSSL=false
 6     driver-class-name: com.mysql.jdbc.Driver
 7     schema:
 8       - classpath:department.sql
 9     type: com.alibaba.druid.pool.DruidDataSource
10     #   数据源其他配置
11     initialSize: 5
12     minIdle: 5
13     maxActive: 20
14     maxWait: 60000
15     timeBetweenEvictionRunsMillis: 60000
16     minEvictableIdleTimeMillis: 300000
17     validationQuery: SELECT 1 FROM DUAL
18     testWhileIdle: true
19     testOnBorrow: false
20     testOnReturn: false
21     poolPreparedStatements: true
22     #   配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙
23     filters: stat,wall,log4j
24     maxPoolPreparedStatementPerConnectionSize: 20
25     useGlobalDataSourceStat: true
26     connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500

五.整合Mybatis
  1.查看POM依赖

 1     <dependencies>
 2         <dependency>
 3             <groupId>org.springframework.boot</groupId>
 4             <artifactId>spring-boot-starter-jdbc</artifactId>
 5         </dependency>
 6         <dependency>
 7             <groupId>org.springframework.boot</groupId>
 8             <artifactId>spring-boot-starter-web</artifactId>
 9         </dependency>
10         <dependency>
11             <groupId>org.mybatis.spring.boot</groupId>
12             <artifactId>mybatis-spring-boot-starter</artifactId>
13             <version>2.1.1</version>
14         </dependency>
15 
16         <dependency>
17             <groupId>mysql</groupId>
18             <artifactId>mysql-connector-java</artifactId>
19             <scope>runtime</scope>
20         </dependency>
21         <dependency>
22             <groupId>org.springframework.boot</groupId>
23             <artifactId>spring-boot-starter-test</artifactId>
24             <scope>test</scope>
25         </dependency>
26     </dependencies>

  2.配置使用Mybatis
  (1)配置数据源相关;
  (2)在数据库中建立相关数据表
  (3)创建javaBean;
  (4)使用SpringBoot整合Mybatis;

 1 package com.skykuqi.springboot.mybatis.mapper;
 2 
 3 import com.skykuqi.springboot.mybatis.entity.Department;
 4 import org.apache.ibatis.annotations.*;
 5 
 6 /**
 7  * @author : S K Y
 8  * @version :0.0.1
 9  */
10 @Mapper     //指定这是一个操作数据库的mapper
11 public interface DepartmentMapper {
12     @Select("select * from department where id=#{id}")
13     Department queryDepartmentById(Integer id);
14 
15     @Delete("delete from department where id=#{id}")
16     int deleteDepartmentById(Integer id);
17 
18     @Insert("insert into department(departmentName) values(#{departmentName}) ")
19     int insertDepartment(Department department);
20 
21     @Update("update department set departmentName=#{departmentName} where id=#{id}")
22     int updataDepartment(Department department);
23 }

 

 1 package com.skykuqi.springboot.mybatis.controller;
 2 
 3 import com.skykuqi.springboot.mybatis.entity.Department;
 4 import com.skykuqi.springboot.mybatis.mapper.DepartmentMapper;
 5 import org.springframework.beans.factory.annotation.Autowired;
 6 import org.springframework.web.bind.annotation.GetMapping;
 7 import org.springframework.web.bind.annotation.PathVariable;
 8 
 9 /**
10  * @author : S K Y
11  * @version :0.0.1
12  */
13 @org.springframework.web.bind.annotation.RestController
14 public class RestController {
15     @Autowired
16     DepartmentMapper departmentMapper;
17 
18     @GetMapping("/dept/{id}")
19     public Department getDepartment(@PathVariable("id") Integer id) {
20         return departmentMapper.queryDepartmentById(id);
21     }
22 
23     @GetMapping("/dept")
24     public Department insertDept(Department department) {
25         departmentMapper.insertDepartment(department);
26         return department;
27     }
28 }

  --实现插入语句的id值回显:

1     @Options(useGeneratedKeys = true,keyProperty = "id")
2     @Insert("insert into department(departmentName) values(#{departmentName}) ")
3     int insertDepartment(Department department);

  (5)当javaBean中的名称与数据库中的名称不一致时.例如javaBean中为departmentName,而在数据库中为department_name,在Mybatis的自动配置中存在ConfigurationCustomizer相关的配置,我们可以自定义实现该接口:

 1 package com.skykuqi.springboot.mybatis.config;
 2 
 3 import org.mybatis.spring.boot.autoconfigure.ConfigurationCustomizer;
 4 import org.springframework.context.annotation.Bean;
 5 import org.springframework.context.annotation.Configuration;
 6 
 7 /**
 8  * @author : S K Y
 9  * @version :0.0.1
10  */
11 @Configuration
12 public class MyBatisConfig {
13     @Bean
14     public ConfigurationCustomizer configurationCustomizer() {
15         return configuration -> {
16             configuration.setMapUnderscoreToCamelCase(true);        //开启驼峰命名法
17         };
18     }
19 }

  (6)可以使用@MapperScan 来配置mapper包扫描,避免过多的Mapper注解的实现

  3.使用配置文件的方式来进行Mybatis的整合
  (1)在yml配置文件中注册配置类:

  (2)在xml文件中配置启用mapUnderscoreToCamelCase

1 <?xml version="1.0" encoding="UTF-8" ?>
2 <!DOCTYPE configuration
3         PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
4         "http://mybatis.org/dtd/mybatis-3-config.dtd">
5 <configuration>
6     <settings>
7         <setting name="mapUnderscoreToCamelCase" value="true"/>
8     </settings>
9 </configuration>

  (3)编写mapper.xml

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <!DOCTYPE mapper
 3         PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 4         "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 5 <mapper namespace="com.skykuqi.springboot.mybatis.mapper.EmployeeMapper">
 6     <select id="queryEmpById" parameterType="Integer"
 7             resultType="com.skykuqi.springboot.mybatis.entity.Employee">
 8         select *
 9         from employee
10         where id = #{id}
11     </select>
12 
13     <insert id="insertEmp" parameterType="com.skykuqi.springboot.mybatis.entity.Employee">
14         insert into employee(lastName, email, gender, d_id)
15         values (#{lastName}, #{email}, #{gender}, #{d_id})
16     </insert>
17 </mapper>
posted @ 2019-12-16 22:07  灰色天空_graySky  阅读(350)  评论(0编辑  收藏  举报