SprinBootSpringData整合


目录

  • [SpringData]
  • [整合JDBC]
  • [JDBCTemplate]
  • [整合Druid]
  • [配置数据源]
  • [配置Druid数据源监控]
  • [整合MyBatis]
  • [整合测试]
  • [整合Redis]
  • [测试整合]
  • [序列化配置]
  • [自定义redisTemplate]


项目代码位置:https://gitee.com/zwtgit/employee-management-system

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

整合JDBC

1、去新建一个项目测试,引入相应的模块!基础模块 2、项目建好之后,发现自动帮们导入了如下的启动器:

<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>

3 、编写yaml配置文件连接数据库;

这个的配置才是和自己的数据库连接成功
spring:
  datasource:
    username: root
    password: 240055
        时区报错
    url: jdbc:mysql://localhost:3306/richtexteditor?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=GMT
    driver-class-name: com.mysql.jdbc.Driver

4、配置完这一些东西后,们就可以直接去使用了,因为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();
    }
}

关于这个配置的源码分析

结果:们可以看到他默认给们配置的数据源为 : class com.zaxxer.hikari.HikariDataSource ,

们并没有手动配置

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

@Import(
    {Hikari.class, Tomcat.class, Dbcp2.class, Generic.class, DataSourceJmxConfiguration.class}
)
protected static class PooledDataSourceConfiguration {
    protected PooledDataSourceConfiguration() {
    }
}

这里导入的类都在 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 指定自定义的数据源类型,值为 要使用的连接池实现的完全限定名。

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方法:用于执行存储过程、函数相关语句。

编写一个Controller,注入 jdbcTemplate,编写测试方法进行访问测试;

package com.zwt.employeemanagementsystem.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.RestController;
import java.util.List;
import java.util.Map;
@RestController
public class JDBCController {
    @Autowired
    JdbcTemplate jdbcTemplate;
    //查询数据库的所有信息
    @GetMapping("/userList")
    public List<Map<String, Object>> userlist() {
        String sql = "select * from user";
        List<Map<String, Object>> list_maps = jdbcTemplate.queryForList(sql);
        return list_maps;
    }
    @GetMapping("/addUser")
    public String addUser() {
        String sql = "insert into mybatis.user(id,name,pwd) values (9,'小明','123456')";
        jdbcTemplate.update(sql);
        return "UPDTE_OK";
    }
    //    @PathVariable("xxx")
//    通过 @PathVariable 可以将URL中占位符参数绑定到处理器类的方法形参中@PathVariable("xxx")
//
//    @RequestMapping(value="user//{name}")
//    请求路径:http://localhost:8080/hello/show5/1/james
    @GetMapping("/updateUser/")
    public String updateUser(@PathVariable("id") int id) {
        String sql = "update mybatis.user set name=?,pwd=? where id=" + id;
        //封装
        Object[] objects = new Object[2];
        objects[0] = "小明-修改";
        objects[1] = "123456";
        jdbcTemplate.update(sql, objects);
        return "update_OK";
    }
    @GetMapping("/deleteUser/")
    public String deleteUser(@PathVariable("id") int id) {
        String sql = "delete from mybatis.user where id=?";
        jdbcTemplate.update(sql, id);
        return "delete_OK";
    }
}

整合Druid

学这个主要是一般就用这么几个,都了解,免得去了公司说不会 Java程序很大一部分要操作数据库,为了提高性能操作数据库的时候,又不得不使用数据库连接池。 Druid 是阿里巴巴开源平台上一个数据库连接池实现,结合了 C3P0、DBCP 等 DB 池的优点,同时加入了日志监控。 Druid 可以很好的监控 DB 池连接和 SQL 的执行情况,天生就是针对监控而生的 DB 连接池。 Spring Boot 2.0 以上默认使用 Hikari 数据源,可以说 Hikari 与 Driud 都是当前 Java Web 上最优秀的数据源,们来重点介绍 Spring Boot 如何集成 Druid 数据源,如何实现数据库监控。 Github地址:https://github.com/alibaba/druid/

