SpringSecurity權限管理系統實戰—2、日誌、接口文檔等實現

系列目錄

SpringSecurity權限管理系統實戰—1、項目簡介和開發環境準備
SpringSecurity權限管理系統實戰—2、日誌、接口文檔等實現
SpringSecurity權限管理系統實戰—3、主要頁面及接口實現
SpringSecurity權限管理系統實戰—4、整合SpringSecurity(上)
SpringSecurity權限管理系統實戰—5、整合SpringSecurity(下)
SpringSecurity權限管理系統實戰—6、SpringSecurity整合jwt
SpringSecurity權限管理系統實戰—7、處理一些問題css

前言

​本篇文章的內容有點雜,搞得我都不知道怎麼取標題了。html

​上次咱們已經搭建好了my-springsecurity-plus的基本環境,本次咱們咱們要實現功能有系統日誌配置、配置swagger接口文檔、配置druid鏈接池等java

1、Banner替換

​能夠有些第一次接觸到這個名詞的小夥伴不清楚banner是什麼,其實就是在運行springboot項目時控制檯打印出的圖案,就是下面這個東西。mysql

.   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v2.3.1.RELEASE)

​這下是否是就熟悉了,其實SpringBoot支持自定義banner圖案。只須要放在指定位置,SpringBoot會幫咱們自動替換。Spring Boot 默認尋找 Banner 的順序是:jquery

  1. 依次在 Classpath 下找 文件 banner.gif , banner.jpg , 和 banner.png , 先找到誰就用誰。
  2. 繼續 Classpath 下找 banner.txt
  3. 上面都沒有找到的話, 用默認的 SpringBootBanner

咱們只須要在 src/main/resources 下新建一個 banner.txt,而後找一個在線生成banner的網站,例如patorjk,而後將生成的文本複製到banner.txt文件中。啓動項目,查看控制檯git

在這裏插入圖片描述

是否是很炫酷,一個知名項目的banner是這樣的github

////////////////////////////////////////////////////////////////////
//                          _ooOoo_                               //
//                         o8888888o                              //
//                         88" . "88                              //
//                         (| ^_^ |)                              //
//                         O\  =  /O                              //
//                      ____/`---'\____                           //
//                    .'  \\|     |//  `.                         //
//                   /  \\|||  :  |||//  \                        //
//                  /  _||||| -:- |||||-  \                       //
//                  |   | \\\  -  /// |   |                       //
//                  | \_|  ''\---/''  |   |                       //
//                  \  .-\__  `-`  ___/-. /                       //
//                ___`. .'  /--.--\  `. . ___                     //
//              ."" '<  `.___\_<|>_/___.'  >'"".                  //
//            | | :  `- \`.;`\ _ /`;.`/ - ` : | |                 //
//            \  \ `-.   \_ __\ /__ _/   .-` /  /                 //
//      ========`-.____`-.___\_____/___.-`____.-'========         //
//                           `=---='                              //
//      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^        //
//            佛祖保佑       永不宕機     永無BUG                    //
////////////////////////////////////////////////////////////////////

2、日誌

​在項目的開發中,日誌是必不可少的一個記錄事件的組件。應該不少很多剛入門的小夥伴對日誌都是不怎麼重視,對於我來講也是這樣,即便如今我對日誌也不是很重視,也沒有養成記錄日誌的習慣。但其實日誌在一個系統中尤其的重要,能夠幫助快速定位bug,來保證服務的高可用。web

​Spring Boot默認使用LogBack日誌系統,若是不須要更改成其餘日誌系統如Log4j2等,則無需多餘的配置,LogBack默認將日誌打印到控制檯上。ajax

​而Spring Boot項目通常都會引用spring-boot-starter或者spring-boot-starter-web的依賴,這兩個依賴中包含了spring-boot-starter-logging的依賴,因此咱們若是不使用別的日誌框架,無需修改依賴。spring

