Springboot+mybatis+druid的整合

2023-11-03

最近的公司项目后端用到了Springboot框架,把阿里的druid作为数据源,采用mybatis+druid的方式,本人之前也是在这里踩了很多坑,因此感觉有必要出个博客来记录一下。

首先,用druid最为数据源的好处就不多说了,灵活动态切换数据库是小case,更重要的是提供了健全的数据库监控机制和页面(号称目前最好的数据库连接池可不是简单说说),开始进入正题。

首先创建Springboot项目,这里就不多说了,可以点击这里看怎么创建Springboot项目,接着,在pom文件中引入mybatis、mysql和druid所需要的依赖,如下

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.20</version>
 </dependency>
 <dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>1.2.1</version>
 </dependency>
 <dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid-spring-boot-starter</artifactId>
    <version>1.1.9</version>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-jdbc</artifactId>
 </dependency>

然后再在项目中分别创建model,dao,service,controller,这里就不多说了,各位应该都会,创建好后如下

需要注意的是,dao要写成接口形式,并且注解为@Mapper

@Mapper
public interface SysUserDao {

    public SysUser getUserById(String id);

}

service和controller的注解还是和原来的一样,service用@Service,controller用@RestController,接着就是编写Mapper.xml配置文件,可以不写mapper.xml配置文件直接在dao上写sql语句,实现零配置模式,但是个人不建议,毕竟实体类还是简单点好。mapper配置文件如下

<?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.azhe.mybsql.dao.SysUserDao" >
  <resultMap id="BaseResultMap" type="com.azhe.mybsql.model.SysUser" >
    <id column="ID" property="id" jdbcType="VARCHAR" />
    <result column="USER_NAME" property="userName" jdbcType="VARCHAR" />
    <result column="PASSWORD" property="password" jdbcType="VARCHAR" />
  </resultMap>
  <select id="getUserById" parameterType="java.lang.String" resultMap="BaseResultMap">
    select * from sys_user where id = #{id, jdbcType=VARCHAR}
  </select>

</mapper>

