`
vvsuperman
  • 浏览: 27564 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

shiro多权限+spring+hibernate配置详解

    博客分类:
  • J2EE
阅读更多

其实不难,照着手册做就基本ok了,直接上代码,注释的很详细了

 

web.xml

 

  <?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<!-- Spring 刷新Introspector防止内存泄露 -->
<listener>
		<listener-class>
			org.springframework.web.util.IntrospectorCleanupListener
		</listener-class>
</listener>

<!--字符过滤器,统一使用utf-8编码 -->
	<filter>
		<filter-name>encodingFilter</filter-name>
		<filter-class>
			org.springframework.web.filter.CharacterEncodingFilter
		</filter-class>
		<init-param>
			<param-name>encoding</param-name>
			<param-value>UTF-8</param-value>
		</init-param>
		<init-param>
			<param-name>forceEncoding</param-name>
			<param-value>true</param-value>
		</init-param>
	</filter>
 
    <filter-mapping>
      <filter-name>encodingFilter</filter-name>
      <url-pattern>*</url-pattern>
    </filter-mapping>


 <listener>
  <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
 </listener>

<listener>  
        <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>  
</listener>

<!-- 配置常见错误页面 -->

		

 <servlet>
  <servlet-name>spring</servlet-name>
  <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
  <load-on-startup>1</load-on-startup>
 </servlet>
 <servlet-mapping>
  <servlet-name>spring</servlet-name>
  <url-pattern>/</url-pattern>
 </servlet-mapping>
 <welcome-file-list>
  <welcome-file>/page/bidhome.jsp</welcome-file>
 </welcome-file-list>
 <login-config>
  <auth-method>BASIC</auth-method>
 </login-config>
 

<!-- add to avoid "Write operations are not allowed in read-only mode (FlushMode.MANUAL)"" error -->
<filter> 
   <filter-name>openSessionInViewFilter</filter-name> 
   <filter-class> 
     org.springframework.orm.hibernate3.support.OpenSessionInViewFilter 
   </filter-class> 
   <init-param> 
    <param-name>sessionFactoryBeanName</param-name> 
    <param-value>sessionFactory</param-value> 
   </init-param> 
   <init-param> 
            <param-name>singleSession</param-name> 
            <param-value>true</param-value>            
        </init-param> 
        <init-param> 
        <param-name> flushMode </param-name> 
   <param-value>AUTO </param-value>         
        </init-param> 
</filter>



    <!-- Shiro Filter is defined in the spring application context: -->
    <filter>
        <filter-name>shiroFilter</filter-name>
        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    </filter>

    <filter-mapping>
        <filter-name>openSessionInViewFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <filter-mapping>
        <filter-name>shiroFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
 
</web-app>
 

 

 

 

applicationContext.xml

 

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:mvc="http://www.springframework.org/schema/mvc"
	xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:aop="http://www.springframework.org/schema/aop"
	xmlns:util="http://www.springframework.org/schema/util"
	
	
	xsi:schemaLocation="http://www.springframework.org/schema/beans 
	   		http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
	   		http://www.springframework.org/schema/context
	   		http://www.springframework.org/schema/context/spring-context-3.0.xsd
			http://www.springframework.org/schema/mvc 
			http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
			http://www.springframework.org/schema/tx  
    http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
    http://www.springframework.org/schema/aop  
    http://www.springframework.org/schema/aop/spring-aop.xsd
    http://www.springframework.org/schema/util
     http://www.springframework.org/schema/util/spring-util-3.0.xsd"> 

	
	//数据源
	<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
		<property name="driverClassName"
			value="oracle.jdbc.driver.OracleDriver">
		</property>
		<property name="url" value="jdbc:oracle:thin:@172.31.112.87:1521:biddb">
		</property>
		<property name="username" value="bid"></property>
		<property name ="password" value="bid"></property>
	</bean>
	
        //定义sessionFactory
	<bean id="sessionFactory"
		class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
		<property name="dataSource">
			<ref bean="dataSource" />
		</property>
		
		<property name="hibernateProperties">
			<props>
                <prop key="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</prop>
                <prop key="hibernate.show_sql">true</prop>
                <prop key="hibernate.format_sql">true</prop>
                <prop key="hibernate.jdbc.fetch_size">100</prop>
<!--                 <prop key="hibernate.hbm2ddl.auto">create</prop> -->
<!--                 <prop key="hibernate.cache.provider_class">net.sf.ehcache.hibernate.SingletonEhCacheProvider</prop> -->
            </props>
		</property>
				
		<property name="packagesToScan">
            <list>
                <value>com.bid.*</value>
            </list>
        </property>
     </bean>
	
	<!-- 声明一个 Hibernate 3 的事务管理器供代理类自动管理事务用 -->
	<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
		<property name="sessionFactory"><ref local="sessionFactory" /></property>
	</bean>
	
	
    <bean id="hibernateTemplate"  class="org.springframework.orm.hibernate3.HibernateTemplate">
        <property name="sessionFactory" ref="sessionFactory" />
    </bean>
	<!-- 激活spring的注解. -->
	<context:annotation-config />
	
	<!-- Spring AOP auto-proxy creation (required to support Shiro annotations) -->
    <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator">
        <property name="proxyTargetClass" value="true"/> 
    </bean>

<!--  事务控制 -->
   <tx:annotation-driven  transaction-manager="transactionManager" proxy-target-class="true"/>
        

	<!-- 扫描注解组件并且自动的注入spring beans中. 
	例如,他会扫描@Controller 和@Service下的文件.所以确保此base-package设置正确. -->
	<context:component-scan base-package="com.bid.*" />
	<context:component-scan base-package="com.bid.security" />
	

	<!-- 配置注解驱动的Spring MVC Controller 的编程模型.注:次标签只在 Servlet MVC工作! -->
	<mvc:annotation-driven />
	<!-- 用注解来实现事务管理 -->

	
	<mvc:resources location="/resources/" mapping="/resources/**"/>  
	
	 <!-- =========================================================
         Shiro Components
         ========================================================= -->


    <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>
     
    <!-- add on 05.08, shiro work well -->
    <bean
		class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
		<property name="securityManager" ref="securityManager" />
   </bean>
	
	
	<!-- Shiro's main business-tier object for web-enabled applications (use 
		org.apache.shiro.web.mgt.DefaultWebSecurityManager instead when there is 
		no web environment) -->
	<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">	
		<property name="realm" ref="BidRealm" />
		
<!-- 	    配置session超时,10分钟,session配置无效,原因未知		 -->
<!--          <property name="sessionManager.globalSessionTimeout" value="600000"></property> -->

<!-- Uncomment this next property if you want heterogenous session access 
			or clusterable/distributable sessions. The default value is 'http' which 
			uses the Servlet container's HttpSession as the underlying Session implementation. 
			<property name="sessionMode" value="native"/> -->
    </bean>
    
     <!-- Define the Shiro Filter here (as a FactoryBean) instead of directly in web.xml -
         web.xml uses the DelegatingFilterProxy to access this bean.  This allows us
         to wire things with more control as well utilize nice Spring things such as
         PropertiesPlaceholderConfigurer and abstract beans or anything else we might need: -->
    <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
        <property name="securityManager" ref="securityManager"/>
          <property name="unauthorizedUrl" value="/login"/>
        <property name="loginUrl" value="page/unauthorized.jsp"/>
        <property name="successUrl" value="home"/>
     
    </bean>
	</beans>

 

 进行认证和授权的realm

package com.uunemo.security;

import java.util.HashSet;
import java.util.Set;

import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authc.credential.Sha256CredentialsMatcher;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.uunemo.beans.Permission;
import com.uunemo.beans.Role;
import com.uunemo.beans.User;
import com.uunemo.daos.UserDAO;

/**
 * The Spring/Hibernate sample application's one and only configured Apache Shiro Realm.
 *
 * <p>Because a Realm is really just a security-specific DAO, we could have just made Hibernate calls directly
 * in the implementation and named it a 'HibernateRealm' or something similar.</p>
 *
 * <p>But we've decided to make the calls to the database using a UserDAO, since a DAO would be used in other areas
 * of a 'real' application in addition to here. We felt it better to use that same DAO to show code re-use.</p>
 */
@Component(value = "nemoRealm")
public class NemoRealm extends AuthorizingRealm {

    protected UserDAO userDAO = null;

    public NemoRealm() {
        setName("NemoRealm"); //This name must match the name in the User class's getPrincipals() method
//        setCredentialsMatcher(new Sha256CredentialsMatcher());
    }

    @Autowired
    public void setUserDAO(UserDAO userDAO) {
        this.userDAO = userDAO;
    }
   //登录时shiro会用到的方法
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken) throws AuthenticationException {
        UsernamePasswordToken token = (UsernamePasswordToken) authcToken;
        User user = (User)userDAO.findByName(token.getUsername()).get(0);
        if( user != null) {
            return new SimpleAuthenticationInfo(user.getUserid(), user.getPassword(), getName());
        } else {
            return null;
        }
    }

//权限验证
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
      //用的userid,当然也可以用username,
    	Integer userId = (Integer) principals.fromRealm(getName()).iterator().next();
        User user = userDAO.findById(userId);
        Set permissionSet = new HashSet<String>();
        if( user != null ) {
            SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
            for( Role role : user.getRoles() ) {
                info.addRole(role.getRoleName());
                permissionSet.clear();
                for(Permission permission:role.getPermissions()){
                	permissionSet.add(permission.getPermissionName());
                }
               //将当前用户的permission加入info
                info.addStringPermissions( permissionSet);
            }
            return info;
        } else {
            return null;
        }
    }
}

 

 然后就可以使用啦,代码片段如下

   

//若非法登录,sihro会报异常,尝试在web.xml里无法捕获,因此采用下述方法在spring中捕获,异常捕获页面,跳转到登录页面
	@ExceptionHandler(org.apache.shiro.authz.UnauthenticatedException.class)
	public String handleException(){
		return BIDHOME;
	}
	
	
	//异常捕获页面,跳转到登录页面
		@ExceptionHandler(org.apache.shiro.authz.AuthorizationException.class)
		public String handleException2(){
			return BIDHOME;
		}
		
		//异常捕获页面,跳转到登录页面	
		@ExceptionHandler(java.lang.IllegalStateException.class)
		public String handleIllgalException(){
			return BIDHOME;
		}
		/**
		 * shiro有时logout再login会报这个错,框架bug。
		 * stackflow解释it looks like your UI framework is not regenerating the session
		 * @return
		 */
		@ExceptionHandler(org.apache.shiro.session.InvalidSessionException.class)	
		   public String handleInvalidSession(){
			return BIDHOME;
		}		
		
	
	//shiro的权限控制,在这里控制user和superuser可以访问
		@RequiresRoles(value={ConstantUtil.ROLE_USER,ConstantUtil.ROLE_SUPERUSER},logical=Logical.OR)
		@RequestMapping(value="duraldaypage")
		public String duralDayPageController(Model model){
			String duralDay= bidService.findDuralDay();
			if(duralDay==null||duralDay.equals("")){
				duralDay="0";
				model.addAttribute("duralday",duralDay);
			}else{
				model.addAttribute("duralday",duralDay);
			}
			return SETDURALDAYPAGE;
		}
		

 为hibernate实现,给出实体类 User.java

 

    

package com.uunemo.beans;

import java.util.HashSet;
import java.util.Set;

import javax.annotation.Generated;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.Table;

/**
 * User entity. @author MyEclipse Persistence Tools
 */

@Entity
@Table(name="user")
public class User {

	// Fields
   
	private Integer userid;
	private String username;
	private String password;
    private String realname;
    private String schoolname;
    private String email;	
    
   
    private String company;
    
    
    
    private Set<Role> roles = new HashSet<Role>();
    
    
    @ManyToMany(
			targetEntity = com.uunemo.beans.Role.class,
			cascade = {CascadeType.PERSIST, CascadeType.MERGE },
			fetch=FetchType.EAGER)
	@JoinTable(
			name = "user_role",
			joinColumns = @JoinColumn(name = "user_id"),
			inverseJoinColumns = @JoinColumn(name = "role_id"))
	public Set<Role> getRoles() {
		return roles;
	}


	public void setRoles(Set<Role> roles) {
		this.roles = roles;
	}

	 @Id
	    @GeneratedValue
	    @Column(name = "user_id",unique =true,nullable=false)
	public Integer getUserid() {
		return userid;
	}


	public void setUserid(Integer userid) {
		this.userid = userid;
	}

	@Column(name="user_name",unique=true,length=100 )
	public String getUsername() {
		return username;
	}


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

	 @Column(name="password",length=100)
	public String getPassword() {
		return password;
	}


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

	 @Column(name="real_name",length=100)
	public String getRealname() {
		return realname;
	}


	public void setRealname(String realname) {
		this.realname = realname;
	}

	 @Column(name="school_name",length=100)
	public String getSchoolname() {
		return schoolname;
	}


	public void setSchoolname(String schoolname) {
		this.schoolname = schoolname;
	}

	 @Column(name="email",length=100)
	public String getEmail() {
		return email;
	}


	public void setEmail(String email) {
		this.email = email;
	}


   @Column(name="company",length=25)
    public String getCompany() {
		return company;
	}


	public void setCompany(String company) {
		this.company = company;
	}


	
    
    public User(Integer user_id, String user_name, String password,
			String real_name, String school_name, String email) {
		super();
		this.userid = user_id;
		this.username = user_name;
		this.password = password;
		this.realname = real_name;
		this.schoolname = school_name;
		this.email = email;
	}

    
    public User() {
		// TODO Auto-generated constructor stub
	}


	
	

}

 实体类Role.java

 

package com.uunemo.beans;

import java.util.HashSet;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.Table;

import com.uunemo.beans.Permission;

/**
 * Model object that represents a security role.
 */
@Entity
@Table(name="role")
public class Role {
    private int roleId;
    private String roleName;
    private Set<Permission> permissions = new HashSet<Permission>();

	@Id
	@GeneratedValue
	@Column(name="role_id",length=8,nullable=false)
    public int getId() {
        return roleId;
    }

	
    public void setId(int role_id) {
        this.roleId = role_id;
    }

    @Column(name="role_name",unique=true,length=20)
    public String getRoleName() {
        return roleName;
    }

    public void setRoleName(String role_name) {
        this.roleName = role_name;
    }
    
    
	@ManyToMany(targetEntity = com.uunemo.beans.Permission.class, cascade = {
			CascadeType.PERSIST, CascadeType.MERGE },
			fetch=FetchType.EAGER)
	@JoinTable(name = "role_permission", 
			joinColumns = @JoinColumn(name = "role_id"), 
			inverseJoinColumns = @JoinColumn(name = "permission_id"))
	public Set<Permission> getPermissions() {
		return permissions;
	}

	public void setPermissions(Set<Permission> permissions) {
		this.permissions = permissions;
	}

  
}

   

 

 

 

  

分享到:
评论
2 楼 jacking124 2013-04-18  
不错的,看看学习了!!
1 楼 chongzi0307 2013-03-11  
  最近也正在看,学习了。

相关推荐

    spring boot 使用jsp 集成hibernate+shiro+ehcache项目分享

    【Spring Boot 使用 JSP 集成 Hibernate+Shiro+Ehcache 项目详解】 Spring Boot 是一个基于 Spring 框架的高度集成了多种技术的开发工具,它简化了配置过程,使得开发人员能够快速构建可运行的应用程序。在这个项目...

    将_Shiro_作为应用的权限基础_五:SpringMVC+Apache_Shiro+JPA(hibernate)整合配置

    ### 将Shiro作为应用的权限基础五:SpringMVC+Apache Shiro+JPA(hibernate)整合配置 本文旨在详细介绍如何将Apache Shiro整合到基于SpringMVC和JPA(hibernate)的应用程序中,为系统提供安全控制机制。通过本...

    图书管理系统(struts+hibernate+spring).rar

    SSH(Struts+Spring+Hibernate)是一个常见的Java Web开发框架组合,它集成了MVC模式的Struts、依赖注入与事务管理的Spring以及持久层的Hibernate,为开发人员提供了强大的工具支持。本系统——"图书管理系统(struts...

    tianyu:spring+springmvc+hibernate+shiro+maven+easyui

    《构建企业级Web应用:Spring、SpringMVC、Hibernate、Shiro、Maven与EasyUI集成详解》 在现代企业级Web开发中,一个高效、稳定的框架组合是至关重要的。"tianyu"项目整合了Spring、SpringMVC、Hibernate、Shiro、...

    SpringMVC+Shiro权限管理.

    ### SpringMVC+Shiro权限管理系统详解 #### 权限管理概述 权限管理在软件开发中扮演着至关重要的角色,特别是在涉及多用户交互的应用场景下。通过合理的权限控制,可以确保不同用户仅能访问和操作他们被授权的功能...

    从零开始学Spring Boot

    1.1 前言 1.2 资料官网 1.3 spring boot起步之Hello World 1.4 Spring Boot返回json数据 1.5 Spring Boot热部署 1.6 Spring Boot使用别的json解析框架 1.7 全局异常捕捉 ...1.45 Spring Boot Shiro权限管理

    基于SpringBoot+Hibernate+Shiro的库存管理系统后端.zip

    《构建基于SpringBoot+Hibernate+Shiro的库存管理系统后端详解》 在现代软件开发中,企业级应用的构建越来越倾向于轻量级、快速开发的框架。本项目以"基于SpringBoot+Hibernate+Shiro的库存管理系统后端.zip"为例,...

    SSH整合Shiro源码

    在SSH_Shiro压缩包中,可能包含了一个完整的整合示例,包括了Spring、Struts2、Hibernate的配置文件、Shiro配置、Realm实现以及相关的Action和视图文件。通过研究这些示例代码,可以帮助你更好地理解和掌握SSH与...

    基于Hibernate,Spring,Spring mvc,Bootstrap的管理系统实现

    7. 安全管理:Spring Security或Apache Shiro等安全框架可以集成到项目中,实现用户的登录验证、权限控制等功能,保证系统安全。 8. 测试:JUnit和Mockito等工具可用于编写单元测试,确保代码质量,而Spring Boot的...

    rapidsh-SSH经典整合框架-包括权限管理-文件上传下载-用户管理-分页-lookup

    **权限管理**:在SSH框架中,通常会利用Spring Security(原Acegi)或者Apache Shiro来实现权限控制。这些安全框架提供了角色、权限的概念,可以对用户的访问权限进行精细化控制,确保系统安全。 **文件上传下载**...

    通用权限管理的后台源码

    Spring Security或Apache Shiro可能是实现权限管理的工具,它们提供了丰富的功能,如认证、授权、会话管理等。 三、Spring Security详解 1. 认证(Authentication):验证用户的身份,通常通过用户名和密码进行。...

    基于SpringBoot的权限管理系统.zip

    在权限管理方面,SpringBoot结合Spring Security或Apache Shiro等安全框架,可以轻松实现用户认证与授权。 首先,我们来了解Spring Security。这是一个强大的、高度可定制的身份验证和访问控制框架,它提供了一套...

    权限管理系统 AuthorityManagementSystem SSH

    在具体实现过程中,开发者可能需要使用到Spring Security或Apache Shiro这样的安全框架,它们提供了丰富的权限控制策略,如角色、权限、URL过滤等,能够方便地集成到SSH框架中,实现细粒度的权限控制。 总的来说,...

    hibernate基础 快速入门 一

    - **Shiro:** 权限管理框架。 - **Apache CXF:** Web服务框架。 #### 二、学习框架的方法 1. **理解框架的核心价值:** 明确框架解决的问题。 2. **快速入门:** 通过一个简单的“Hello World”项目快速熟悉框架的...

    SpringBoot基于Shiro处理ajax请求代码实例

    Shiro框架可以与多种框架和技术集成,例如Spring、Hibernate、Struts等。 Shiro在SpringBoot中的应用 在SpringBoot中,Shiro框架可以用于身份验证和授权。通过使用Shiro,开发者可以轻松地实现用户身份验证和权限...

    这是个基于java语言SSH框架的考试系统.zip

    SSH框架中,Spring的Security或Apache Shiro可以用于实现权限控制。 2. **试题库模块**:试题的创建、分类、修改、删除等功能。Hibernate在此负责存储和检索试题,Struts2处理相关请求并展示结果。 3. **考试模块*...

    全套Java、Android、HTML5前端视频教程

    - Hibernate配置与映射文件。 - 查询语言与缓存机制。 - **Spring4视频教程** - Spring框架核心容器。 - AOP与事务管理。 - MVC框架及集成测试。 - **SSH整合&综合案例视频** - Struts2+Spring+Hibernate...

    ssh 投票系统

    此外,Spring的AOP特性可用于实现日志记录、权限控制等跨切面关注点。 3. **Hibernate框架** Hibernate是一个持久化框架,简化了数据库操作。它提供了一种对象关系映射(Object-Relational Mapping,ORM)机制,将...

    基于SSH版的购物商城源码

    - 可能采用Spring Security或Shiro进行安全控制,防止SQL注入、XSS攻击等安全问题。 - 使用缓存技术(如Spring Cache或Hibernate二级缓存)优化性能,减少数据库访问。 6. **开发流程**: - 设计数据库表结构,...

    基于SSH的宠物医院项目源码

    这通常通过角色-权限的关联模型实现,例如在Spring Security或Apache Shiro框架中配置权限控制。 7. **文档数据库**:项目中可能包含需求文档、设计文档、数据库脚本等,帮助理解项目背景、功能和数据库结构。这些...

Global site tag (gtag.js) - Google Analytics