配置数据源

1、添加上 Druid 数据源依赖。 2、切换数据源;

  type: com.alibaba.druid.pool.DruidDataSource  自定义数据源

3、测试,数据源切换之后,在测试类中注入 DataSource,然后获取到它, 4、切换成功!既然切换成功,就可以设置数据源连接初始化大小、最大连接数、等待时间、最小连接数 等设置项;可以查看源码

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

5、导入Log4j 的依赖 6、现在需要程序员自己为 DruidDataSource 绑定全局配置文件中的参数,再添加到容器中,

而不再使用 Spring Boot 的自动生成了;们需要 自己添加 DruidDataSource 组件到容器中,并绑定属性;

@Configuration
public class DruidConfig {
    /*
       将自定义的 Druid数据源添加到容器中,不再让 Spring Boot 自动创建
       绑定全局配置文件中的 druid 数据源属性到 com.alibaba.druid.pool.DruidDataSource从而让它们生效
       @ConfigurationProperties(prefix = "spring.datasource"):作用就是将 全局配置文件中
       前缀为 spring.datasource的属性值注入到 com.alibaba.druid.pool.DruidDataSource 的同名参数中
     */
    @ConfigurationProperties(prefix = "spring.datasource")
    @Bean
    public DataSource druidDataSource() {
        return new DruidDataSource();
    }
}

7、去测试类中测试一下;看是否成功!

@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);
        DruidDataSource druidDataSource = (DruidDataSource) dataSource;
        System.out.println("druidDataSource 数据源最大连接数:" + druidDataSource.getMaxActive());
        System.out.println("druidDataSource 数据源初始化连接数:" + druidDataSource.getInitialSize());
        //关闭连接
        connection.close();
    }
}

配置Druid数据源监控

Druid 数据源具有监控的功能,并提供了一个 web 界面方便用户查看,类似安装 路由器 时,人家也提供了一个默认的 web 页面。

所以第一步需要设置 Druid 的后台管理页面,比如 登录账号、密码 等;配置后台管理;

//配置 Druid 监控管理后台的Servlet;
//内置 Servlet 容器时没有web.xml文件,所以使用 Spring Boot 的注册 Servlet 方式
@Bean
public ServletRegistrationBean statViewServlet() {
    ServletRegistrationBean bean = new ServletRegistrationBean(new StatViewServlet(), "/druid/*");
    // 这些参数可以在 com.alibaba.druid.support.http.StatViewServlet 
    // 的父类 com.alibaba.druid.support.http.ResourceServlet 中找到
    Map<String, String> initParams = new HashMap<>();
    initParams.put("loginUsername", "admin"); //后台管理界面的登录账号
    initParams.put("loginPassword", "123456"); //后台管理界面的登录密码
    //后台允许谁可以访问
    //initParams.put("allow", "localhost"):表示只有本机可以访问
    //initParams.put("allow", ""):为空或者为null时,表示允许所有访问
    initParams.put("allow", "");
    //deny:Druid 后台拒绝谁访问
    //initParams.put("kuangshen", "192.168.1.20");表示禁止此ip访问
    //设置初始化参数
    bean.setInitParameters(initParams);
    return bean;
}

整合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

整合测试

1、导入 MyBatis 所需要的依赖

        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.0.0</version>
        </dependency>