​若是咱們要使用日誌功能,只須要在相應類上加上@Slf4j(須要lambok插件)註解,在對應方法中log.indf(),log.error()等就能夠輸出日誌。咱們把HelloController改形成以下這樣

@Controller
@Slf4j
public class HelloController {

    @GetMapping(value = "/index")
    public String index(){
        log.info("測試");
        log.error("測試");
        return "index";
    }   
    @GetMapping(value = "/login")
    public String login(){
        return "login";
    }
    @GetMapping(value = "/console/console1")
    public String console1(){
        return "console/console1";
    }
}

​重啓項目,訪問http://localhost:8080/index控制檯會打印以下信息

在這裏插入圖片描述

​那麼如何把日誌存貯到文件裏呢?咱們只要在application.yml中簡單定義一下

logging:
  file:
    path: src\main\resources\logger\ # logger文件夾須要提早生成

​啓動項目,會在logger目錄下生成一個spring.log文件,內容和控制檯輸出的一致。

​日誌的輸出格式支持自定義,可是自定義後在控制檯輸出的內容就不是彩色的了,固然也能定義成彩色的,還有日誌文件生成的大小(總不能一直存在一個文件裏吧,那不就無限大了)和存儲時間等等,均可以自定義。我這裏不詳細介紹了,有興趣的小夥伴能夠本身瞭解。

3、Swagger接口文檔

​Swagger 是一個規範和完整的框架,用於生成、描述、調用和可視化RESTful風格的 Web 服務。整體目標是使客戶端和文件系統做爲服務器以一樣的速度來更新。文件的方法,參數和模型緊密集成到服務器端的代碼,容許API來始終保持同步。Swagger讓部署管理和使用功能強大的API變得很是簡單。官方網站:http://swagger.io/。
​Swagger也能夠用來測試接口(不少人會用postman,可是swagger可能用起來更簡單一點)

​那麼咱們首先要在maven添加相關依賴

<!--swagger-->
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
            <version>2.9.2</version>
        </dependency>
        <!--swagger ui-->
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger-ui</artifactId>
            <version>2.9.2</version>
        </dependency>

​ 這個我上一章給的依賴中有了,不要重複添加,這裏只是爲了說明。

​ 在啓動類的那一層級中新建config包,在其中新建SwaggerConfig類

@Configuration//代表這是一個配置類
@EnableSwagger2//開啓Swagger
public class SwaggerConfig {
    @Bean
    public Docket webApiConfig(){
        return new Docket(DocumentationType.SWAGGER_2)
                .groupName("webApi")//組名稱
                .apiInfo(webApiInfo())
                .select()
                .apis(RequestHandlerSelectors.basePackage("com.codermy.myspringsecurityplus.controller"))//掃描的包
                .paths(PathSelectors.any())
                .build();

    }
    /**
     * 該套 API 說明,包含做者、簡介、版本、等信息
     * @return
     */
    private ApiInfo webApiInfo(){
        return new ApiInfoBuilder()
                .title("my-springsecurity-plus-API文檔")
                .description("本文檔描述了my-springsecurity-plus接口定義")
                .version("1.0")
                .build();
    }

}

​ 而後咱們訪問http://localhost:8080/swagger-ui.html

在這裏插入圖片描述

​ 接口的名字也能夠自定義,詳細見Swagger 經常使用註解使用詳解

​ 咱們再改造一下HelloController

@Controller
@Slf4j
@Api(tags = "前期測試後面會刪")
public class HelloController {

    @GetMapping(value = "/index")
    public String index(){
        return "index";
    }

    @GetMapping(value = "/login")
    public String login(){
        return "login";
    }

    @GetMapping(value = "/console/console1")
    @ApiOperation(value = "轉發console1請求")
    public String console1(){
        return "console/console1";
    }
}

重啓訪問

在這裏插入圖片描述

4、主要界面接口

