Shiro安全框架数据库配置文件详解 (shiro 数据库配置文件)

Shiro是一个Java安全框架,它提供了认证、授权、加密等安全功能,广泛应用于企业级应用程序的开发中。Shiro的配置文件中包含了很多重要的参数和配置信息,其中数据库配置文件是非常关键的一部分。本文将详细介绍Shiro安全框架数据库配置文件的内容和作用。

一、数据库中的表结构

在Shiro框架中,用户信息和权限信息都存储在数据库中,我们需要在数据库中创建相关的表结构。Shiro默认的表结构如下:

1.用户表

CREATE TABLE `sys_user` (

`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT ‘用户id’,

`username` varchar(50) NOT NULL COMMENT ‘用户名’,

`password` varchar(100) NOT NULL COMMENT ‘密码’,

`salt` varchar(50) DEFAULT NULL COMMENT ‘盐值’,

`state` tinyint(4) NOT NULL DEFAULT ‘0’ COMMENT ‘状态(0:正常,1:锁定)’,

PRIMARY KEY (`id`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT=’用户表’;

2.角色表

CREATE TABLE `sys_role` (

`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT ‘角色id’,

`role_name` varchar(50) NOT NULL COMMENT ‘角色名称’,

`role_desc` varchar(100) DEFAULT NULL COMMENT ‘角色描述’,

`avlable` tinyint(4) NOT NULL DEFAULT ‘0’ COMMENT ‘状态(0:可用,1:不可用)’,

PRIMARY KEY (`id`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT=’角色表’;

3.权限表

CREATE TABLE `sys_permission` (

`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT ‘权限id’,

`permission_name` varchar(50) NOT NULL COMMENT ‘权限名称’,

`permission_url` varchar(200) DEFAULT NULL COMMENT ‘权限URL’,

`avlable` tinyint(4) NOT NULL DEFAULT ‘0’ COMMENT ‘状态(0:可用,1:不可用)’,

`parent_id` bigint(20) DEFAULT NULL COMMENT ‘父权限id’,

PRIMARY KEY (`id`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT=’权限表’;

4.用户角色关系表

CREATE TABLE `sys_user_role` (

`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT ‘用户角色关系id’,

`user_id` bigint(20) NOT NULL COMMENT ‘用户id’,

`role_id` bigint(20) NOT NULL COMMENT ‘角色id’,

PRIMARY KEY (`id`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT=’用户角色关系表’;

5.角色权限关系表

CREATE TABLE `sys_role_permission` (

`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT ‘角色权限关系id’,

`role_id` bigint(20) NOT NULL COMMENT ‘角色id’,

`permission_id` bigint(20) NOT NULL COMMENT ‘权限id’,

PRIMARY KEY (`id`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT=’角色权限关系表’;

二、数据库配置文件

Shiro安全框架的数据库配置文件是Shiro的核心配置之一,它保存了Shiro框架中数据库连接的相关信息、表结构信息和查询语句等。本节将详细介绍Shiro安全框架数据库配置文件的每个配置项的作用和参数设置方法。

1.数据库连接信息配置

Shiro框架需要连接数据库才能读取用户信息和权限信息,因此,数据库连接信息是配置文件中最重要的一部分。下面是Shiro框架的数据库连接信息配置模板:

[mn]

# 数据库连接配置

jdbcDriver = com.mysql.jdbc.Driver

jdbcUrl = jdbc:mysql://localhost:3306/shiro?useUnicode=true&characterEncoding=utf8

jdbcUsername = root

jdbcPassword = root

其中,jdbcDriver是数据库驱动程序的名称,jdbcUrl是数据库连接字符串,jdbcUsername和jdbcPassword是数据库的登录用户名和密码。需要注意的是,如果使用非默认的数据库,则需要修改jdbcUrl配置项的内容。

2.表结构信息配置

Shiro框架需要读取数据库中的用户信息表、角色信息表和权限信息表,并且根据它们的关系建立用户角色关系表和角色权限关系表。下面是Shiro框架的数据库表结构信息配置模板:

[roles]

# 用户信息表名称

userTable = sys_user

# 用户名字段名称

usernameColumn = username

# 密码字段名称

passwordColumn = password

# 盐值字段名称

saltColumn = salt

[roles]

# 角色信息表名称

roleTable = sys_role

# 角色名字段名称

roleNameColumn = role_name

# 角色描述字段名称

roleDescColumn = role_desc

# 是否可用字段名称

roleAvlableColumn=avlable

[permissions]

# 权限信息表名称

permissionTable = sys_permission

# 权限名字段名称

permissionNameColumn = permission_name

# 权限url字段名称

permissionUrlColumn = permission_url

# 是否可用字段名称

permissionAvlableColumn = avlable

# 父权限id字段名称

permissionParentColumn = parent_id

[user_role]

# 用户角色关系表名称

userRoleTable = sys_user_role

# 用户id字段名称

userIdColumn = user_id

# 角色id字段名称

roleIdColumn = role_id

[role_permission]

# 角色权限关系表名称

rolePermissionTable = sys_role_permission

# 角色id字段名称

roleIdColumn = role_id

# 权限id字段名称

permissionIdColumn = permission_id

其中,[roles]、[permissions]、[user_role]和[role_permission]是配置文件的子标签,它们分别表示用户表信息、角色表信息、权限表信息、用户角色关系表信息和角色权限关系表信息。每个子标签中的参数名称和作用如下:

userTable:用户信息表名称

usernameColumn:用户名字段名称

passwordColumn:密码字段名称

saltColumn:盐值字段名称

roleTable:角色信息表名称

roleNameColumn:角色名字段名称

roleDescColumn:角色描述字段名称

roleAvlableColumn:是否可用字段名称

permissionTable:权限信息表名称

permissionNameColumn:权限名字段名称

permissionUrlColumn:权限url字段名称

permissionAvlableColumn:是否可用字段名称

permissionParentColumn:父权限id字段名称

userRoleTable:用户角色关系表名称

userIdColumn:用户id字段名称

roleIdColumn:角色id字段名称

rolePermissionTable:角色权限关系表名称

roleIdColumn:角色id字段名称

permissionIdColumn:权限id字段名称

3.查询语句配置

Shiro框架使用SQL语句查询数据库中的用户信息和权限信息,查询语句包括查询所有用户信息、查询用户角色信息、查询角色权限信息等。下面是Shiro框架的查询语句配置模板:

[roles]

# 查询单个用户信息

userSql = select password,salt from sys_user where username = ?

# 查询用户角色信息

rolesSql = select r.role_name from sys_user_role ur, sys_role r where ur.role_id = r.id and ur.user_id = (select id from sys_user where username = ?)

# 查询所有角色信息

allRolesSql = select role_name from sys_role

# 查询角色权限信息

permissionsSql = select p.permission_name from sys_role_permission rp,sys_permission p where rp.permission_id = p.id and rp.role_id = (select id from sys_role where role_name = ?)

其中,[roles]是配置文件的子标签,它表示角色信息相关查询语句。每个子标签中的参数名称和作用如下:

userSql:查询单个用户信息的SQL语句,其中?表示用户名参数

rolesSql:查询用户角色信息的SQL语句,其中?表示用户名参数

allRolesSql:查询所有角色信息的SQL语句

permissionsSql:查询角色权限信息的SQL语句,其中?表示角色名参数

三、数据库配置文件示例

下面是一个完整的Shiro安全框架数据库配置文件示例:

[mn]

# 数据库连接配置

jdbcDriver = com.mysql.jdbc.Driver

jdbcUrl = jdbc:mysql://localhost:3306/shiro?useUnicode=true&characterEncoding=utf8

jdbcUsername = root

jdbcPassword = root

[roles]

# 用户表信息

userTable = sys_user

usernameColumn = username

passwordColumn = password

saltColumn = salt

# 角色表信息

roleTable = sys_role

roleNameColumn = role_name

roleDescColumn = role_desc

roleAvlableColumn=avlable

# 权限表信息

permissionTable = sys_permission

permissionNameColumn = permission_name

permissionUrlColumn = permission_url

permissionAvlableColumn = avlable

permissionParentColumn = parent_id

# 用户角色关系表信息

userRoleTable = sys_user_role

userIdColumn = user_id

roleIdColumn = role_id

# 角色权限关系表信息

rolePermissionTable = sys_role_permission

roleIdColumn = role_id

permissionIdColumn = permission_id

# 查询单个用户信息

userSql = select password,salt from sys_user where username = ?

# 查询用户角色信息

rolesSql = select r.role_name from sys_user_role ur, sys_role r where ur.role_id = r.id and ur.user_id = (select id from sys_user where username = ?)

# 查询所有角色信息

allRolesSql = select role_name from sys_role

# 查询角色权限信息

permissionsSql = select p.permission_name from sys_role_permission rp,sys_permission p where rp.permission_id = p.id and rp.role_id = (select id from sys_role where role_name = ?)

上述配置文件中,包括了数据库连接信息、表信息和查询语句信息,开发人员只需要修改其中相应的参数即可使Shiro框架连接到自己的数据库。

Shiro安全框架的数据库配置文件是Shiro功能完整性的关键之一,它保存了Shiro框架中数据库连接的相关信息、表结构信息和查询语句等。开发人员可以根据自己的需求进行相应的修改和配置。

相关问题拓展阅读:

Shiro的 rememberMe 功能使用指导为什么rememberMe设置了没作用

采用这个解决方案的前提是,你必须自己先实现一个realm,不过这个我相信大家都会实现的,毕竟默认的不是jdbcRealm ,真正的项目都是要查数据库才能确定用户是否登录的。那么我就假定大家的项目中都有那么一个负责验证登录的 JdbcRealm, 并且是采用用户名密码认证的,在 doGetAuthenticationInfo 方法里面是采用如下的方法来做认证

info = new SimpleAuthenticationInfo(username, password.toCharArray(), getName());

这个前提条件保证你的principal是username,相信大部分人根据教程做shiro的时候都采用了这种方式

STEP1 复写 FormAuthenticationFilter 的 isAccessAllowed 方法

做一个新类继承FormAuthenticationFilter ,并复写 isAccessAllowed 方法

package com.yqr.jxc.shiro;

import javax.annotation.Resource;

import javax.servlet.ServletRequest;

import javax.servlet.ServletResponse;

import org.apache.shiro.session.Session;

import org.apache.shiro.subject.Subject;

import org.apache.shiro.web.filter.authc.FormAuthenticationFilter;

import com.yqr.jxc.service.global.GlobalUserService;

public class RememberAuthenticationFilter extends FormAuthenticationFilter {

@Resource(name=”globalUserService”)

private GlobalUserService globalUserService;

/**

* 这个方法决定了是否能让用户登录

*/

@Override

protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {

Subject subject = getSubject(request, response);

//如果 isAuthenticated 为 false 证明不是登录过的,同时 isRememberd 为true 证明是没登陆直接通过记住我功能进来的

if(!subject.isAuthenticated() && subject.isRemembered()){

//获取session看看是不是空的

Session session = subject.getSession(true);

//随便拿session的一个属性来看session当前是否是空的,我用userId,你们的项目可以自行发挥

if(session.getAttribute(“userId”) == null){

//如果是空的才初始化,否则每次都要初始化,项目得慢死

//这边根据前面的前提假设,拿到的是username

String username = subject.getPrincipal().toString();

//在这个方法里面做初始化用户上下文的事情,比如通过查询数据库来设置session值,你们自己发挥

globalUserService.initUserContext(username, subject);

}

}

//这个方法本来只返回 subject.isAuthenticated() 现在我们加上 subject.isRemembered() 让它同时也兼容remember这种情况

return subject.isAuthenticated() || subject.isRemembered();

}

}

STEP2 设置使用这个新的 AuthenticationFilter (认证过滤器)

如果你用的是spring那么

<!–将之前的 /** = authc 替换成 rememberAuthFilter

/** = rememberAuthFilter

如果你用的是 ini 文件,那么

rememberAuthFilter=com.yqr.jxc.shiro.RememberAuthenticationFilter

#将之前的 /** = authc 替换成 rememberAuthFilter

/** = rememberAuthFilter

然后重启项目我们来测试一下,先登录一次系统,然后直接关掉浏览器,然后打开浏览器直接输入系统某个页面的地址,发现可以直接进去了,session什么的也设置好了

官方的文档有说明,isRemembered和isAuthenticated是互斥的

isRemembered是在服务器上记录一个cookie说明你这个用户登陆过并且被记住了

效果类似于亚马逊页面上,他会记住近期登陆过的用户(Subject)

但是你进行敏感操作的时候还是要重新登录敲账号密码的,也就是必须重新进行Authentication

也就是说如果你的拦截器配置了authc或者其他需要认证之后才能使用的

shiro的rememberMe功能就不起作用了

印象中有一个url拦截器可以过滤这个,不记得名字了

2、SpringMVC shiro 项目 jeesite框架,启动后可以访问,等待约30分钟或更久之后,之一次访问会卡住。

应该是session超时导致的,shiro的默认设置会话的全局过期时间30分钟:

我也出现了同样的情况 楼主解决了没

3、java框架有哪些常用框架

十大常用框架:

一、SpringMVC

二、Spring

三、Mybatis

四、Dubbo

五、Maven

六、RabbitMQ

七、Log4j

八、Ehcache

九、Redis

十、Shiro

延展阅读:

一、SpringMVC

SpringWebMVC是一种基于Java的实现了WebMVC设计模式的请求驱动类型的轻量级Web框架,即使用了MVC架构模式的思想,将web层进行职责解耦,基于请求驱动指的就是使用请求-响应模型,框架的目的就是帮助我们简化开发,SpringWebMVC也是要简化我们日常Web开发的。

模型(Model)封装了应用程序的数据和一般他们会组成的POJO。

视图(View)是负责呈现模型数据和一般它生成的HTML输出,客户端的浏览器能够解释。

控制器(Controller)负责处理用户的请求,并建立适当的模型,并把它传递给视图渲染。

Spring的web模型-视图-控制器(MVC)框架是围绕着处理所有的HTTP请求和响应的的设计。

SpringWebMVC处理请求的流程

具体执行步骤如下:

1、首先用户发送请求————>前端控制器,前端控制器根据请求信息(如URL)来决定选择哪一个页面控制器进行处理并把请求委托给它,即以前的控制器的控制逻辑部分;图2-1中的1、2步骤;

2、页面控制器接收到请求后,进行功能处理,首先需要收集和绑定请求参数到一个对象,这个对象在SpringWebMVC中叫命令对象,并进行验证,然后将命令对象委托给业务对象进行处理;处理完毕后返回一个(模型数据和逻辑视图名);图2-1中的3、4、5步骤;

3、前端控制器收回控制权,然后根据返回的逻辑视图名,选择相应的视图进行渲染,并把模型数据传入以便视图渲染;图2-1中的步骤6、7;

4、前端控制器再次收回控制权,将响应返回给用户,图2-1中的步骤8;至此整个结束。

二、Spring

2.1、IOC容器:wwwblogs/linjiqin/archive/2023/11/04/.html

IOC容器就是具有依赖注入功能的容器,IOC容器负责实例化、定位、配置应用程序中的对象及建立这些对象间的依赖。应用程序无需直接在代码中new相关的对象,应用程序由IOC容器进行组装。在Spring中BeanFactory是IOC容器的实际代表者。

2.2、AOP:blog.csdn.net/moreevan/article/details/

简单地说,就是将那些与业务无关,却为业务模块所共同调用的逻辑或责任封装起来,便于减少系统的重复代码,降低模块间的耦合度,并有利于未来的可操作性和可维护性。AOP代表的是一个横向的关系

AOP用来封装横切关注点,具体可以在下面的场景中使用:

权限

Caching缓存

Contextpassing内容传递

Errorhandling错误处理

Lazyloading懒加载

Debugging调试

logging,tracing,profilingandmonitoring记录跟踪优化校准

Performance性能优化

Persistence持久化

Resourcepooling资源池

同步

事务

三、Mybatis

MyBatis是支持普通SQL查询,存储过程和高级映射的优秀持久层框架。MyBatis消除了几乎所有的JDBC代码和参数的手工设置以及结果集的检索。MyBatis使用简单的XML或注解用于配置和原始映射,将接口和Java的POJOs(PlainOldJavaObjects,普通的Java对象)映射成数据库中的记录。

总体流程:

(1)加载配置并初始化

触发条件:加载配置文件

将SQL的配置信息加载成为一个个对象(包括了传入参数映射配置、执行的SQL语句、结果映射配置),存储在内存中。

(2)接收调用请求

触发条件:调用Mybatis提供的API

传入参数:为SQL的ID和传入参数对象

处理过程:将请求传递给下层的请求处理层进行处理。

(3)处理操作请求触发条件:API接口层传递请求过来

传入参数:为SQL的ID和传入参数对象

处理过程:

(A)根据SQL的ID查找对应的对象。

(B)根据传入参数对象解析对象,得到最终要执行的SQL和执行传入参数。

(C)获取数据库连接,根据得到的最终SQL语句和执行传入参数到数据库执行,并得到执行结果。

(D)根据对象中的结果映射配置对得到的执行结果进行转换处理,并得到最终的处理结果。

(E)释放连接资源。

(4)返回处理结果将最终的处理结果返回。

MyBatis最强大的特性之一就是它的动态语句功能。如果您以前有使用JDBC或者类似框架的经历,您就会明白把SQL语句条件连接在一起是多么的痛苦,要确保不能忘记空格或者不要在columns列后面省略一个逗号等。动态语句能够完全解决掉这些痛苦。

四、Dubbo

Dubbo是一个分布式服务框架,致力于提供高性能和透明化的RPC(远程过程调用协议)远程服务调用方案,以及SOA服务治理方案。简单的说,bbo就是个服务框架,如果没有分布式的需求,其实是不需要用的,只有在分布式的时候,才有bbo这样的分布式服务框架的需求,并且本质上是个服务调用的东东,说白了就是个远程服务调用的分布式框架。

1、透明化的远程方法调用,就像调用本地方法一样调用远程方法,只需简单配置,没有任何API侵入。

2、软负载均衡及容错机制,可在内网替代F5等硬件负载均衡器,降低成本,减少单点。

3、服务自动注册与发现,不再需要写死服务提供方地址,注册中心基于接口名查询服务提供者的IP地址,并且能够平滑添加或删除服务提供者。

节点角色说明:

Provider:暴露服务的服务提供方。

Consumer:调用远程服务的服务消费方。

Registry:服务注册与发现的注册中心。

Monitor:统计服务的调用次调和调用时间的监控中心。

Container:服务运行容器。

五、Maven

Maven这个个项目管理和构建自动化工具,越来越多的开发人员使用它来管理项目中的jar包。但是对于我们程序员来说,我们最关心的是它的项目构建功能。

六、RabbitMQ

消息队列一般是在项目中,将一些无需即时返回且耗时的操作提取出来,进行了异步处理,而这种异步处理的方式大大的节省了服务器的请求响应时间,从而提高了系统的吞吐量。

RabbitMQ是用Erlang实现的一个高并发高可靠AMQP消息队列服务器。

Erlang是一门动态类型的函数式编程语言。对应到Erlang里,每个Actor对应着一个Erlang进程,进程之间通过消息传递进行通信。相比共享内存,进程间通过消息传递来通信带来的直接好处就是消除了直接的锁开销(不考虑Erlang虚拟机底层实现中的锁应用)。

AMQP(AdvancedMessageQueueProtocol)定义了一种消息系统规范。这个规范描述了在一个分布式的系统中各个子系统如何通过消息交互。

七、Log4j

日志记录的优先级,分为OFF、FATAL、ERROR、WARN、INFO、DEBUG、ALL或者您定义的级别。

八、Ehcache

EhCache是一个纯Java的进程内缓存框架,具有快速、精干等特点,是Hibernate中默认的。Ehcache是一种广泛使用的开源Java分布式缓存。主要面向通用缓存,JavaEE和轻量级容器。它具有内存和磁盘存储,缓存加载器,缓存扩展,缓存异常处理程序,一个gzip缓存servlet过滤器,支持REST和SOAPapi等特点。

优点:

1、快速

2、简单

3、多种缓存策略

4、缓存数据有两级:内存和磁盘,因此无需担心容量问题

5、缓存数据会在虚拟机重启的过程中写入磁盘

6、可以通过RMI、可插入API等方式进行分布式缓存

7、具有缓存和缓存管理器的侦听接口

8、支持多缓存管理器实例,以及一个实例的多个缓存区域

9、提供Hibernate的缓存实现

缺点:

1、使用磁盘Cache的时候非常占用磁盘空间:这是因为DiskCache的算法简单,该算法简单也导致Cache的效率非常高。它只是对元素直接追加存储。因此搜索元素的时候非常的快。如果使用DiskCache的,在很频繁的应用中,很快磁盘会满。

2、不能保证数据的安全:当突然kill掉java的时候,可能会产生冲突,EhCache的解决方法是如果文件冲突了,则重建cache。这对于Cache数据需要保存的时候可能不利。当然,Cache只是简单的加速,而不能保证数据的安全。如果想保证数据的存储安全,可以使用BekeleyDBJavaEdition版本。这是个嵌入式数据库。可以确保存储安全和空间的利用率。

九、Redis

redis是一个key-value存储系统。和Memcached类似,它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set()、zset(sortedset_有序)和hash(哈希类型)。这些数据类型都支持push/pop、add/remove及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的。在此基础上,redis支持各种不同方式的排序。与memcached一样,为了保证效率,数据都是缓存在内存中。区别的是redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了master-slave(主从)同步。

Redis数据库完全在内存中,使用磁盘仅用于持久性。相比许多键值数据存储,Redis拥有一套较为丰富的数据类型。Redis可以将数据复制到任意数量的从服务器。

1.2、Redis优点:

(1)异常快速:Redis的速度非常快,每秒能执行约11万,每秒约81000条记录。

(2)支持丰富的数据类型:Redis支持更大多数开发人员已经知道像列表,,有序,散列数据类型。这使得它非常容易解决各种各样的问题,因为我们知道哪些问题是可以处理通过它的数据类型更好。

(3)操作都是原子性:所有Redis操作是原子的,这保证了如果两个客户端同时访问的Redis服务器将获得更新后的值。

(4)多功能实用工具:Redis是一个多实用的工具,可以在多个用例如缓存,消息,队列使用(Redis原生支持发布/订阅),任何短暂的数据,应用程序,如Web应用程序会话,网页命中计数等。

1.3、Redis缺点:

(1)单线程

(2)耗内存

十、Shiro

ApacheShiro是Java的一个安全框架,旨在简化身份验证和授权。Shiro在JavaSE和JavaEE项目中都可以使用。它主要用来处理身份认证,授权,企业会话管理和加密等。Shiro的具体功能点如下:

(1)身份认证/登录,验证用户是不是拥有相应的身份;

(2)授权,即权限验证,验证某个已认证的用户是否拥有某个权限;即判断用户是否能做事情,常见的如:验证某个用户是否拥有某个角色。或者细粒度的验证某个用户对某个资源是否具有某个权限;

(3)会话管理,即用户登录后就是一次会话,在没有退出之前,它的所有信息都在会话中;会话可以是普通JavaSE环境的,也可以是如Web环境的;

(4)加密,保护数据的安全性,如密码加密存储到数据库,而不是明文存储;

(5)Web支持,可以非常容易的集成到Web环境;

Caching:缓存,比如用户登录后,其用户信息、拥有的角色/权限不必每次去查,这样可以提高效率;

(6)shiro支持多线程应用的并发验证,即如在一个线程中开启另一个线程,能把权限自动传播过去;

(7)提供测试支持;

(8)允许一个用户假装为另一个用户(如果他们允许)的身份进行访问;

(9)记住我,这个是非常常见的功能,即一次登录后,下次再来的话不用登录了。

返回列表

上一篇:mysql数据库告警

关于shiro 数据库配置文件的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站。


数据运维技术 » Shiro安全框架数据库配置文件详解 (shiro 数据库配置文件)