mybatis:
mapper-locations: classpath:com/zwt/mapper/*.xml
type-aliases-package: com.kuang.pojo

2、配置数据库连接信息(不变) ,基本数据库配置 3、测试数据库是否连接成功! 4、创建实体类,导入 Lombok! 5、创建mapper目录以及对应的 Mapper 接口 6、对应的Mapper映射文件 7、maven配置资源过滤问题 8、编写部门的 DepartmentController 进行测试!

整合Redis

项目地址:https://gitee.com/zwtgit/spring-boot-integrates-redis SpringBoot操作数据: spring-data jpa jdbc mongodb redis ! SpringData也是和SpringBoot齐名的项目!

说明:在SpringBoot2.x之后,原来使用的jedis被替换为了lettuce jedis : 采用的直连, 多个线程操作的话,是不安全的,如果想要避免不安全的 , 使用jedis pool 连接池! 更像BIO (block input output) lettuce : 采用netty , 实例可以再多个线程中进行共享,不存在线程不安全的情况 ! 可以减少线程数据了,更像NIO, java.nio全称java non-blocking IO(实际上是 new io)

源码分析

/*
 * right 2012-2020 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.springframework.boot.autoconfigure.data.redis;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnSingleCandidate;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
/**
 * {@link EnableAutoConfiguration Auto-configuration} for Spring Data's Redis support.
 *
 * @author Dave Syer
 * @author Andy Wilkinson
 * @author Christian Dupuis
 * @author Christoph Strobl
 * @author Phillip Webb
 * @author Eddú Meléndez
 * @author Stephane Nicoll
 * @author Marco Aust
 * @author Mark Paluch
 * @since 1.0.0
 */
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(RedisOperations.class)
@EnableConfigurationProperties(RedisProperties.class)
@Import({ LettuceConnectionConfiguration.class, JedisConnectionConfiguration.class })
public class RedisAutoConfiguration {
    @Bean
    @ConditionalOnMissingBean(name = "redisTemplate")
    @ConditionalOnSingleCandidate(RedisConnectionFactory.class)
    public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
        //没有过多的设置,redis的对象要序列化
        //都是object类型,所有后面要转化
        RedisTemplate<Object, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(redisConnectionFactory);
        return template;
    }
    //由于String最常用,所以提出来了
    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnSingleCandidate(RedisConnectionFactory.class)
    public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory) {
        StringRedisTemplate template = new StringRedisTemplate();
        template.setConnectionFactory(redisConnectionFactory);
        return template;
    }
}

测试整合

导入依赖

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>

application.properties配置

apring所有的配置都有自动的配置类

自动配置都会有一个properties文件
spring.redis.host=localhost
spring.redis.port=6379

测试

package com.zwt;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.RedisTemplate;
@SpringBootTest
class SpringBootIntegratesRedisApplicationTests {
    @Autowired
    private RedisTemplate redisTemplate;
    @Test
    void contextLoads() {
//        RedisConnection connection = redisTemplate.getConnectionFactory().getConnection();
//        connection.flushDb();
//        connection.flushAll();
        redisTemplate.opsForValue().set("zwt", "lijaitu");
        System.out.println(redisTemplate.opsForValue().get("zwt"));
    }
}

序列化配置

    @SuppressWarnings("rawtypes") private @Nullable RedisSerializer keySerializer = null;
    @SuppressWarnings("rawtypes") private @Nullable RedisSerializer valueSerializer = null;
    @SuppressWarnings("rawtypes") private @Nullable RedisSerializer hashKeySerializer = null;
    @SuppressWarnings("rawtypes") private @Nullable RedisSerializer hashValueSerializer = null;
        if (defaultSerializer == null) {
            //默认是jdk的序列化
            defaultSerializer = new JdkSerializationRedisSerializer(
                    classLoader != null ? classLoader : this.getClass().getClassLoader());
        }
package com.zwt.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.stereotype.Component;
import java.io.Serializable;
@Data
@AllArgsConstructor
@NoArgsConstructor
@Component
//implements Serializable,在企业中一般都会序列化
public class User implements Serializable{
    private String name;
    private int age;
}
    @Test
    @SneakyThrows
    public void test() {
        User user = new User("李嘉图", 3);
        String jsonstring = new ObjectMapper().writeValueAsString(user);
        redisTemplate.opsForValue().set("user", jsonstring);
        System.out.println(redisTemplate.opsForValue().get("user"));
    }