接下來咱們把用戶管理,角色管理,和權限管理三個界面的的接口換成咱們本身的。

首先咱們新建一個類來統一返回數據格式,新建utiils包,在其中新建Result類

//統一返回結果的類
@Data
public class Result<T> implements Serializable {

    @ApiModelProperty(value = "是否成功")
    private Boolean success;

    @ApiModelProperty(value = "返回碼")
    private Integer code;

    @ApiModelProperty(value = "返回消息")
    private String msg;

    @ApiModelProperty(value = "總數")
    private Integer count;

    @ApiModelProperty(value = "返回數據")
    private List<T> data = new ArrayList<T>();

    //把構造方法私有
    private Result() {}

    public static Result table_sucess() {
        Result r = new Result();
        r.setSuccess(true);
        r.setCode(ResultCode.TABLE_SUCCESS);
        r.setMsg("成功");
        return r;
    }

    //成功靜態方法
    public static Result ok() {
        Result r = new Result();
        r.setSuccess(true);
        r.setCode(ResultCode.SUCCESS);
        r.setMsg("成功");
        return r;
    }

    //失敗靜態方法
    public static Result error() {
        Result r = new Result();
        r.setSuccess(false);
        r.setCode(ResultCode.ERROR);
        r.setMsg("失敗");
        return r;
    }
    public Result success(Boolean success){
        this.setSuccess(success);
        return this;
    }
    public Result message(String message){
        this.setMsg(message);
        return this;
    }
    public Result code(Integer code){
        this.setCode(code);
        return this;
    }

    public Result data(List<T> list){
        this.data.addAll(list);
        return this;
    }
    public Result count(Integer count){
        this.count = count;
        return this;
    }
}

在新建一個ReslutCode接口來定義經常使用的狀態碼

public interface ResultCode {
    /**
     * 請求t成功
     */
    public static Integer SUCCESS = 200;
    /**
     * 請求table成功
     */
    public static Integer TABLE_SUCCESS = 0;
    /**
     * 請求失敗
     */
    public static Integer ERROR = 201;

    /**
     * 請求已經被接受
     */
    public static final Integer ACCEPTED = 202;

    /**
     * 操做已經執行成功,可是沒有返回數據
     */
    public static final Integer NO_CONTENT = 204;

    /**
     * 資源已被移除
     */
    public static final Integer MOVED_PERM = 301;

    /**
     * 重定向
     */
    public static final Integer SEE_OTHER = 303;

    /**
     * 資源沒有被修改
     */
    public static final Integer NOT_MODIFIED = 304;

    /**
     * 參數列表錯誤(缺乏,格式不匹配)
     */
    public static final Integer BAD_REQUEST = 400;

    /**
     * 未受權
     */
    public static final Integer UNAUTHORIZED = 401;

    /**
     * 訪問受限,受權過時
     */
    public static final Integer FORBIDDEN = 403;

    /**
     * 資源,服務未找到
     */
    public static final Integer NOT_FOUND = 404;

    /**
     * 不容許的http方法
     */
    public static final Integer BAD_METHOD = 405;

    /**
     * 資源衝突,或者資源被鎖
     */
    public static final Integer CONFLICT = 409;

    /**
     * 不支持的數據,媒體類型
     */
    public static final Integer UNSUPPORTED_TYPE = 415;

    /**
     * 接口未實現
     */
    public static final Integer NOT_IMPLEMENTED = 501;
}

