• SpringBoot-数据库操作


    SpringBoot-数据库操作

    1.JDBC+HikariDataSource

    1.应用实例-需求

    ● 需求:演示 Spring Boot 如何通过 jdbc+HikariDataSource 完成对 Mysql 操作 说明: HikariDataSource : 目前市面上非常优秀的数据源, 是 springboot2 默认数据源

    2.应用实例-代码实现

    1. 创建测试数据库和表
    -- 创建 spring_boot 
    DROP DATABASE IF EXISTS spring_boot; CREATE DATABASE spring_boot; 
    USE spring_boot; 
    -- 创建家居表 
    CREATE TABLE furn( `id` INT(11) PRIMARY KEY AUTO_INCREMENT, ## id 
    `name` VARCHAR(64) NOT NULL, ## 家居名 
    `maker` VARCHAR(64) NOT NULL, ## 厂商
    `price` DECIMAL(11,2) NOT NULL, ## 价格
    `sales` INT(11) NOT NULL, ## 销量
    `stock` INT(11) NOT NULL, ## 库存
    `img_path` VARCHAR(256) NOT NULL ## 照片路径 
    );
    
    -- 初始化家居数据
    INSERT INTO furn(`id` , `name` , `maker` , `price` , `sales` , `stock` , `img_path`) VALUES(NULL , ' 北 欧 风 格 小 桌 子 ' , ' 熊 猫 家 居 ' , 180 , 666 , 7 , 'assets/images/product-image/1.jpg'); 
    INSERT INTO furn(`id` , `name` , `maker` , `price` , `sales` , `stock` , `img_path`) VALUES(NULL , ' 简 约 风 格 小 椅 子 ' , ' 熊 猫 家 居 ' , 180 , 666 , 7 , 'assets/images/product-image/2.jpg'); 
    INSERT INTO furn(`id` , `name` , `maker` , `price` , `sales` , `stock` , `img_path`) VALUES(NULL , ' 典 雅 风 格 小 台 灯 ' , ' 蚂 蚁 家 居 ' , 180 , 666 , 7 , 'assets/images/product-image/3.jpg'); 
    INSERT INTO furn(`id` , `name` , `maker` , `price` , `sales` , `stock` , `img_path`) VALUES(NULL , ' 温 馨 风 格 盆 景 架 ' , ' 蚂 蚁 家 居 ' , 180 , 666 , 7 , 'assets/images/product-image/4.jpg'); SELECT * FROM furn;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    1. 进 行 数 据 库 开 发 , 在 pom.xml 引 入 data-jdbc starter , 参 考 官 方 文 档 https://docs.spring.io/spring-boot/docs/current/reference/html/using.html#using.build-systems.starters

    image-20220814165510657

    
    <dependency>
        <groupId>org.springframework.bootgroupId>
        <artifactId>spring-boot-starter-data-jdbcartifactId>
    dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    1. Spring Boot 不知道项目要操作 Mysql 还是 Oracle , 需要在 pom.xml 指定导入数据库 驱动, 并指定对应版本.
    
    <dependency>
        <groupId>mysqlgroupId>
        <artifactId>mysql-connector-javaartifactId>
        <version>5.1.49version>
    dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    1. 在 application.yml 配置操作数据源的信息
    spring:
      datasource:
        #说明:如果没有指定useSSL=true,启动项目可能会爆红警告,环境问题
        url: jdbc:mysql://127.0.0.1:3306/spring_boot?useSSL=true&useUnicode=true&characterEncoding=UTF-8
        username: root
        password: root
        driver-class-name: com.mysql.jdbc.Driver
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    ​ 5.创建src\main\java\com\llp\springboot\bean\Furn.java

    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    public class Furn {
        private Integer id;
    
        private String name;
    
        private String maker;
    
        private BigDecimal price;
    
        private Integer sales;
    
        private Integer stock;
    
        private String imgPath = "assets/images/product-image/1.jpg";
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    3.应用实例-测试结果

    1.创建src\test\java\com\llp\springboot\ApplicationTests.java 测试类

    /**
     * 如何在springboot中开发测试类,需要引入如下的依赖
     *        
     *           org.springframework.boot
     *           spring-boot-starter-test
     *        
     */
    @SpringBootTest
    public class ApplicationTests {
    
        @Autowired
        private JdbcTemplate jdbcTemplate;
    
        @Test
        public void contextLoads() {
            BeanPropertyRowMapper<Furn> rowMapper = new BeanPropertyRowMapper(Furn.class);
            List<Furn> furns = jdbcTemplate.query("select * from furn", rowMapper);
            for (Furn furn : furns) {
                System.out.println(furn);
            }
            System.out.println(jdbcTemplate.getDataSource().getClass());
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    可以看到springBoot默认使用的是HikariDataSource 数据源

    image-20220814165845926

    2.整合 Druid 到 Spring-Boot

    1.官方文档

    1.使用手册

    https://github.com/alibaba/druid

    image-20220814170213913

    2.中文手册

    https://github.com/alibaba/druid/wiki/%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98

    2.基本介绍

    1. HiKariCP: 目前市面上非常优秀的数据源, 是 springboot2 默认数据源

    2. Druid: 性能优秀,Druid 提供性能卓越的连接池功能外【Java 基础】,还集成了 SQL 监 控,黑名单拦截等功能,强大的监控特性,通过 Druid 提供的监控功能,可以清楚知道连 接池和 SQL 的工作情况,所以根据项目需要,我们也要掌握 Druid 和 SpringBoot 整合

    3. 整合 Druid 到 Spring-Boot 方式

    ● 自定义方式

    ● 引入 starter 方式

    3.Durid 基本使用

    1.需求: 将 Spring-Boot 的数据源切换成 Druid

    2.代码实现

    1. 修改 pom.xml , 引入 druid 依赖
    
    <dependency>
       <groupId>com.alibabagroupId>
       <artifactId>druidartifactId>
       <version>1.1.17version>
    dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    2.创建src\main\java\com\llp\springboot\config\DruidDataSourceConfig.java 配置类

    @Configuration
    public class DruidDataSourceConfig {
    
        //编写方法,注入DruidDataSource
        //为什么我们注入自己的DataSource , 默认的HiKariDatasource失效?
        //1. 默认的数据源是如配置? @ConditionalOnMissingBean({ DataSource.class, XADataSource.class })
        //   解读通过@ConditionalOnMissingBean({ DataSource.class}) 判断如果容器有DataSource Bean 就不注入默认的HiKariDatasource
        @ConfigurationProperties("spring.datasource")
        @Bean
        public DataSource dataSource() {
            //1. 配置了 @ConfigurationProperties("spring.datasource")
            //   就可以读取到application.yml的配置,注意:我们需要将bean注入到spring ioc容器中、bean中提供get\set方法
            //2. 我们就不需要调用DruidDataSource 对象的setXxx, 会自动关联
    
            DruidDataSource druidDataSource = new DruidDataSource();
            //druidDataSource.setUrl();
            //druidDataSource.setUsername();
            //druidDataSource.setPassword();
            return druidDataSource;
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    1. 完成测试,运行 ApplicationTests.java , 观察数据源的运行类型

    image-20220814181728551

    4.Durid 监控功能-SQL 监控

    1.需求: 配置 Druid 的监控功能,包括 SQL 监控、SQL 防火墙、Web 应用、Session 监控等

    在配置监控功能之前,我们先来看看如何配置 Druid 的监控页面

      
    <servlet>  
        <servlet-name>DruidStatViewservlet-name>  
        <servlet-class>com.alibaba.druid.support.http.StatViewServletservlet-class>  
        <init-param>  
    	  
    	<param-name>resetEnableparam-name>  
    	<param-value>trueparam-value>  
        init-param>  
        <init-param>  
    	  
    	<param-name>loginUsernameparam-name>  
    	<param-value>druidparam-value>  
        init-param>  
        <init-param>  
    	  
    	<param-name>loginPasswordparam-name>  
    	<param-value>druidparam-value>  
        init-param>  
    servlet>  
    <servlet-mapping>  
        <servlet-name>DruidStatViewservlet-name>  
        <url-pattern>/druid/*url-pattern>  
    servlet-mapping>  
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    image-20220814183739265

    1.在springBoot项目中,我们需要将StatViewServlet注入到容器中并配置登录的用户名和密码等信息

    /**
     * 
     * 
     *     DruidStatView
     *     com.alibaba.druid.support.http.StatViewServlet
     *     
     *     
     *     resetEnable
     *     true
     *     
     *     
     *     
     *     loginUsername
     *     druid
     *     
     *     
     *     
     *     loginPassword
     *     druid
     *     
     * 
     * 
     *     DruidStatView
     *     /druid/*
     * 
     * @return
     */
    @Bean
    public ServletRegistrationBean registrationBean(){
        StatViewServlet statViewServlet = new StatViewServlet();
        //配置监控页面的访问路径
        ServletRegistrationBean registrationBean = new ServletRegistrationBean(statViewServlet, "/druid/*");
        //配置登录用户名和密码,结合上面这段 init-param即配置servlet的初始化参数,key和其保持一致,value值我们可以自行定义
        registrationBean.addInitParameter("loginUsername","llp");
        registrationBean.addInitParameter("loginPassword","123");
        return registrationBean;
    }
    
    • 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

    2.启动完成测试http://localhost:8080/druid/login.html,我这里配置了拦截器匹配规则是/**,但是访问druid的监控是走的servlet不会走拦截器,因此可以直接访问

    image-20220814184402415

    image-20220814184531350

    image-20220814184542828

    2.SQL 监控数据

    https://github.com/alibaba/druid/wiki/%E9%85%8D%E7%BD%AE_StatFilter

    image-20220814191838045

    1.那么如何在springboot项目中配置druid的sql监控功能呢,从上面可以看到我们需要在注入druidDataSource数据源对象的地方添加一个属性 druidDataSource.setFilters("stat");

    @ConfigurationProperties("spring.datasource")
    @Bean
    public DataSource dataSource() throws SQLException {
        //1. 配置了 @ConfigurationProperties("spring.datasource")
        //   就可以读取到application.yml的配置,注意:我们需要将bean注入到spring ioc容器中、bean中提供get\set方法
        //2. 我们就不需要调用DruidDataSource 对象的setXxx, 会自动关联
    
        DruidDataSource druidDataSource = new DruidDataSource();
    
        //配置sql监控
        druidDataSource.setFilters("stat");
        return druidDataSource;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    2.模拟操作 DB 的请求

    @Controller
    @RequiredArgsConstructor
    public class DruidSqlController {
    
        private final JdbcTemplate jdbcTemplate;
    
        @ResponseBody
        @GetMapping("/sql")
        public List<Furn> getFurnList(){
            BeanPropertyRowMapper<Furn> furnBeanPropertyRowMapper = new BeanPropertyRowMapper<>(Furn.class);
            List<Furn> furnList = jdbcTemplate.query("select * from furn", furnBeanPropertyRowMapper);
            System.out.println(furnList);
            return furnList;
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    3.我们来看下sql监控的效果

    image-20220814192722457

    image-20220814192946889

    5.Durid 监控功能-Web 关联监控

    1.需求: 配置 Web 关联监控配置:Web 应用、URI 监控

    2.官方文档

    https://github.com/alibaba/druid/wiki/%E9%85%8D%E7%BD%AE_%E9%85%8D%E7%BD%AEWebStatFilter

    image-20220814194521364

    image-20220814194532601

    3.Web 关联监控配置-Web 应用、URI 监控

    1.修改src\main\java\com\llp\springboot\config\DruidDataSourceConfig.java

    /**
     * 配置druid的web应用和url监控功能
     * 
     *     DruidWebStatFilter
     *     com.alibaba.druid.support.http.WebStatFilter
     *     
     *        exclusions
     *        *.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*
     *     
     *   
     *   
     *     DruidWebStatFilter
     *     /*
     *   
     */
    @Bean
    public FilterRegistrationBean webStatFilter(){
        WebStatFilter webStatFilter = new WebStatFilter();
        FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(webStatFilter);
        filterRegistrationBean.addInitParameter("exclusions","*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*");
        filterRegistrationBean.setUrlPatterns(Arrays.asList("/*"));
        return filterRegistrationBean;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    1. 为了测试方便,将拦截器放行 /sql 请求
    @Configuration
    public class WebConfig implements WebMvcConfigurer {
    
        @Override
        public void addInterceptors(InterceptorRegistry registry) {
            /**
             * 1.拦截器会先拦截controller的路径映射
             * 2.如果找不到则去静态资源下查找
             * 3.这里配置/**会拦截所有的请求,包括静态资源
             * 4.这里不拦截静态资源,为什么直接写成 "/images/**","/css/**" ?
             * 5.在SpringBoot中引入了spring-boot-starter-web 依赖,每个starter都会对于的自动装配
             * 6.在WebProperties中配置了类路径映射,因此可以直接省略/static/
             * private static final String[] CLASSPATH_RESOURCE_LOCATIONS = { "classpath:/META-INF/resources/",
             *              "classpath:/resources/", "classpath:/static/", "classpath:/public/" };
             *
             */
            registry.addInterceptor(new LoginInterceptor()).addPathPatterns("/**").excludePathPatterns("/","/login","/upload.html","/upload","/images/**","/css/**","/sql");
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    3.重启项目,看看 Web 应用和 URI 监控页面

    image-20220814195336374

    image-20220814195517371

    6.Durid 监控功能-SQL 防火墙

    1.需求: 配置 SQL 防火墙

    2.官方文档

    https://github.com/alibaba/druid/wiki/%E9%85%8D%E7%BD%AE-wallfilter

    image-20220814200409860

    1.修改src\main\java\com\llp\springboot\config\DruidDataSourceConfig.java

    @ConfigurationProperties("spring.datasource")
    @Bean
    public DataSource dataSource() throws SQLException {
        //1. 配置了 @ConfigurationProperties("spring.datasource")
        //   就可以读取到application.yml的配置,注意:我们需要将bean注入到spring ioc容器中、bean中提供get\set方法
        //2. 我们就不需要调用DruidDataSource 对象的setXxx, 会自动关联
    
        DruidDataSource druidDataSource = new DruidDataSource();
    
        //stat:配置sql监控, wall:配置druid sql防火墙
        druidDataSource.setFilters("stat,wall");
        return druidDataSource;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    2.完成测试,重启项目,看看 SQL 防火墙监控是否生效

    image-20220814200459289

    7.Durid 监控功能-Session 监控

    注意:Durid 的Session 监控的是用户的系统不是druid的后台系统

    1.需求: 配置 Session 监控

    2.官方文档

    https://github.com/alibaba/druid/wiki/%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98

    image-20220814201000879

    image-20220814201011954

    3.Session 监控

    1. 重启项目, 先登录管理系统

    image-20220814201056283

    1. 完成测试, 查看监控页需要输入用户名和密码, 点击 Session 监控,可以看到相关信息 (注意要登录用户系统,才能看到 Session 监控信息)

    image-20220814200859472

    8.Druid Spring Boot Starter

    1.基本介绍

    1. 前面我们使用的是自己引入 druid+配置类方式整合 Druid 和监控
    2. Druid Spring Boot Starter 可以让程序员在 Spring Boot 项目中更加轻松集成 Druid 和监控
    3. 每个starter都对应一个自动配置类,这里其实也是根据DruidStatProperties类的属性去匹配@ConfigurationProperties("spring.datasource.druid")

    image-20220814204057196

    2.应用实例

    1.需求: 使用 Druid Spring Boot Starter 方式完成 Druid 集成和监控
    2.具体实现
    1. 修改 pom.xml 注销 druid 的依赖

    image-20220814201547876

    1. 注销src\main\java\com\llp\springboot\config\DruidDataSourceConfig.java

    image-20220814201636183

    3.这样我们之前配置的druid就失效了

    1. 查看 druid 文档 https://github.com/alibaba/druid,引入 druid starter
    
    <dependency>
       <groupId>com.alibabagroupId>
       <artifactId>druid-spring-boot-starterartifactId>
       <version>1.1.17version>
    dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    image-20220814201920057

    image-20220814201928436

    1. 确认 druid starter 引入哪些依赖

    image-20220814202353676

    1. 修改 resources/application.yml 增加配置参数
    spring:
      datasource:
        #说明:如果没有指定useSSL=true,启动项目可能会爆红警告,环境问题
        url: jdbc:mysql://127.0.0.1:3306/spring_boot?useSSL=true&useUnicode=true&characterEncoding=UTF-8
        username: root
        password: root
        driver-class-name: com.mysql.jdbc.Driver
        druid:
          #配置druid和监控功能
          stat-view-servlet:
            enabled: true
            login-username: llp
            login-password: 123
            reset-enable: false
            #配置web监控
          web-stat-filter:
            enabled: true
            #配置路径,如果没有设置默认为/*
            url-pattern: /*
            exclusions: "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*"
          filter:
            #配置sql监控
            stat:
              #1000毫秒及以上就是满慢sql
              slow-sql-millis: 1000
              #启用慢查询log日志
              log-slow-sql: true
              enabled: true
              #配置sql防火墙
            wall:
              #启用
              enabled: true
              config:
                #不允许删除表的sql操作
                drop-table-allow: false
                #不孕执行select *的sql执行
                select-all-column-allow: false
    
    • 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

    image-20220814203701345

    image-20220814203921222

    7.删除德鲁伊广告配置,新增配置类如下

    /**
     * 去除druid底部的广告配置类
     */
    @Configuration
    @ConditionalOnWebApplication
    @AutoConfigureAfter(DruidDataSourceAutoConfigure.class)
    @ConditionalOnProperty(name = "spring.datasource.druid.stat-view-servlet.enabled", havingValue = "true", matchIfMissing = true)
    public class RemoveDruidOtherConfig {
    
    
        /**
         * 方法描述:  除去页面底部的广告
         */
        @Bean
        public FilterRegistrationBean removeDruidAdFilterBean(DruidStatProperties properties) {
            final String filePath = "support/http/resources/js/common.js";
            
            // 获取web监控页面的参数
            DruidStatProperties.StatViewServlet config = properties.getStatViewServlet();
            // 提取common.js的配置路径
            String pattern = config.getUrlPattern() != null ? config.getUrlPattern() : "/druid/*";
            String jsPattern = pattern.replaceAll("\\*", "js/common.js");
    
            //创建filter进行过滤
            Filter filter = new Filter() {
                @Override
                public void init(FilterConfig filterConfig) throws ServletException {
                }
    
                @Override
                public void doFilter(ServletRequest req, ServletResponse rep, FilterChain chain) throws IOException, ServletException {
                    chain.doFilter(req, rep);
                    // 重置缓冲区,响应头不会被重置
                    rep.resetBuffer();
                    // 获取common.js
                    String text = Utils.readFromResource(filePath);
                    // 正则替换, 除去底部的广告信息
                    text = text.replaceAll("
    "
    , ""); text = text.replaceAll("powered.*?shrek.wang", ""); rep.getWriter().write(text); } @Override public void destroy() { } }; FilterRegistrationBean registrationBean = new FilterRegistrationBean(); registrationBean.setFilter(filter); registrationBean.addUrlPatterns(jsPattern); return registrationBean; } }
    • 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
  • 相关阅读:
    21.10 Python 使用CRC32校验文件
    PyTorch深度学习快速入门
    centos使用root用户登录
    解决MacOS 报错提示 zsh: command not found: wget
    PaddleSeg数据集的准备
    34k*16 薪,3年自动化测试历经3轮面试成功拿下字节Offer....
    边缘计算:基于tflite实现andriod边缘端回归预测推理实战
    数据库、数据中台、数据仓库、数据湖区别
    【Python性能优化实例】计算 numpy 数组首尾为 0 的数量
    英语——分享篇——每日100词——401-500
  • 原文地址:https://blog.csdn.net/qq_44981526/article/details/126336010