自定义redisTemplate

package com.zwt.config;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
@Configuration
public class RedisConfig {
    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        //配置具体的序列化
        Jackson2JsonRedisSerializer<Object> objectJackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
        template.setKeySerializer(objectJackson2JsonRedisSerializer);
        template.setConnectionFactory(redisConnectionFactory);
        return template;
    }
}

常见场景的封装

@Configuration
public class RedisConfig { 
    // 自己定义了一个 RedisTemplate
    @Bean
    @SuppressWarnings("all")
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
        // 们为了自己开发方便,一般直接使用 <String, Object>
        RedisTemplate<String, Object> template = new RedisTemplate<String, Object>();
        template.setConnectionFactory(factory);
        // Json序列化配置
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(om);
        // String 的序列化
        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
        // key采用String的序列化方式
        template.setKeySerializer(stringRedisSerializer);
        // hash的key也采用String的序列化方式
        template.setHashKeySerializer(stringRedisSerializer);
        // value序列化方式采用jackson
        template.setValueSerializer(jackson2JsonRedisSerializer);
        // hash的value序列化方式采用jackson
        template.setHashValueSerializer(jackson2JsonRedisSerializer);
        template.afterPropertiesSet();
        return template;
    }
}

原文创作:ML李嘉图

原文链接:https://www.cnblogs.com/zwtblog/p/15177501.html

文章列表

更多推荐

更多
  • spring boot 系列之三:spring boot 整合JdbcTemplate spring boot 系列之三:spring boot 整合JdbcTemplate知识改变命运,技术成就你我
  • spring boot 系列之八:SpringBoot处理定时任务 spring boot 系列之八:SpringBoot处理定时任务知识改变命运,技术成就你我一、cron表达式二、@Schedule实现三、Quartz实现1.引入依赖2.代码实现3.测试效果1.Quartz介绍2.基本使用3.spri
  • spring boot 系列之四:spring boot 整合JPA spring boot 系列之四:spring boot 整合JPA知识改变命运,技术成就你我
  • spring boot 系列之七:SpringBoot整合Mybatis spring boot 系列之七:SpringBoot整合Mybatis知识改变命运,技术成就你我1.pom配置2.application.propertis3.启动器4.db脚本5.pojo类6.mapper文件和mapper.xml
  • Java集合List,Set,Map Java集合List,Set,Map ![集合结构框架体系图](README.assets/image-20210121140002794.png) ![集合结构关系图](README.assets/image-202101211
    Java面试

  • Java集合,Map遍历 Java集合,Map遍历 ```Java /**Map 集合的遍历与 List 和 Set 集合不同。 Map 有两组值,因此遍历时可以只遍历值的集合,也可以只遍历键的集合,也可以同时遍历。 Map 以及实现 Map 的接口类(如
    Java面试

  • Java集合面试,HashMap与HashTable的区别? Java集合面试,HashMap与HashTable的区别? 1)说说常见的集合有哪些吧? 答:Map接口和Collection接口是所有集合框架的父接口: 1. Collection接口的子接口包括:Set接口和List接
    Java面试

  • 信息安全 2 密码工具箱续 [信息安全] 2.密码工具箱(续)1. 伪随机数生成器(Pseudo-Random Number Generator)2. 混合密码系统3. 证书(Certificate)- 为公钥添加数字签名4. 总结参考1.2 伪随机数的实际应用1
  • CopyOnWriteArrayList并发容器源码解析 CopyOnWriteArrayList并发容器源码解析CopyOnWriteArrayList并发List容器源码解析程序员的精进之路类结构读写线程安全的实现原理CopyOnWriteArrayList的特点CopyOnWriteAr
  • Java 修饰符 Java语言提供了很多修饰符,主要分为以下两类:访问修饰符,非访问修饰符,修饰符用来定义类、方法或者变量,通常放在语句的最前端
  • 近期文章

    更多
    文章目录

      推荐作者

      更多