其中的查询语句  ( <select id="getUserById‘’ ......) id必须和dao的方法名一致,并且指定的参数类型和返回类型也要一致,才能映射成功。

配置文件放置于resource路径下即可,本人就放在这个位置

然后在applicatin.yml中配置数据mapper文件的位置

mybatis:
  mapper-locations: classpath:mybatis/*.xml

然后再在配置文件中编写数据源和设置数据库连接池

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/shc-accounts?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
    username: root
    password: 1003
    driver-class-name: com.mysql.jdbc.Driver
    platform: mysql
    # 使用druid数据源
    type: com.alibaba.druid.pool.DruidDataSource
    # 初始化连接池大小
    initialSize: 10
    # 连接池最少
    minIdle: 3
    # 连接池最多
    maxActive: 20
    # 获取连接等待超时
    maxWait: 60000
    # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
    timeBetweenEvictionRunsMillis: 60000
    # 配置一个连接在池中最小生存的时间,单位是毫秒
    minEvictableIdleTimeMillis: 30000
    validationQuery: select 'x'
    testWhileIdle: true
    testOnBorrow: false
    testOnReturn: false
    # 打开PSCache,并且指定每个连接上PSCache的大小
    poolPreparedStatements: true
    maxPoolPreparedStatementPerConnectionSize: 20
    # 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙
    filters: stat,wall,slf4j
    # 通过connectProperties属性来打开mergeSql功能;慢SQL记录
    connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
    # 合并多个DruidDataSource的监控数据
    useGlobalDataSourceStat: true

其中的commun_forum是事先已经创建好的数据库,这里建议大家在配置数据库url时,后边加上 ?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC ,否则有可能会报错,一直循环的连接失败、连接失败,具体原因下次有机会再说。

最后在项目中加上druid的管理配置文件,用java文件作为配置文件即可,如下

package com.azhe.config;

import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.support.http.StatViewServlet;
import com.alibaba.druid.support.http.WebStatFilter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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 org.springframework.context.annotation.Primary;

import javax.sql.DataSource;
import java.sql.SQLException;

/**
 * Linzr
 */
@Configuration
public class DruidConfiguration {

    private static final Logger logger = LoggerFactory.getLogger(DruidConfiguration.class);

    private static final String DB_PREFIX = "spring.datasource";

    @Bean
    public ServletRegistrationBean druidServlet() {
        logger.info("init Druid Servlet Configuration ");
        ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(new StatViewServlet(), "/druid/*");
        // IP白名单
        servletRegistrationBean.addInitParameter("allow", "192.168.2.25,127.0.0.1");
        // IP黑名单(共同存在时,deny优先于allow)
        servletRegistrationBean.addInitParameter("deny", "192.168.1.100");
        //控制台管理用户
        servletRegistrationBean.addInitParameter("loginUsername", "admin");
        servletRegistrationBean.addInitParameter("loginPassword", "5555");
        //是否能够重置数据 禁用HTML页面上的“Reset All”功能
        servletRegistrationBean.addInitParameter("resetEnable", "false");
        return servletRegistrationBean;
    }

    @Bean
    public FilterRegistrationBean filterRegistrationBean() {
        FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(new WebStatFilter());
        filterRegistrationBean.addUrlPatterns("/*");
        filterRegistrationBean.addInitParameter("exclusions", "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*");
        return filterRegistrationBean;
    }

    //解决 spring.datasource.filters=stat,wall,log4j 无法正常注册进去
    @ConfigurationProperties(prefix = DB_PREFIX)
    class IDataSourceProperties {
        private String url;
        private String username;
        private String password;
        private String driverClassName;
        private int initialSize;
        private int minIdle;
        private int maxActive;
        private int maxWait;
        private int timeBetweenEvictionRunsMillis;
        private int minEvictableIdleTimeMillis;
        private String validationQuery;
        private boolean testWhileIdle;
        private boolean testOnBorrow;
        private boolean testOnReturn;
        private boolean poolPreparedStatements;
        private int maxPoolPreparedStatementPerConnectionSize;
        private String filters;
        private String connectionProperties;

        @Bean     //声明其为Bean实例
        @Primary  //在同样的DataSource中,首先使用被标注的DataSource
        public DataSource dataSource() {
            DruidDataSource datasource = new DruidDataSource();
            datasource.setUrl(url);
            datasource.setUsername(username);
            datasource.setPassword(password);
            datasource.setDriverClassName(driverClassName);

            //configuration
            datasource.setInitialSize(initialSize);
            datasource.setMinIdle(minIdle);
            datasource.setMaxActive(maxActive);
            datasource.setMaxWait(maxWait);
            datasource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
            datasource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
            datasource.setValidationQuery(validationQuery);
            datasource.setTestWhileIdle(testWhileIdle);
            datasource.setTestOnBorrow(testOnBorrow);
            datasource.setTestOnReturn(testOnReturn);
            datasource.setPoolPreparedStatements(poolPreparedStatements);
            datasource.setMaxPoolPreparedStatementPerConnectionSize(maxPoolPreparedStatementPerConnectionSize);
            try {
                datasource.setFilters(filters);
            } catch (SQLException e) {
                System.err.println("druid configuration initialization filter: " + e);
            }
            datasource.setConnectionProperties(connectionProperties);
            return datasource;
        }

        public String getUrl() {
            return url;
        }

        public void setUrl(String url) {
            this.url = url;
        }

        public String getUsername() {
            return username;
        }

        public void setUsername(String username) {
            this.username = username;
        }

        public String getPassword() {
            return password;
        }

        public void setPassword(String password) {
            this.password = password;
        }

        public String getDriverClassName() {
            return driverClassName;
        }

        public void setDriverClassName(String driverClassName) {
            this.driverClassName = driverClassName;
        }

        public int getInitialSize() {
            return initialSize;
        }

        public void setInitialSize(int initialSize) {
            this.initialSize = initialSize;
        }

        public int getMinIdle() {
            return minIdle;
        }

        public void setMinIdle(int minIdle) {
            this.minIdle = minIdle;
        }

        public int getMaxActive() {
            return maxActive;
        }

        public void setMaxActive(int maxActive) {
            this.maxActive = maxActive;
        }

        public int getMaxWait() {
            return maxWait;
        }

        public void setMaxWait(int maxWait) {
            this.maxWait = maxWait;
        }

        public int getTimeBetweenEvictionRunsMillis() {
            return timeBetweenEvictionRunsMillis;
        }

        public void setTimeBetweenEvictionRunsMillis(int timeBetweenEvictionRunsMillis) {
            this.timeBetweenEvictionRunsMillis = timeBetweenEvictionRunsMillis;
        }

        public int getMinEvictableIdleTimeMillis() {
            return minEvictableIdleTimeMillis;
        }

        public void setMinEvictableIdleTimeMillis(int minEvictableIdleTimeMillis) {
            this.minEvictableIdleTimeMillis = minEvictableIdleTimeMillis;
        }

        public String getValidationQuery() {
            return validationQuery;
        }

        public void setValidationQuery(String validationQuery) {
            this.validationQuery = validationQuery;
        }

        public boolean isTestWhileIdle() {
            return testWhileIdle;
        }

        public void setTestWhileIdle(boolean testWhileIdle) {
            this.testWhileIdle = testWhileIdle;
        }

        public boolean isTestOnBorrow() {
            return testOnBorrow;
        }

        public void setTestOnBorrow(boolean testOnBorrow) {
            this.testOnBorrow = testOnBorrow;
        }

        public boolean isTestOnReturn() {
            return testOnReturn;
        }

        public void setTestOnReturn(boolean testOnReturn) {
            this.testOnReturn = testOnReturn;
        }

        public boolean isPoolPreparedStatements() {
            return poolPreparedStatements;
        }

        public void setPoolPreparedStatements(boolean poolPreparedStatements) {
            this.poolPreparedStatements = poolPreparedStatements;
        }

        public int getMaxPoolPreparedStatementPerConnectionSize() {
            return maxPoolPreparedStatementPerConnectionSize;
        }

        public void setMaxPoolPreparedStatementPerConnectionSize(int maxPoolPreparedStatementPerConnectionSize) {
            this.maxPoolPreparedStatementPerConnectionSize = maxPoolPreparedStatementPerConnectionSize;
        }

        public String getFilters() {
            return filters;
        }

        public void setFilters(String filters) {
            this.filters = filters;
        }

        public String getConnectionProperties() {
            return connectionProperties;
        }

        public void setConnectionProperties(String connectionProperties) {
            this.connectionProperties = connectionProperties;
        }
    }

}

这里要注意的是,要加上@Bean注解,Spring启动时候才会进行初始化并进行管理,然后就好了,整体的目录大概这样

接着,启动项目,也就是执行Applicatin.java中的main方法,启动成功后,和平时一样打开浏览器输入controller的映射地址去访问即可得到数据

然后将controller所映射的那段地址段换成druid,继续访问druid做带来的访问监控页面

然后输入账号密码,也就是前边的druid配置文件 DruidConfiguration  中所指定的账号密码

servletRegistrationBean.addInitParameter("loginUsername", "admin");
servletRegistrationBean.addInitParameter("loginPassword", "5555");

输入即可登录

至此,整合完毕

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Springboot+mybatis+druid的整合 的相关文章

  • 概念基础:恶意软件混淆的方法

    2020 05 20 看了一些网站的内容 发现主要存在四种方式 xor 加壳 base64编码 rot13 arm的一个指令 1 2 分别是简答介绍了这集中方式 3 是一个实验室的工具 可以取出一些混淆的字符串 但是只支持pe格式 在原理方
  • Android和iOS 测试五个最好的开源自动化工具

    本文主要介绍Android和iOS 五个最好的开源自动化工具 这里整理了相关资料 希望能帮助测试软件的朋友 有需要的看下 自动化测试在产品测试上有着非常重要的作用 实现测试自动化有多种积极的方式 包括最大限度地减少测试执行时间 在关键的发布
  • 相约久久网 -- 有很多东西值得学习

    http www meet99 com 转载于 https www cnblogs com yqskj archive 2012 10 07 2714622 html
  • flutter 怎么实现app整体灰度

    今天举国哀悼 进入各种大厂的app也可以看到主色都变成灰色的了 作为程序员我们肯定会想怎么可以实现的 我简单研究了10分钟 flutter中只要在整体外面套一个ShaderMask 然后修改blendMode即可 核心代码 class My
  • CentOS7目录结构详细版

    原文地址 http www cnblogs com ellisonDon archive 2012 10 03 2710730 html 原文地址 https www cnblogs com ellisonDon archive 2012
  • SpringBoot集成ShardingJDBC系列【2】—— 基于yaml基本配置

    文章只负责讲解sharding的相关配置 springboot其他的配置自己解决 文章内容将分开发布 便于平时查阅 基于yaml基本配置 在application yml配置文件中对mybatis plus做简单的配置 这里不对Mybati
  • Flutter设置Container的高度随ListView或者GridView

    在做移动端的时候 很多时候会需要下图所示的需求 如图1美团外卖首页的一部分 先进行需求分析 这个模块可以设计成Container包含GridView GridView中子内容个数由后台数据控制 但是在直接写Container包含GridVi
  • 第130篇 在 OpenSea 上创建自己的 NFT 商店(2)

    本文介绍一种通过自己部署智能合约 在 OpenSea 上创建自己的 NFT 商店的方法 1 ERC721合约 写一个最简单的标准 ERC721 合约 源码 SPDX License Identifier MIT pragma solidit
  • java 简介

    java 简介 1991 年Sun公司的James Gosling 詹姆斯 高斯林 等人开始开发名称为 Oak 的语言 希望用于控制嵌入在有线电视交换盒 PDA等的微处理器 1994年将Oak语言更名为Java 1 java体系结构 j2s
  • C语言笔记 指针 数组

    C语言中 指针做函数参数传递二维数组有两种基本方法 1 传递 数组指针 include
  • Openstack常用命令

    目录 一 创建用户 二 创建删除模板和模板其他操作 三 创建更新删除镜像 四 创建网络 五 VPN的使用 六 创建容器swift模块 前言 在linux中使用openstakc命令前 需要source etc keystone admin
  • 设计模式在开源框架中的应用

    设计模式不是虚的 实实在在出现在很多开源框架中 比如spring tomcat等等 现在这篇文章是一个阅读合集 整理了设计模式在开源框架中的应用 后续会逐渐补充 1 tomcat中设计模式的使用 Tomcat 系统架构与设计模式 第 2 部
  • 最大期望值(EM算法)学习

    20201008 0 引言 提示 本篇文章并没有详细的说明EM算法数学推导 虽然前面通过GMM的例子能够明白大致的思想 但是在底层数学推导部分没有非常完整说明 后续有时间可能会继续添加 如果想知道数学原理的读者 就不要浪费时间再看这篇文章了
  • TCP/IP学习笔记-PPPoE协议

    写在前面 仅供学习使用 PPPoE协议概述 PPPoE是一种把PPP帧封装到以太网帧的链路层协议 所以抓包的时候抓的是以太网协议 PPPoE利用以太网将大量主机组网 不仅具有以太网快速简便的特点还有PPP强大的功能 任何能被PPP封装的协议
  • OLED拼接屏生产流程全解析:关键步骤、注意事项和技术趋势

    OLED拼接屏作为现代商业展示 会议室和指导系统中的重要组成部分 其高亮度 高对比度和逼真的色彩效果备受推崇 然而 要实现一块完美无缝的OLED拼接屏并非易事 本文将深入探讨OLED拼接屏的生产过程 包括关键步骤 注意事项以及当前的技术趋势
  • Spring Cloud Gateway 远程代码执行漏洞(CVE-2022-22947)

    一 漏洞描述 Spring Cloud Gateway 是基于 Spring Framework 和 Spring Boot 构建的网关 它旨在为微服务架构提供一种简单 有效 统一的 API 路由管理方式 3月1日 VMware发布安全公告
  • Linux三剑客(grep、sed、awk)

    Linux三剑客指的是grep sed awk 其中grep擅长查找功能 sed擅长取行和替换 awk擅长取列 一 grep grep作用是筛选 查询 文本搜索工具 根据用户指定的 模式 pattern 对目标文本进行过滤 显示被模式匹配到
  • bp神经网络算法matlab程序,bp神经网络的matlab实现

    MATLAB中BP神经网络的训练算法具体是怎么样的 先用newff函数建立网络 再用train函数训练即可 1 正向传播 输入样本 gt 输入层 gt 各隐层 处理 gt 输出层注1 若输出层实际输出与期望输出 教师信号 不符 则转入2 误
  • MATLAB批量重命名存储数据

    目录 文件查找 文件移动和改名 所调用函数功能 文件查找 首先确定数据存储的文件夹地址 记为folder dir 如果该文件夹不存在需要访问的子文件夹 则直接复制文件地址 如果存在需要访问的子文件夹 则要利用dir函数进行寻找 将子文件夹信
  • Content-Type

    要学习content type 必须事先知道它到底是什么 是干什么用的 HTTP协议 RFC2616 采用了请求 响应模型 客户端向服务器发送一个请求 请求头包含请求的方法 URI 协议版本 以及包含请求修饰符 客户 信息和内容的类似于MI

随机推荐

  • SQL综合案例之电商漏斗转化分析,pv,uv及

    漏斗模型示例 不同的业务场景有不同的业务路径 有先后顺序 事件可以出现多次 注册转化漏斗 启动APP gt APP注册页面 gt 注册结果 gt 提交订单 gt 支付成功 搜购转化漏斗 搜索商品 gt 点击商品 gt 加入购物车 gt 提交
  • 什么是UTXO

    比特币UTXO是比特币网络中的一个重要概念 它是比特币交易的基础 也是比特币的账户系统 本文将从UTXO的定义 使用方式 优点和缺点等多个方面详细介绍比特币UTXO 一 UTXO的定义 UTXO Unspent Transaction Ou
  • 超详细用profile工具分析sql语句执行及status说明

    超详细用profile工具分析sql语句执行及status说明 介绍 sql执行慢的原因有可能很多种 怎么定位呢 可以用Query Profile人工具 通过该工具可以获取一条Query 在整个执行过程中多种资源的消耗情况 如 CPU IO
  • 如何防止服务器数据轻易泄露

    如今 对于中小企业和个人用户来说 在考虑到服务器的性能与安全成本的基础上 应该如何保护自己的服务器数据呢 1 提高服务器的容错能力 容错能力指的是 当服务器出现磁盘阵列错误 发现其中一组数据出错 服务器可以自动通过其他磁盘来纠正错误 恢复到
  • deep learning编程作业总结3---一步步搭建多层神经网络及应用

    本周的主要学习了如何搭建一个多层神经网络 涉及较多的理论知识 因此本编博客将对自己所学的有关神经的知识做一个总结 图1展示的是具有4个隐藏层的神经网络结构 它的输入由x1 x2 x3构成 表示样本X具有三个特征 随后进入第一个隐藏层 该层分
  • python财务报表预测股票价格_建模股票价格数据并进行预测(统计信号模型):随机信号AR模型+Yule-Walker方程_Python...

    1 背景 针对股票市场中AR 模型的识别 建立和估计问题 利用AR 模型算法对股票价格进行预测 2 模型选取 股票的价格可视为随机信号 将此随机信号建模为 一个白噪声通过LTI系统的输出 通过原始数据求解 所建模型参数 得到模型 即可预测近
  • 华为od业务主管面试问题-我的回答

    目录 1 怎么处理项目上的需求 2 业余会不会学什么东西 3 你对加班的看法 4 你对OD的看法 5 哪里人 6 后续的发展 7 你对华为的认识 对当前岗位的了解 1 怎么处理项目上的需求 gt 项目经理和产品经理进行需求对接 gt 项目经
  • vant-list + toast分页加载,数据加载后会滚动至顶部

    vant list toast分页加载 数据加载后会滚动至顶部 主要原因是 toast组件在全局添加了 pointer event none 解决办法 在对应的van list的属性值添加 pointer event volunteer l
  • QT控件之(TableView)的居中效果

    T将tableView中的表头以及文本内容都进行居中处理 1 需要在构造函数中增加一句 以下增加的是表头的效果 ui gt tableView gt horizontalHeader gt setSectionResizeMode QHea
  • SQL注入之布尔盲注

    布尔盲注 如果确定页面注入点存在 如果页面没有回显并且没有报错信息可以考虑使用布尔盲注 布尔盲注的判断条件是页面布尔类型状态 当传递参数 id 1 and 1 1 这里以sqlilab的闯关为例 当传递参数 id 1 and 1 2 比较两
  • MyBatis学习(三):解析MyBatis的SQL映射XML文件写法和使用原理

    上面的两篇文章 分别是MyBatis的入门小程序和MyBatis的配置XML解析 有需要的可以先去看看这两篇文章 本篇文章 会来讲解SQL映射XML文件的写法以及如何使用 MyBatis真正的力量在于其映射语句 这里应该是奇迹发生的地方 S
  • Vue传参出现 Required String parameter 'username' is not present

    场景描述 在 使用axios 发送HTTP请求时 传递了后端指定的请求参数 但是后端报错 描述信息为 Required String parameter username is not present 分析问题 开始找原因 确定前端传递的参
  • jsp页面整合ECharts绘制图表(以折线图为例)

    文章目录 jsp页面整合ECharts绘制折线图 先看效果图 前端代码 后端测试代码 jsp页面整合ECharts绘制折线图 官网 https echarts apache org zh index html 官网上有demo可以直接调试样
  • 2021-06-15 好用的STF-Git项目

    好用的STF Git项目 1 基于openstf二次开发的群控管理平台 快速开始 Mac Linux centos 相关工具 测试使用版本 2 deploy stf docker 在Ubuntu上使用一键操作部署STF主服务器的脚本 1 基
  • Pyecharts——Python高级可视化

    Pyecharts是百度开源的移植到Python上的可视化工具 里面方法调用起来像是标记性语言 因此代码的可读性很强 一目了然 下面是一个绘制散点图的例子 import pyecharts options as opts from pyec
  • 出现 DeprecationWarning: BICUBIC is deprecated and will be removed in Pillow 10 的解决方法

    目录 1 问题所示 2 原理分析 3 解决方法 1 问题所示 使用plt代码模块的时候 问题如下 home kkjz anaconda3 envs py17 lib python3 7 site packages ipykernel lau
  • 强推,黑白照片一步完美上色,Picture Colorizer Pro Mac版

    今天在国外一个网站偶尔发现一个超棒的软件Picture Colorizer Pro专业版 黑白照片或老旧照片自动上色 心动不如行动 马上下载上手使用 效果超棒 它的强在在于色彩还原非常真实 有老照片的胶片感 边缘过度很精细 没有粗糙的感觉
  • 在C++中如何使用httpClient,用Newtonsoft解析JSON

    现在C 也不行了吗 网上找不到相关代码 为了搞清楚C 中如何使用httpClient和Newtonsoft 研究了一下午 我从未用C 编程 一直用C 现学现卖 https download csdn net download cnwjl 1
  • 深入浅出java并发编程(AbstractQueuedSynchronizer)(AQS)

    前言 Abstract抽象的 Ownable拥有 Synchronizer同步器 Queued队列 AbstractOwnableSynchronizer简称为AOS AbstractQueuedSynchronizer简称为AQS Abs
  • Springboot+mybatis+druid的整合

    最近的公司项目后端用到了Springboot框架 把阿里的druid作为数据源 采用mybatis druid的方式 本人之前也是在这里踩了很多坑 因此感觉有必要出个博客来记录一下 首先 用druid最为数据源的好处就不多说了 灵活动态切换