自定義異常處理(這裏不過多解釋,只簡單實現直接貼代碼

@ControllerAdvice
@Slf4j
public class GlobalExceptionHandler {
    //指定處理什麼異常
    @ExceptionHandler(Exception.class)
    @ResponseBody
    public Result error(Exception e){
        e.printStackTrace();
        return Result.error().message("執行了全局異常");
    }
    //自定義異常
    @ExceptionHandler(MyException.class)
    @ResponseBody
    public Result error(MyException e){
        log.error(e.getMessage());
        e.printStackTrace();
        return Result.error().code(e.getCode()).message(e.getMsg());
    }
}
@Data
@AllArgsConstructor
@NoArgsConstructor
public class MyException extends  RuntimeException {
    private  Integer code;//狀態碼
    private String  msg;//異常信息
}

新建PageTableRequest 分頁工具類

@Data
public class PageTableRequest implements Serializable {

    private Integer page;//初始頁
    private Integer limit;//一頁幾條數據
    private Integer offset;//頁碼

    public void countOffset(){
        if(null == this.page || null == this.limit){
            this.offset = 0;
            return;
        }
        this.offset = (this.page - 1) * limit;
    }

}

下面進入正題

由於我這裏用的是druid的鏈接池(以後介紹),我直接把application.yml貼出來

server:
  port: 8080
spring:
  profiles:
    active: dev
  application:
    name: my-springsecurity-plus
  datasource:
    driver:
    driver-class-name: com.mysql.cj.jdbc.Driver
    # 後面時區不要忘了若是你是mysql8.0以上的版本
    url: jdbc:mysql://localhost:3306/my-springsecurity-plus?serverTimezone=Asia/Shanghai
    username: root
    password: 180430121
    type: com.alibaba.druid.pool.DruidDataSource #druid鏈接池以後會解釋這裏先複製
    druid:
      # 初始化配置
      initial-size: 3
      # 最小鏈接數
      min-idle: 3
      # 最大鏈接數
      max-active: 15
      # 獲取鏈接超時時間
      max-wait: 5000
      # 鏈接有效性檢測時間
      time-between-eviction-runs-millis: 90000
      # 最大空閒時間
      min-evictable-idle-time-millis: 1800000
      test-while-idle: true
      test-on-borrow: false
      test-on-return: false
      validation-query: select 1
      # 配置監控統計攔截的filters
      filters: stat
      web-stat-filter:
        url-pattern: /*
        exclusions: "*.js,*.gif,*.jpg,*.bmp,*.png,*.css,*.ico,/druid/*"
      #StatViewServlet配置,說明請參考Druid Wiki,配置_StatViewServlet配置
      stat-view-servlet:
        enabled: true #是否啓用StatViewServlet默認值true
        url-pattern: /druid/*
        reset-enable: true
        login-username: admin
        login-password: admin
  jackson:
    date-format: yyyy-MM-dd HH:mm:ss
    time-zone: GMT+8

# mybatis配置
mybatis:
  type-aliases-package: com.codermy.myspringsecurityplus.entity
  mapper-locations: classpath:/mybatis-mappers/*
  configuration:
    map-underscore-to-camel-case: true

logging:
  file:
    path: src\main\resources\logger\ # logger文件夾須要提早生成

用戶管理菜單接口,以前應該都建立好了相應的類,只拿這一個接口作例子,另外兩個都同樣

MyUser實體類

@Data
@EqualsAndHashCode(callSuper = true)
public class MyUser extends BaseEntity<Integer>{
    private static final long serialVersionUID = -6525908145032868837L;
    private String userName;
    private String password;
    private String nickName;
    private String phone;
    private String email;
    private Integer status;
    public interface Status {
        int LOCKED = 0;
        int VALID = 1;
    }
}

UserDao中新建兩個方法,分頁會用到

@Mapper
public interface UserDao {
    //分頁返回全部用戶
    @Select("SELECT * FROM my_user t ORDER BY t.id LIMIT #{startPosition}, #{limit}")
    List<MyUser> getAllUserByPage(@Param("startPosition")Integer startPosition,@Param("limit")Integer limit);

    //計算全部用戶數量
    @Select("select count(*) from My_user")
    Long countAllUser();
}

UserService和UserServiceImlpl

public interface UserService {
    Result<MyUser> getAllUsersByPage(Integer startPosition, Integer limit);
}
@Service
public class UserServiceImpl implements UserService {
    @Autowired
    private UserDao userDao;

    @Override
    public Result<MyUser> getAllUsersByPage(Integer startPosition, Integer limit) {

        return Result.ok().count(userDao.countAllUser().intValue()).data(userDao.getAllUserByPage(startPosition,limit)).code(ResultCode.TABLE_SUCCESS);
    }
}

UserController

@Controller
@RequestMapping("/api/user")
@Api(tags = "用戶相關接口")
public class UserController {
    @Autowired
    private UserService userService;

    @GetMapping
    @ResponseBody
    @ApiOperation(value = "用戶列表")
    public Result<MyUser> index(PageTableRequest pageTableRequest){
        pageTableRequest.countOffset();
        return userService.getAllUsersByPage(pageTableRequest.getOffset(),pageTableRequest.getLimit());
    }
}

咱們能夠比較一下他須要的json(user.json,在admin/data/user.json)和咱們返回的json格式

在這裏插入圖片描述

在這裏插入圖片描述

他原先設置空值的能夠不看,說明也用不着,而後在usr.html中把對應相同的數據,可是命名不同的地方修改一下便可。

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
	<head>
		<meta charset="utf-8">
		<title></title>
		<link rel="stylesheet" th:href="@{/PearAdmin/component/layui/css/layui.css}" />
		<link rel="stylesheet" th:href="@{/PearAdmin/admin/css/pearCommon.css}"/>
	</head>
	<body class="pear-container">
		<div class="layui-card">
			<div class="layui-card-body">
				<form class="layui-form" action="">
					<div class="layui-form-item">
						<label class="layui-form-label">用戶名</label>
						<div class="layui-input-inline">
							<input type="text" name="nickName" placeholder="" class="layui-input">
						</div>
						<label class="layui-form-label">帳號</label>
						<div class="layui-input-inline">
							<input type="text" name="userName" placeholder="" class="layui-input">
						</div>
						<label class="layui-form-label">地點</label>
						<div class="layui-input-inline">
							<select name="city" lay-verify="required">
							        <option value=""></option>
							        <option value="0">北京</option>
							        <option value="1">上海</option>
							        <option value="2">廣州</option>
							        <option value="3">深圳</option>
							        <option value="4">杭州</option>
							      </select>
						</div>
						<button class="pear-btn pear-btn-md pear-btn-primary" lay-submit lay-filter="user-query">
							<i class="layui-icon layui-icon-search"></i>
							查詢
						</button>
						<button type="reset" class="pear-btn pear-btn-md">
							<i class="layui-icon layui-icon-refresh"></i>
							重置
						</button>
					</div>
				</form>
			</div>
		</div>
		<div class="layui-card">
			<div class="layui-card-body">
				<table id="user-table" lay-filter="user-table"></table>
			</div>
		</div>

		<script type="text/html" id="user-toolbar">
		    <button class="pear-btn pear-btn-primary pear-btn-md" lay-event="add">
		        <i class="layui-icon layui-icon-add-1"></i>
		        新增
		    </button>
		    <button class="pear-btn pear-btn-danger pear-btn-md" lay-event="batchRemove">
		        <i class="layui-icon layui-icon-delete"></i>
		        刪除
		    </button>
		</script>
		
		<script type="text/html" id="user-bar">
		    <button class="pear-btn pear-btn-primary pear-btn-sm" lay-event="edit"><i class="layui-icon layui-icon-edit"></i></button>
		    <button class="pear-btn pear-btn-danger pear-btn-sm" lay-event="remove"><i class="layui-icon layui-icon-delete"></i></button>
		</script>
		
		<script type="text/html" id="user-status">
		    <input type="checkbox" name="status" value="{{d.id}}" lay-skin="switch" lay-text="啓用|禁用" lay-filter="user-status" checked = "{{ d.status == 0 ? 'true' : 'false' }}">
		</script>

		
		<script type="text/html" id="user-createTime">
		    {{layui.util.toDateString(d.createTime, 'yyyy-MM-dd HH:mm:ss')}}
		</script>

		<script th:src="@{/PearAdmin/component/layui/layui.js}" charset="utf-8"></script>
		<script>
		    layui.use(['table','form','jquery'],function () {
		        let table = layui.table;
		        let form = layui.form;
		        let $ = layui.jquery;
		        let MODULE_PATH = "operate/";
                //這裏對應的field要和本身返回的json名稱一致
		        let cols = [
		            [
		                {type:'checkbox'},
		                {title: '帳號', field: 'userName', align:'center', width:100},
		                {title: '姓名', field: 'nickName', align:'center'},
		                {title: '電話', field: 'phone', align:'center'},
						{title: '郵箱', field: 'email', align:'center'},
		                {title: '啓用', field: 'status', align:'center', templet:'#user-status'},
		                {title: '建立時間', field: 'createTime', align:'center',templet:'#user-createTime'},
		                {title: '操做', toolbar: '#user-bar', align:'center', width:130}
		            ]
		        ]
		
		        table.render({
		            elem: '#user-table',
		            url: '/api/user',//+++++++++++看這裏  這裏的url換成本身接口的url++++++++++++++
		            page: true ,
		            cols: cols ,
		            skin: 'line',
		            toolbar: '#user-toolbar',
		            defaultToolbar: [{
		                layEvent: 'refresh',
		                icon: 'layui-icon-refresh',
		            }, 'filter', 'print', 'exports']
		        });
		
		        table.on('tool(user-table)', function(obj){
		            if(obj.event === 'remove'){
		                window.remove(obj);
		            } else if(obj.event === 'edit'){
		                window .edit(obj);
		            }
		        });
		
		        table.on('toolbar(user-table)', function(obj){
		            if(obj.event === 'add'){
		                window.add();
		            } else if(obj.event === 'refresh'){
		                window.refresh();
		            } else if(obj.event === 'batchRemove'){
		                window.batchRemove(obj);
		            }
		        });
		
		        form.on('submit(user-query)', function(data){
		            table.reload('user-table',{where:data.field})
		            return false;
		        });
		
		        form.on('switch(user-status)', function(obj){
		            layer.tips(this.value + ' ' + this.name + ':'+ obj.elem.checked, obj.othis);
		        });
		
		        window.add = function(){
		            layer.open({
		                type: 2,
		                title: '新增',
		                shade: 0.1,
		                area: ['500px', '400px'],
		                content: MODULE_PATH + 'add.html'
		            });
		        }
		        window.edit = function(obj){
		            layer.open({
		                type: 2,
		                title: '修改',
		                shade: 0.1,
		                area: ['500px', '400px'],
		                content: MODULE_PATH + 'edit.html'
		            });
		        }
		
		        window.remove = function(obj){
		            layer.confirm('肯定要刪除該用戶', {icon: 3, title:'提示'}, function(index){
		                layer.close(index);
		                let loading = layer.load();
		                $.ajax({
		                    url: MODULE_PATH+"remove/"+obj.data['id'],
		                    dataType:'json',
		                    type:'delete',
		                    success:function(result){
		                        layer.close(loading);
		                        if(result.success){
		                            layer.msg(result.msg,{icon:1,time:1000},function(){
		                                obj.del();
		                            });
		                        }else{
		                            layer.msg(result.msg,{icon:2,time:1000});
		                        }
		                    }
		                })
		            });
		        }
		
		        window.batchRemove = function(obj){
		            let data = table.checkStatus(obj.config.id).data;
		            if(data.length === 0){
		                layer.msg("未選中數據",{icon:3,time:1000});
		                return false;
		            }
		            let ids = "";
		            for(let i = 0;i<data.length;i++){
		                ids += data[i].id+",";
		            }
		            ids = ids.substr(0,ids.length-1);
		            layer.confirm('肯定要刪除這些用戶', {icon: 3, title:'提示'}, function(index){
		                layer.close(index);
		                let loading = layer.load();
		                $.ajax({
		                    url: MODULE_PATH+"batchRemove/"+ids,
		                    dataType:'json',
		                    type:'delete',
		                    success:function(result){
		                        layer.close(loading);
		                        if(result.success){
		                            layer.msg(result.msg,{icon:1,time:1000},function(){
		                                table.reload('user-table');
		                            });
		                        }else{
		                            layer.msg(result.msg,{icon:2,time:1000});
		                        }
		                    }
		                })
		            });
		        }
		
		        window.refresh = function(param){
		            table.reload('user-table');
		        }
		    })
		</script>
	</body>
</html>

這樣當咱們再次點擊用戶管理時,訪問的就是本身的接口了

在這裏插入圖片描述

本來本身看別人的教學博客時,是真的但願人家把全部的代碼一字不差的貼上來。等到本身寫的時候就以爲仍是有道理的,代碼太佔篇幅了,還影響博客的觀感。因此另外兩個界面我就補貼代碼了,你們仿照這個來就行。

在這裏插入圖片描述
放兩張圖片,讓你們看一下改完的效果。

在這裏插入圖片描述
在這裏插入圖片描述

數據庫文件和同步代碼在giteegithub中能夠獲取

5、Druid鏈接池

Druid是阿里開源的數據庫鏈接池,做爲後起之秀,性能比dbcp、c3p0更高,使用也愈來愈普遍。

固然Druid不只僅是一個鏈接池,還有不少其餘的功能。

druid的優勢

  • 高性能。性能比dbcp、c3p0高不少。
  • 只要是jdbc支持的數據庫,druid都支持,對數據庫的支持性好。而且Druid針對oracle、mysql作了特別優化。
  • 提供監控功能。能夠監控sql語句的執行時間、ResultSet持有時間、返回行數、更新行數、錯誤次數、錯誤堆棧等信息,來了解鏈接池、sql語句的工做狀況,方便統計、分析SQL的執行性能

如何使用??

導入依賴,以前給的依賴中就有不用重複導入

<!--druid鏈接池-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.1.21</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>

application.yml中配置

spring:
  profiles:
    active: dev
  application:
    name: my-springsecurity-plus
  datasource:
    driver:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/my-springsecurity-plus?serverTimezone=Asia/Shanghai
    username: root
    password: 180430121
    type: com.alibaba.druid.pool.DruidDataSource
    druid:
      # 初始化配置
      initial-size: 3
      # 最小鏈接數
      min-idle: 3
      # 最大鏈接數
      max-active: 15
      # 獲取鏈接超時時間
      max-wait: 5000
      # 鏈接有效性檢測時間
      time-between-eviction-runs-millis: 90000
      # 最大空閒時間
      min-evictable-idle-time-millis: 1800000
      test-while-idle: true
      test-on-borrow: false
      test-on-return: false

      validation-query: select 1
      # 配置監控統計攔截的filters
      filters: stat
      web-stat-filter:
        url-pattern: /*
        exclusions: "*.js,*.gif,*.jpg,*.bmp,*.png,*.css,*.ico,/druid/*"
      #StatViewServlet配置,說明請參考Druid Wiki,配置_StatViewServlet配置
      stat-view-servlet:
        enabled: true #是否啓用StatViewServlet默認值true
        url-pattern: /druid/*
        reset-enable: true
        login-username: admin #用戶名
        login-password: admin #密碼

更詳細的配置這裏就不介紹了。
而後重啓項目訪問http://localhost:8080/druid/login.html輸入用戶名密碼就能夠看到界面了。
在這裏插入圖片描述 呼,終於又寫完一篇,寫代碼的時候真沒感受這麼累,像我這種文筆差的常常寫着寫着就把本身寫亂了。。。。。

相關文章
相關標籤/搜索