ssm+shiro+freemarker。关键字:ftl。(作为了解即可,主要了解ssm+shiro+jsp标签这篇笔记)

本案例和ssm+shiro+jsp标签这篇文章几乎没差别,差别主要在于spring.xml文件中controller跳转的前后缀的区别以及使用的页面的不同,这个案例页面是ftl,那个案例是jsp页面,并且jsp页面可以写shiro标签


步骤一:在pom.xml文件中导入依赖

 <spring.version>4.3.25.RELEASE</spring.version>
    <shiro.version>1.2.2</shiro.version>





 <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
    </dependency>



    <!-- 德鲁伊数据连接池 -->
    <dependency>
      <groupId>com.alibaba</groupId>
      <artifactId>druid</artifactId>
      <version>1.0.9</version>
    </dependency>
    <!--shiro相关依赖-->
    <dependency>
      <groupId>org.apache.shiro</groupId>
      <artifactId>shiro-core</artifactId>
      <version>${shiro.version}</version>
    </dependency>

    <dependency>
      <groupId>org.apache.shiro</groupId>
      <artifactId>shiro-web</artifactId>
      <version>${shiro.version}</version>
    </dependency>

    <dependency>
      <groupId>org.apache.shiro</groupId>
      <artifactId>shiro-ehcache</artifactId>
      <version>${shiro.version}</version>
    </dependency>


    <dependency>
      <groupId>org.apache.shiro</groupId>
      <artifactId>shiro-spring</artifactId>
      <version>${shiro.version}</version>
    </dependency>


    <!--spring ioc/di-->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-core</artifactId>
      <version>${spring.version}</version>
    </dependency>

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>${spring.version}</version>
    </dependency>

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-beans</artifactId>
      <version>${spring.version}</version>
    </dependency>

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-expression</artifactId>
      <version>${spring.version}</version>
    </dependency>

    <!-- spring - aop -->

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-aop</artifactId>
      <version>${spring.version}</version>
    </dependency>

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-aspects</artifactId>
      <version>${spring.version}</version>
    </dependency>

    <dependency>
      <groupId>aopalliance</groupId>
      <artifactId>aopalliance</artifactId>
      <version>1.0</version>
    </dependency>

    <dependency>
      <groupId>org.aspectj</groupId>
      <artifactId>aspectjweaver</artifactId>
      <version>1.8.10</version>
    </dependency>

    <dependency>
      <groupId>cglib</groupId>
      <artifactId>cglib</artifactId>
      <version>3.2.4</version>
    </dependency>


    <!-- spring tx-->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-tx</artifactId>
      <version>${spring.version}</version>
    </dependency>

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-jdbc</artifactId>
      <version>${spring.version}</version>
    </dependency>

    <!--web项目  -->

    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>3.1.0</version>
    </dependency>

    <dependency>
      <groupId>javax.servlet.jsp</groupId>
      <artifactId>jsp-api</artifactId>
      <version>2.2</version>
    </dependency>

    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>jstl</artifactId>
      <version>1.2</version>
    </dependency>

    <!--spring整合web项目 -->

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-web</artifactId>
      <version>${spring.version}</version>
    </dependency>


    <!--springmvc -->

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>${spring.version}</version>
    </dependency>

    <!-- json -->
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-databind</artifactId>
      <version>2.8.9</version>
    </dependency>

    <!-- 文件上传-->
    <dependency>
      <groupId>commons-fileupload</groupId>
      <artifactId>commons-fileupload</artifactId>
      <version>1.3.1</version>
    </dependency>

    <dependency>
      <groupId>commons-io</groupId>
      <artifactId>commons-io</artifactId>
      <version>2.4</version>
    </dependency>


    <!--数据库相关 -->
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>5.1.48</version>
    </dependency>

    <dependency>
      <groupId>com.mchange</groupId>
      <artifactId>c3p0</artifactId>
      <version>0.9.5.2</version>
    </dependency>

    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis</artifactId>
      <version>3.4.5</version>
    </dependency>

    <!-- 缓存-->
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis-ehcache</artifactId>
      <version>1.0.0</version>
    </dependency>

    <dependency>
      <groupId>net.sf.ehcache</groupId>
      <artifactId>ehcache-core</artifactId>
      <version>2.6.5</version>
    </dependency>

    <dependency>
      <groupId>com.github.pagehelper</groupId>
      <artifactId>pagehelper</artifactId>
      <version>4.1.6</version>
    </dependency>

    <!-- mybatis整合spring  -->
    <!-- https://mvnrepository.com/artifact/org.mybatis/mybatis-spring -->
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis-spring</artifactId>
      <version>1.3.2</version>
    </dependency>


    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context-support</artifactId>
      <version>${spring.version}</version>
    </dependency>

    <dependency>
      <groupId>com.yunpian.sdk</groupId>
      <artifactId>yunpian-java-sdk</artifactId>
      <version>1.2.7</version>
    </dependency>


    <!-- quartz -->



    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context-support</artifactId>
      <version>${spring.version}</version>
    </dependency>


    <dependency>
      <groupId>com.yunpian.sdk</groupId>
      <artifactId>yunpian-java-sdk</artifactId>
      <version>1.2.7</version>
    </dependency>


    <!-- freemarker-->

    <dependency>
      <groupId>org.freemarker</groupId>
      <artifactId>freemarker</artifactId>
      <version>2.3.23</version>
    </dependency>




  </dependencies>


步骤二:在resources文件夹创建mybatis-config.xml配置文件

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <!--给类起别名,默认是包下的类名首字母小写,后面字母不变就是它对应的别名。这个别名是给mapper文件省略类路径用的,如parameter、resultType等。基本类型mybatis已经七号别名了,因此只用管我们自建的实体类即可-->
    <!--<typeAliases>
        &lt;!&ndash;<typeAlias type="com.entity.Student" alias="abc"></typeAlias>&ndash;&gt;
        <package name="com.qf.entity"></package>
    </typeAliases>-->

    <!--   &lt;!&ndash;展示出mapper文件中执行的sql语句的详细情况&ndash;&gt;
   <settings>
       <setting name="logImpl" value="STDOUT_LOGGING"></setting>
   </settings>-->

    <!--插件写在plugins标签中,这里使用的就是分页插件-->
    <plugins>
        <plugin interceptor="com.github.pagehelper.PageHelper">
            <property name="dialect" value="mysql"/>
        </plugin>
    </plugins>
</configuration>



步骤三:在resouces下创建spring.xml配置文件.设置freemarker的controller层跳转的前后缀

<?xml version="1.0" encoding="UTF-8"?>
<!--加p、tx、mvc、context命名空间-->
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
                           http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
                           http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
                           http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/tx
                           http://www.springframework.org/schema/tx/spring-tx.xsd">



    <!--连接数据库,即创建数据库连接对象-->
    <bean id="db" class="com.alibaba.druid.pool.DruidDataSource"><!--druid连接池包路径,其他两个连接池路径自己不知道可以网上找找。找到评论留言,分享给其他人吧-->
        <property name="username" value="root"></property><!--你连接的数据库的用户名-->
        <property name="password" value="root"></property><!--连接的数据库的密码-->
        <property name="url" value="jdbc:mysql://localhost:3306/shiroweb"></property><!--连接的数据库的地址,此处的数据库名叫hospital-->
        <property name="driverClassName" value="com.mysql.jdbc.Driver"></property><!--根据使用的数据库连接池以及数据库,找对应的连接池,三种连接池,druid,c3p0,dbcp。去百度吧。此处用的druid连接池和myql数据库-->
    </bean>
    <!--用context命名空间扫描注解包-->
    <context:component-scan base-package="com"><!--扫描com包下的所有注解,这个com包是我们自定义的,我们创建的所有java类都放在该包下面,具体可见最下面的案例框架图的com包的位置--></context:component-scan>
    <!--创建InternalResourceViewResolver视图解析器,注意下面这四行,尤其是前后缀的这两行会影响你在跳转页面的前后缀名,如return "/index.jsp",在使用这两句前后缀语句后,只需return "index"即可-->
    <!--<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">-->
        <!--<property name="prefix" value="/"></property> &lt;!&ndash;return跳转页面时加前缀&ndash;&gt;-->
        <!--<property name="suffix" value=".jsp"></property>&lt;!&ndash;加后缀&ndash;&gt;-->
    <!--</bean>-->
    <!--用MVC命名空间加注解驱动-->
    <mvc:annotation-driven></mvc:annotation-driven><!--也是用于转换json必不可少的部分,另一个就是jackson包-->
    <!--创建sqlsesion工厂,专门读取xml文件的-->
    <bean id="factory" class="org.mybatis.spring.SqlSessionFactoryBean"><!--org.mybatis.spring.SqlSessionFactoryBean整合了mybatis和sring中的sqlsession-->
        <property name="dataSource" ref="db"></property><!--将数据库连接赋进dataSource属性中-->
        <property name="mapperLocations" value="classpath:mapper/*.xml"></property><!--mapper文件下的所有xml文件,不然创建一个扫描一个。此处*.xml爆红代表你mapper文件夹下还没创建xml文件-->
        <property name="configLocation" value="classpath:mybatis-config.xml"></property><!--加载mybatis-config.xml配置文件-->
    </bean>
    <!--使用dao层实现类的时候,需要得到sqlSessionTemplate对象
      <bean class="org.mybatis.spring.SqlSessionTemplate">
          <constructor-arg index="0" ref="factory"></constructor-arg>&lt;!&ndash;将上面创建好的sqlsesion对象当成SqlSessionTemplate类的一个构造参数&ndash;&gt;
      </bean>-->
    <!--6.省略dao实现类,扫描dao层的接口-->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="com.qf.dao"></property>
        <property name="sqlSessionFactoryBeanName" value="factory" ></property>
    </bean>
    <bean id="tx" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="db"></property>
    </bean>
    <tx:advice id="ad"  transaction-manager="tx" ></tx:advice><!--id必须起个名字-->

    <!--8.配置静态资源,如果不写,静态资源无法显示在网页中。这段话是根据后缀名判断是否是静态资源的,这是其优势也是劣势。当controller的RequestMapping的请求地址为jsp时可测试出来。这是因为我们在web.xml文件中拦截了除jsp外的所有静态资源,而所有资源走的都是dispatcherservlet,然后dispatcherservlet会去找到handler,这也是为什么最终由RequestMapping请求路径后缀来判断-->
    <mvc:default-servlet-handler></mvc:default-servlet-handler>


    <!--freemarker解析器-->
        <bean id="configruration"
              class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
            <!-- 模板放置的位置  / classpath resources-->
            <property name="templateLoaderPath" value="/" /><!--"/"表示ftl模板文件必须放在webapp下。ftl模板放在WEB-INF下的ftl文件夹下时value=/WEB-INF/ftl/,这表示ftl模板文件的位置-->
            <property name="defaultEncoding" value="UTF-8" />
        </bean>

        <!-- 页面访问。访问ftl模板文件时,他会自动编译成html文件-->
        <bean class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver"><!--使用了freemarker视图解析器则必须把InternalResourceViewResolver这个springmvc的视图解析器去掉-->
            <property name="contentType" value="text/html;charset=utf-8"/>
            <property name="prefix" value="/" /><!--前缀,此时省略也没事-->
            <property name="suffix" value=".ftl" /><!--controller层跳转的后缀,当index.ftl模板文件放在webapp下时访问路径:http://localhost:8080/index.ftl-->
        </bean>

</beans>

步骤四:自定义realm,继承AuthorizingRealm类

package com.qf.realm;

import com.qf.entity.User;
import com.qf.service.UserService;
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.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.Controller;
import javax.annotation.Resource;
import java.util.Set;

//shiro 授权和赋予角色都是在自定义realm中完成的,这也是使用shiro的核心。这也是shiro和数据库建立连接的核心,因为这里用户的角色和权限都是调用service层查询数据库得到的信息,因此applicationContxt-shiro.xml和spring.xml配置文件一定要放在一起,都放在contextlistener中加载,不然因为这个realm类先加载,会导致service无法正常注入
public class MyRealm extends AuthorizingRealm{
    @Autowired
    private UserService userService;//当这个为null,是因为spring.xml这个文件在applicationContxt-shiro.xml之后加载的,是配置shiro配置文件加载顺序有问题,我直接全放在contextLoaderListener加载配置文件

    //授权。根据用户名查询用户对应的角色,然后根据角色查询对应的权限,并将角色和权限通过set方法设置给shiro框架。其次授权的前提是一定认证了
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        User user=(User)principals.getPrimaryPrincipal();//获取用户信息
        Set<String> roles=userService.selectRolesByUsername(user.getUsername());//根据用户名查询用户对应的角色
        System.out.println("roles = " + roles);
        Set<String> permissions=userService.selectPermissionsByRoles(roles);//根据用户角色查询权限
        System.out.println("permissions = " + permissions);
        SimpleAuthorizationInfo simpleAuthorizationInfo=new SimpleAuthorizationInfo();
        simpleAuthorizationInfo.setRoles(roles);//设置角色
        simpleAuthorizationInfo.setStringPermissions(permissions);//设置权限
        return simpleAuthorizationInfo;
    }

    //注意自定义的realm中执行sql语句对应的方法即使出错也不会报异常
    //认证。该方法主要用于通过用户输入的账号查询数据库对应的用户信息,传递真实密码。并将查到的用户信息传给上面的授权方法,给用户进行授权
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        String username = (String)token.getPrincipal();//通过token获取用户输入的账号, token.getCredentials()才是获取密码
        User user = (User) userService.selectUserByUsername(username);
        System.out.println("user:"+user);
        if (user == null) {//这代表根据账号没查到
            return null;
        }else {//这代表根据账号查到了用户信息
            SimpleAuthenticationInfo authenticationInfo=new SimpleAuthenticationInfo(user,user.getPassword(),"myrealm");//将用户信息传给调用自定义realm的controller类那。第一个参数是用户信息,controller层可通过subject.getpricinple获取,一般显示登录用户名用;第二个是用户密码,这个就是调用这个realm的securityManager底层比对密码的真实密码;第三个是随便的一个名字
            return authenticationInfo;
        }

    }
}


步骤五:在resouces下创建applicationContxt-shiro.xml配置文件,配置自定义realm、securityManager、拦截哪些地址资源等信息。即配置shiro信息,整合shiro的核心文件

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


    <!-- 该文件需要配realm、 secritymanager即shiro三大组成部分的其中两个,另外一个是subject -->

    <!-- realm -->
    <bean id="myrealm" class="com.qf.realm.MyRealm"><!--告诉shiro过滤器我们自定义的realm在哪-->
         <!-- 此处写密码匹配,使用什么加密-->
    </bean>

    <!-- 自定义退出登陆 -->
    <bean id="logout" class="org.apache.shiro.web.filter.authc.LogoutFilter">
          <property name="redirectUrl" value="/userftl/login" /><!--shiro自带的退出登录,此处表示/userftl/login就是触发shiro自带的突出登录的请求地址-->
    </bean>

    <!--创建securityManager对象-->
    <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
          <property name="realm" ref="myrealm" />
    </bean>


    <!-- 创建shiro过滤器,用于授权管理。intercepter拦截器是spring所独有的,因此shiro底层授权用的是过滤器-->
    <!-- 授权管理 -->
    <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">

        <property name="securityManager" ref="securityManager" />

        <!--配置登录页面,认证不通过的会自动跳转到这个页面-->
        <property name="loginUrl" value="/userftl/login" /><!--loginUrl对应的值是shiro自带的登录页面,/userftl/login这个请求地址是我们自己写的,它对应的处理方法就只有跳转登录页面-->

        <!-- 配置被拦截的未授权时跳转的页面-->
        <property name="unauthorizedUrl" value="/userftl/403" /><!--/userftl/403这个请求地址在这个案例中它对应的方法就只写了个跳转去未授权页面的-->

        <!--配置过滤链,这才是shiro拦截的核心,定义请求地址被那种方式访问。anon代表匿名地址即不登录就可以访问的;authc代表公共访问地址,需要授权才能访问-->
        <!--anon定义的是不用登录(认证)就可以访问的请求地址,authc是必须登录(认证)才能放行。anon和authc其实就是两个不同条件的过滤器,本质就是过滤器-->
        <property name="filterChainDefinitions">
            <!--格式:  请求地址=anon   ,反正左侧就是资源(请求地址、静态资源),右侧就是申明请求地址的类型-->
            <value>
                /test=anon
                /userftl/login=anon
                /user/login=anon
                /=anon    <!--/代表项目启动后访问的默认页面-->
                /userftl/403=anon
                <!-- 静态资源一定要设置为匿名资源-->
                /css/**=anon
                /font/**=anon
                /image/**=anon
                /js/**=anon
                /store/**=anon
                /user/logout=logout
<!--                授权的前提一定是已经认证过了,这是shiro默认的,也就意味着想接触授权的地址,一定是用户已经登录了
                 roles[1,2]同时需要拥有两个角色才可以访问 ! and的关系
    -->
                /productftl/add=roles[管理员]  <!--roles[管理员]代表只有被授予管理员角色的才能访问,如果为roles[管理员,普通用户]代表要同时是管理员又是普通用户才能访问的请求地址-->
                <!--请求地址=perms[权限1,权限2]-->
                /**=authc        <!--/** 代表拦截所有路径,除了上面被定义为匿名地址的请求路径-->
            </value>
        </property>
    </bean>

</beans>

步骤六:配置WEB-INF下的web.xml文件,加载配置文件以及加载shiro的全局过滤器,只有配置了这个全局过滤器拦截才生效

<?xml version="1.0" encoding="UTF-8"?>
<web-app 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_3_0.xsd"
         version="3.0"><!--头部信息换成3.0,不然</async-supported>会报错,-->



  <display-name>Archetype Created Web Application</display-name>
  <!--利用DispatcherServlet核心类加载spring.xml配置文件-->
  <servlet>
    <servlet-name>aa</servlet-name><!--与servlet-mapping中的servlet-name要保持一致-->
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value></param-value><!--只有DispatcherServlet才能加载spring.xml文件,因为他是子容器,子容器能访问父容器-->
    </init-param>
  </servlet>


  <servlet-mapping>
    <servlet-name>aa</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>


    <!--一定要用ContextLoaderListener加载applicationContxt-shiro.xml配置文件,不然会报错-->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:spring.xml,classpath:applicationContxt-shiro.xml</param-value><!--applicationContxt-shiro.xml一定要在ContextLoaderListener中加载,因为这是父容器。父容器先加载-->
    </context-param>


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




    <!--用于初始化shiro中的所有过滤器-->
    <filter>
        <filter-name>shiroFilter</filter-name>
        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
        <async-supported>true</async-supported>
        <init-param>
            <param-name>targetFilterLifecycle</param-name>
            <param-value>true</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>shiroFilter</filter-name>
        <url-pattern>/*</url-pattern><!--/*代表过滤所有请求,只有拦截完了,我们才好在applicationContxt-shiro.xml中去决定放行哪些请求-->
    </filter-mapping>


  <!--处理post乱码,设置字符集-->
  <filter>
    <filter-name>bb</filter-name><!--与下面的filter-mapping中的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>
  </filter>

  <filter-mapping>
    <filter-name>bb</filter-name>
    <url-pattern>/*</url-pattern><!--给所有文件设置字符集-->
  </filter-mapping>





</web-app>







本次案例ssm+shiro+jsp标签框架就搭配完了,下面就开始案例的书写



步骤七:创建案例要使用的controller层、service层、dao层以及数据库表对应的实体类

数据库表对应的实体类
第一个实体类:User

package com.qf.entity;

import java.util.List;

public class User {
    private Integer uid;

    private String username;

    private String password;

    private String nickname;

    List<Role>  roles;

    public List<Role> getRoles() {
        return roles;
    }

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

    public Integer getUid() {
        return uid;
    }

    public void setUid(Integer uid) {
        this.uid = uid;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username == null ? null : username.trim();
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password == null ? null : password.trim();
    }

    public String getNickname() {
        return nickname;
    }

    public void setNickname(String nickname) {

        this.nickname = nickname == null ? null : nickname.trim();
    }

    @Override
    public String toString() {
        return "User{" +
                "uid=" + uid +
                ", username='" + username + '\'' +
                ", password='" + password + '\'' +
                ", nickname='" + nickname + '\'' +
                ", roles=" + roles +
                '}';
    }
}

第二个实体类:Role

package com.qf.entity;

import java.util.List;

public class Role {
    private Integer rid;

    private String rname;

    private String rinfo;

    private List<Permission> permissions;

    public List<Permission> getPermissions() {
        return permissions;
    }

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

    public Integer getRid() {
        return rid;
    }

    public void setRid(Integer rid) {
        this.rid = rid;
    }

    public String getRname() {
        return rname;
    }

    public void setRname(String rname) {
        this.rname = rname == null ? null : rname.trim();
    }

    public String getRinfo() {
        return rinfo;
    }

    public void setRinfo(String rinfo) {

        this.rinfo = rinfo == null ? null : rinfo.trim();
    }

    @Override
    public String toString() {
        return "Role{" +
                "rid=" + rid +
                ", rname='" + rname + '\'' +
                ", rinfo='" + rinfo + '\'' +
                ", permissions=" + permissions +
                '}';
    }
}

第三个实体类:Permission

package com.qf.entity;

public class Permission {
    private Integer pid;

    private String pname;

    private String paction;

    private String pinfo;

    public Integer getPid() {
        return pid;
    }

    public void setPid(Integer pid) {
        this.pid = pid;
    }

    public String getPname() {
        return pname;
    }

    public void setPname(String pname) {
        this.pname = pname == null ? null : pname.trim();
    }

    public String getPaction() {
        return paction;
    }

    public void setPaction(String paction) {
        this.paction = paction == null ? null : paction.trim();
    }

    public String getPinfo() {
        return pinfo;
    }

    public void setPinfo(String pinfo) {
        this.pinfo = pinfo == null ? null : pinfo.trim();
    }
}

controller层的类:
本案例controller层的重点类:UserController

package com.qf.controller;

import com.qf.entity.User;
import com.qf.service.UserService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.support.SessionStatus;

import javax.annotation.Resource;

@RequestMapping("/user")
@Controller
public class UserController {
    @Resource
    private UserService userService;

    @RequestMapping("/login")
    public String login(User user, ModelMap modelMap){// User封装登录页面表单传过来的用户名和密码
        String  path="login";//注意这种用变量表示路径的方式
        UsernamePasswordToken usernamePasswordToken=new UsernamePasswordToken(user.getUsername(),user.getPassword());//user.getUsername()为用户输入的账号,user.getPassword()为用户输入的密码
        Subject subject = SecurityUtils.getSubject();//获取用户对象
        try{
            subject.login(usernamePasswordToken);//shiro底层完成登录验证
            path="home";
            User loginUser = (User)subject.getPrincipal();//获取在自定义realm中想传过来的值;jsp页面中的shiro标签获取到的就是认证后的信息
            modelMap.addAttribute("user",loginUser);
            return path;
        }catch (Exception e){
            User user2 = (User) userService.selectUserByUsername(user.getUsername());
            modelMap.addAttribute("msg","认证失败");
            return path;
        }
    }
    @RequestMapping("/logout")
    public String logout(ModelMap modelMap, SessionStatus sessionStatus){
        sessionStatus.setComplete();
        modelMap.addAttribute("msg","退出登录成功");
        return "login";
    }
}

第二个controller类:ProductFtlController,用于测试页面用的

package com.qf.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
@RequestMapping("/productftl")
public class ProductFtlController {
    @RequestMapping("/show")
    public  String jumpShow(){
        return  "show";
    }
    @RequestMapping("/add")
    public String humpAdd(){
        return "show";
    }
}

第三个controller类:UserFtlController,用于跳转页面的

package com.qf.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
@RequestMapping("/userftl")
public class UserFtlController {
    @RequestMapping("/403")
    public String jump403(){
        System.out.println("UserFtlController.jump403");
        return "403";
    }

    @RequestMapping("/home")
    public String jumpHome(){
        System.out.println("UserFtlController.jumpHome");
        return "home";
    }
    @RequestMapping("login")
    public String jumpLogin(){
        System.out.println("UserFtlController.jumpLogin");
        return "login";
    }
}

service层的接口及其实现类:
service层接口:UserService

package com.qf.service;

import com.qf.entity.User;

import java.util.List;
import java.util.Map;
import java.util.Set;

public interface UserService {
public User selectUserByUsername(String username);

    public   Set<String> selectRolesByUsername(String username);

    public Set<String> selectPermissionsByRoles(Set<String> roles);
}

service层UserService对应的实现类:UserServiceImpl

package com.qf.service.impl;

import com.qf.dao.UserDao;
import com.qf.entity.User;
import com.qf.service.UserService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.Set;

@Service
public class UserServiceImpl implements UserService {
    @Resource
    private UserDao userDao;
    @Override
    public User selectUserByUsername(String username) {
        User user = userDao.selectUserAndRolesAndPerminssion(username);
        return user;
    }

    @Override
    public Set<String> selectRolesByUsername(String username) {
        //根据用户名查询 角色信息
        Set<String> roles = userDao.selectRolesByUsername(username);
        return roles;
    }

    @Override
    public Set<String> selectPermissionsByRoles(Set<String> roles) {
        //根据角色查权限信息
        Set<String> permissions = userDao.selectPermissionsByRoles(roles);
        return permissions;
    }
}

dao层的接口:

package com.qf.dao;

import com.qf.entity.User;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Map;
import java.util.Set;
@Component
public interface UserDao {
public User  selectUserAndRolesAndPerminssion(String username);//根据用户名查询用户

    Set<String> selectRolesByUsername(String username);//根据用户名查询角色

    Set<String> selectPermissionsByRoles(Set<String> roles);//根据用户角色查询权限
}


步骤八:在resouces文件夹下创建mapper文件夹,用于写dao层对应的sql语句

在mapper文件夹下创建本次案例dao层对应的sql语句的xml文件:userMapper.xml

<?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.qf.dao.UserDao">
  <resultMap id="BaseResultMap" type="com.qf.entity.User">
    <id column="uid" jdbcType="INTEGER" property="uid" />
    <result column="username" jdbcType="VARCHAR" property="username" />
    <result column="PASSWORD" jdbcType="VARCHAR" property="password" />
    <result column="nickname" jdbcType="VARCHAR" property="nickname" />
  </resultMap>


  <resultMap id="selectUserAndRolesAndPerminssion" type="com.qf.entity.User">
    <id column="uid" jdbcType="INTEGER" property="uid" />
    <result column="username" jdbcType="VARCHAR" property="username" />
    <result column="PASSWORD" jdbcType="VARCHAR" property="password" />
    <result column="nickname" jdbcType="VARCHAR" property="nickname" />
      <collection property="roles" ofType="com.qf.entity.Role">
          <id column="rid" jdbcType="INTEGER" property="rid" />
          <result column="rname" jdbcType="VARCHAR" property="rname" />
          <result column="rinfo" jdbcType="VARCHAR" property="rinfo" />
          <collection property="permissions" ofType="com.qf.entity.Permission">
              <id column="pid" jdbcType="INTEGER" property="pid" />
              <result column="pname" jdbcType="VARCHAR" property="pname" />
              <result column="paction" jdbcType="VARCHAR" property="paction" />
              <result column="pinfo" jdbcType="VARCHAR" property="pinfo" />
          </collection>
      </collection>
  </resultMap>
  <select id="selectUserAndRolesAndPerminssion" resultMap="selectUserAndRolesAndPerminssion">
    SELECT u.*,r.*,p.* FROM user u JOIN  user_role ur ON u.uid=ur.uid
                                    JOIN  role r ON ur.rid=r.rid
                                    JOIN role_permission rp on  rp.rid=r.rid
                                    JOIN permission p on rp.pid=p.pid
                                    WHERE  u.username=#{username}
  </select>

    <select id="selectUserByUsername" resultMap="selectUserAndRolesAndPerminssion">
        SELECT u.*,r.*,p.* FROM user u JOIN  user_role ur ON u.uid=ur.uid
        JOIN  role r ON ur.rid=r.rid
        JOIN role_permission rp on  rp.rid=r.rid
        JOIN permission p on rp.pid=p.pid
        WHERE  u.username=#{username}
    </select>

    <!--因为返回的结果类型为String类型,因此 resultMap="String"-->
    <select id="selectRolesByUsername" resultType="java.lang.String" >
        SELECT r.rname from USER u JOIN  user_role ur on u.uid =ur.uid
                                    JOIN role r ON ur.rid=r.rid
                                    WHERE  u.username=#{username}
    </select>

    <select id="selectPermissionsByRoles" resultType="java.lang.String" >

        SELECT p.pname FROM  role r join role_permission rp on r.rid = rp.rid
        join permission p on rp.pid = p.pid
        where  r.rname in
        <foreach collection="collection" open="("  close=")" separator="," item="rname">
            #{rname}
        </foreach>

    </select>


</mapper>

步骤九:在webapp下定义本次案例用到的ftl模板文件

第一个ftl文件:login.ftl

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <meta http-equiv="X-UA-Compatible" content="IE=9; IE=8; IE=7; IE=EDGE"/>
    <title>商城展示登陆页面</title>
    <link rel="stylesheet" href="/css/index.css" type="text/css"/>
    <link href="/css/layui.css" rel="stylesheet" type="text/css"/>
    <script src="/js/common/jquery-1.8.3.js" type="text/javascript"></script>
    <script src="/js/layui.js" type="text/javascript"></script>


    <style type="text/css">
        html,body{
            height: 100%;
            width: 100%;
        }
    </style>

</head>
<body>

<div class="container" style="height: 100%">
    <center>



        <form class="layui-form" action="/user/login"  method="post" lay-filter="example" style="padding-top: 12%">

            <div class="layui-form-item">
                <label class="layui-form-label layui-col-sm-offset4 layui-col-sm1" >账号:</label>
                <div class="layui-input-block  layui-col-sm4" >
                    <input type="text" name="username" lay-verify="title" autocomplete="off" placeholder="请输入账号!" class="layui-input">
                </div>
            </div>
            <div class="layui-form-item">
                <label class="layui-form-label layui-col-sm-offset3 layui-col-sm1">密码:</label>
                <div class="layui-input-block layui-col-sm4">
                    <input type="password" name="password" placeholder="请输入密码!" autocomplete="off" class="layui-input">
                </div>
            </div>



            <div class="layui-form-item">
                <div class="layui-input-block">
                    <button type="button" class="layui-btn layui-btn-normal" id="LAY-component-form-getval">注册</button>
                    <button type="submit" class="layui-btn" lay-submit="" lay-filter="demo1">登陆</button>
                </div>
            </div>
        </form>

        <font color="red" size="5">${msg!"欢迎登陆!"}</font>

    </center>
</body>

</html>

第二个ftl模板文件:home.ftl

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <meta http-equiv="X-UA-Compatible" content="IE=9; IE=8; IE=7; IE=EDGE"/>
    <title>大众点评后台管理</title>
    <link rel="stylesheet" href="/css/index.css" type="text/css"/>
    <link href="/css/layui.css" rel="stylesheet" type="text/css"/>
    <script src="/js/common/jquery-1.8.3.js" type="text/javascript"></script>
    <script src="/js/layui.js" type="text/javascript"></script>


    <style type="text/css">
          html,body{
              height: 100%;
              width: 100%;
          }
    </style>

</head>
<body>

<div class="container" style="height: 100%">

    <div id="head" class="layui-bg-blue" style="height: 7%">
        <ul class="layui-nav">
            <div style="float: right;">
                <li class="layui-nav-item">
                    <a href="">控制台<span class="layui-badge">9</span></a>
                </li>
                <li class="layui-nav-item">
                    <a href="">个人中心<span class="layui-badge-dot"></span></a>
                </li>
                <li class="layui-nav-item">
                    <a href=""><img src="http://www.baidu.com/img/bd_logo.png" class="layui-nav-img">${user.nickname}</a>
                    <dl class="layui-nav-child">
                        <dd><a href="/user/logout">退出登陆</a></dd>
                    </dl>
                </li>
            </div>

        </ul>

    </div>

    <div id="content" style="height: 93%;">
        <div id="left" class="layui-col-md1" style="height: 100%">

            <ul class="layui-nav layui-nav-tree " lay-filter="test" style="height: 100%;width: 100%;">
                <!-- 侧边导航: <ul class="layui-nav layui-nav-tree layui-nav-side"> -->
                <#list  user.roles as role>
                   <li class="layui-nav-item" >
                       <a href="javascript:;">${role.rname}</a>
                       <dl class="layui-nav-child">
                           <#list role.permissions as permission><#--role.permissions此地mapper文件没映射好导致此处为空,页面不出效果,疯狂报错-->
                               <dd><a data="${permission.paction}" href="${permission.paction}" onclick="navchick(this)">${permission.pname}</a></dd>
                           </#list>
                       </dl>
                   </li>
                </#list>
                <#--<#list user.roles as role>-->

                    <#--<li class="layui-nav-item" >-->
                        <#--<a href="javascript:;">${role.rname}</a>-->
                        <#--<dl class="layui-nav-child">-->
                            <#--<#list role.permissions as permission>-->
                            <#--<dd><a data="${permission.paction}" href="${permission.paction}" >${permission.pname}</a></dd>-->
                            <#--</#list>-->
                        <#--</dl>-->
                    <#--</li>-->

                <#--</#list>-->



            </ul>


        </div>
        <div id="right" class="layui-col-md11" style="height: 100%">

                <div class="layui-tab" lay-allowClose="true" lay-filter="test1" style="height: 7%">
                    <ul class="layui-tab-title">
						<!-- 显示的tab的-->
                       <!-- <li class="layui-this" lay-id="111" >文章列表</li> -->

                    </ul>
                    <div class="layui-tab-content" style="height: 93%">
                     </div>

                </div>


        </div>

    </div>


</div>

</body>
<script>

    var element;
    layui.use('element', function(){
		//element操作导航条
        element = layui.element;
    });



    /*
       点击左侧导航条进行切换!item中data属性包含对应要跳转的路径!
       添加右侧对应的切换tab!并且添加添加显示内容对应的iframe!
       添加之前先要进行判断是否存在,tab id使用data属性设置!如果存在tabchange
       如果不存在!添加!并显示状态class="layui-this"
     */
    function navchick(item) {
		// 就是路径  tab data
        var data =  $(item).attr('data');  //获取的data属性
		//展示
        var text =  $(item).text();  //获取文本内容
        //查看data作为id是否出现 如果出现就切换  没有出现就添加
		//横着的列表
        var titleli_list = $(".layui-tab-title li");

        var exist = false;  //默认不存在

        titleli_list.each(function(){

            var temp = $(this).attr("lay-id");

            if (temp == data) {
                exist = true;
                return false;
            }

        });

        console.log(exist)

        if(exist){
            //如果存在,切换到对应位置即可
		//存在 切换
              //切换
			  //c参数1 : lay-filter
			  //参数2: tab的id

        }else{
            var iframe_id = 'i'+data;   //id
            var iframe_src = data;//src内容

            //如果不存在,创建内容内别换显示
            //创建并切换
            element.tabAdd('test1',{
                title:text,
                id:data,
                content:"<iframe id='+' src='-' frameborder=\"0\" height=\"100%\" width=\"100%\"></iframe>".replace('+',iframe_id).replace('-',iframe_src)
            });


        }

        element.tabChange("test1",data);

    }

</script>
</html>

第三个ftl模板文件:403.ftl

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <meta http-equiv="X-UA-Compatible" content="IE=9; IE=8; IE=7; IE=EDGE"/>
    <title>商城展示403</title>
    <link rel="stylesheet" href="/css/index.css" type="text/css"/>
    <link href="/css/layui.css" rel="stylesheet" type="text/css"/>
    <script src="/js/common/jquery-1.8.3.js" type="text/javascript"></script>
    <script src="/js/layui.js" type="text/javascript"></script>


    <style type="text/css">
        html,body{
            height: 100%;
            width: 100%;
        }
    </style>

</head>
<body>

<div class="container" style="height: 100%">
          <center>

              <h1>您没有权限!</h1>

          </center>
</body>
</html>

第四个ftl模板文件:show.ftl

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <meta http-equiv="X-UA-Compatible" content="IE=9; IE=8; IE=7; IE=EDGE"/>
    <title>商城展示</title>
    <link rel="stylesheet" href="/css/index.css" type="text/css"/>
    <link href="/css/layui.css" rel="stylesheet" type="text/css"/>
    <script src="/js/common/jquery-1.8.3.js" type="text/javascript"></script>
    <script src="/js/layui.js" type="text/javascript"></script>


    <style type="text/css">
        html,body{
            height: 100%;
            width: 100%;
        }
    </style>

</head>
<body>

<div class="container" style="height: 100%">
    <center>

        <h1>展示页面!</h1>

    </center>
</div>
</body>
</html>

第五个ftl模板文件:add.ftl

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <meta http-equiv="X-UA-Compatible" content="IE=9; IE=8; IE=7; IE=EDGE"/>
    <title>商城展示403</title>
    <link rel="stylesheet" href="/css/index.css" type="text/css"/>
    <link href="/css/layui.css" rel="stylesheet" type="text/css"/>
    <script src="/js/common/jquery-1.8.3.js" type="text/javascript"></script>
    <script src="/js/layui.js" type="text/javascript"></script>


    <style type="text/css">
        html,body{
            height: 100%;
            width: 100%;
        }
    </style>

</head>
<body>

<div class="container" style="height: 100%">
    <center>

        <h1>添加页面</h1>

    </center>
</div>
</body>
</html>


案例结构图:
在这里插入图片描述
本次案例用到的数据库:shiroweb

/*
SQLyog Ultimate v12.09 (64 bit)
MySQL - 5.5.40 : Database - shiroweb
*********************************************************************
*/


/*!40101 SET NAMES utf8 */;

/*!40101 SET SQL_MODE=''*/;

/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
CREATE DATABASE /*!32312 IF NOT EXISTS*/`shiroweb` /*!40100 DEFAULT CHARACTER SET utf8 */;

USE `shiroweb`;

/*Table structure for table `permission` */

DROP TABLE IF EXISTS `permission`;

CREATE TABLE `permission` (
  `pid` int(11) NOT NULL AUTO_INCREMENT COMMENT '权限主键',
  `pname` varchar(20) NOT NULL COMMENT '权限的名称',
  `paction` varchar(100) NOT NULL COMMENT '权限的路径',
  `pinfo` varchar(200) DEFAULT NULL COMMENT '权限的描述',
  PRIMARY KEY (`pid`),
  UNIQUE KEY `pname` (`pname`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;

/*Data for the table `permission` */

insert  into `permission`(`pid`,`pname`,`paction`,`pinfo`) values (1,'商品添加','/productftl/add','aaa'),(2,'商品展示','/product/ftl/show','商品展示功能,认证用户随便访问');

/*Table structure for table `product` */

DROP TABLE IF EXISTS `product`;

CREATE TABLE `product` (
  `pid` varchar(96) DEFAULT NULL,
  `pname` varchar(150) DEFAULT NULL,
  `market_price` double DEFAULT NULL,
  `shop_price` double DEFAULT NULL,
  `pimage` varchar(600) DEFAULT NULL,
  `pdate` date DEFAULT NULL,
  `pdesc` varchar(765) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

/*Data for the table `product` */

insert  into `product`(`pid`,`pname`,`market_price`,`shop_price`,`pimage`,`pdate`,`pdesc`) values ('51','小米 4c 标准版',1399,1299,'products/1/c_0001.jpg','2015-11-02','小米 4c 标准版 全网通 白色 移动联通电信4G手机 双卡双待'),('10','华为 Ascend Mate7',2699,2599,'products/1/c_0010.jpg','2015-11-02','华为 Ascend Mate7 月光银 移动4G手机 双卡双待双通6英寸高清大屏,纤薄机身,智能超八核,按压式指纹识别!!选择下方“移动老用户4G飞享合约”,无需换号,还有话费每月返还!'),('51','小米 4c 标准版',1399,1299,'products/1/c_0001.jpg','2015-11-02','小米 4c 标准版 全网通 白色 移动联通电信4G手机 双卡双待'),('17','华为 Ascend Mate7',2699,2599,'products/1/c_0010.jpg','2015-11-02','华为 Ascend Mate7 月光银 移动4G手机 双卡双待双通6英寸高清大屏,纤薄机身,智能超八核,按压式指纹识别!!选择下方“移动老用户4G飞享合约”,无需换号,还有话费每月返还!'),('18','vivo X5Pro',2399,2298,'products/1/c_0014.jpg','2015-11-02','移动联通双4G手机 3G运存版 极光白【购机送蓝牙耳机+蓝牙自拍杆】新升级3G运行内存·双2.5D弧面玻璃·眼球识别技术'),('19','努比亚(nubia)My 布拉格',1899,1799,'products/1/c_0013.jpg','2015-11-02','努比亚(nubia)My 布拉格 银白 移动联通4G手机 双卡双待【嗨11,下单立减100】金属机身,快速充电!布拉格相机全新体验!'),('27','华为 麦芒4',2599,2499,'products/1/c_0012.jpg','2015-11-02','华为 麦芒4 晨曦金 全网通版4G手机 双卡双待金属机身 2.5D弧面屏 指纹解锁 光学防抖'),('28','vivo X5M',1899,1799,'products/1/c_0011.jpg','2015-11-02','vivo X5M 移动4G手机 双卡双待 香槟金【购机送蓝牙耳机+蓝牙自拍杆】5.0英寸大屏显示·八核双卡双待·Hi-Fi移动KTV'),('29','Apple iPhone 6 (A1586)',4399,4288,'products/1/c_0015.jpg','2015-11-02','Apple iPhone 6 (A1586) 16GB 金色 移动联通电信4G手机长期省才是真的省!点击购机送费版,月月送话费,月月享优惠,畅享4G网络,就在联通4G!'),('51','小米 4c 标准版',1399,1299,'products/1/c_0001.jpg','2015-11-02','小米 4c 标准版 全网通 白色 移动联通电信4G手机 双卡双待'),('17','华为 Ascend Mate7',2699,2599,'products/1/c_0010.jpg','2015-11-02','华为 Ascend Mate7 月光银 移动4G手机 双卡双待双通6英寸高清大屏,纤薄机身,智能超八核,按压式指纹识别!!选择下方“移动老用户4G飞享合约”,无需换号,还有话费每月返还!'),('32','vivo X5Pro',2399,2298,'products/1/c_0014.jpg','2015-11-02','移动联通双4G手机 3G运存版 极光白【购机送蓝牙耳机+蓝牙自拍杆】新升级3G运行内存·双2.5D弧面玻璃·眼球识别技术'),('33','努比亚(nubia)My 布拉格',1899,1799,'products/1/c_0013.jpg','2015-11-02','努比亚(nubia)My 布拉格 银白 移动联通4G手机 双卡双待【嗨11,下单立减100】金属机身,快速充电!布拉格相机全新体验!'),('34','华为 麦芒4',2599,2499,'products/1/c_0012.jpg','2015-11-02','华为 麦芒4 晨曦金 全网通版4G手机 双卡双待金属机身 2.5D弧面屏 指纹解锁 光学防抖'),('35','vivo X5M',1899,1799,'products/1/c_0011.jpg','2015-11-02','vivo X5M 移动4G手机 双卡双待 香槟金【购机送蓝牙耳机+蓝牙自拍杆】5.0英寸大屏显示·八核双卡双待·Hi-Fi移动KTV'),('36','Apple iPhone 6 (A1586)',4399,4288,'products/1/c_0015.jpg','2015-11-02','Apple iPhone 6 (A1586) 16GB 金色 移动联通电信4G手机长期省才是真的省!点击购机送费版,月月送话费,月月享优惠,畅享4G网络,就在联通4G!'),('51','小米 4c 标准版',1399,1299,'products/1/c_0001.jpg','2015-11-02','小米 4c 标准版 全网通 白色 移动联通电信4G手机 双卡双待'),('17','华为 Ascend Mate7',2699,2599,'products/1/c_0010.jpg','2015-11-02','华为 Ascend Mate7 月光银 移动4G手机 双卡双待双通6英寸高清大屏,纤薄机身,智能超八核,按压式指纹识别!!选择下方“移动老用户4G飞享合约”,无需换号,还有话费每月返还!'),('45','vivo X5Pro',2399,2298,'products/1/c_0014.jpg','2015-11-02','移动联通双4G手机 3G运存版 极光白【购机送蓝牙耳机+蓝牙自拍杆】新升级3G运行内存·双2.5D弧面玻璃·眼球识别技术'),('40','努比亚(nubia)My 布拉格',1899,1799,'products/1/c_0013.jpg','2015-11-02','努比亚(nubia)My 布拉格 银白 移动联通4G手机 双卡双待【嗨11,下单立减100】金属机身,快速充电!布拉格相机全新体验!'),('41','华为 麦芒4',2599,2499,'products/1/c_0012.jpg','2015-11-02','华为 麦芒4 晨曦金 全网通版4G手机 双卡双待金属机身 2.5D弧面屏 指纹解锁 光学防抖'),('42','vivo X5M',1899,1799,'products/1/c_0011.jpg','2015-11-02','vivo X5M 移动4G手机 双卡双待 香槟金【购机送蓝牙耳机+蓝牙自拍杆】5.0英寸大屏显示·八核双卡双待·Hi-Fi移动KTV'),('43','Apple iPhone 6 (A1586)',8888,4288,'products/1/c_0015.jpg','2015-11-02','Apple iPhone 6 (A1586) 16GB 金色 移动联通电信4G手机长期省才是真的省!点击购机送费版,月月送话费,月月享优惠,畅享4G网络,就在联通4G!'),('51','小米 4c 标准版',1399,1299,'products/1/c_0001.jpg','2015-11-02','小米 4c 标准版 全网通 白色 移动联通电信4G手机 双卡双待'),('17','华为 Ascend Mate7',2699,2599,'products/1/c_0010.jpg','2015-11-02','华为 Ascend Mate7 月光银 移动4G手机 双卡双待双通6英寸高清大屏,纤薄机身,智能超八核,按压式指纹识别!!选择下方“移动老用户4G飞享合约”,无需换号,还有话费每月返还!'),('46','vivo X5Pro',2399,2298,'products/1/c_0014.jpg','2015-11-02','移动联通双4G手机 3G运存版 极光白【购机送蓝牙耳机+蓝牙自拍杆】新升级3G运行内存·双2.5D弧面玻璃·眼球识别技术'),('47','努比亚(nubia)My 布拉格',1899,1799,'products/1/c_0013.jpg','2015-11-02','努比亚(nubia)My 布拉格 银白 移动联通4G手机 双卡双待【嗨11,下单立减100】金属机身,快速充电!布拉格相机全新体验!'),('48','华为 麦芒4',2599,2499,'products/1/c_0012.jpg','2015-11-02','华为 麦芒4 晨曦金 全网通版4G手机 双卡双待金属机身 2.5D弧面屏 指纹解锁 光学防抖'),('49','vivo X5M',1899,1799,'products/1/c_0011.jpg','2015-11-02','vivo X5M 移动4G手机 双卡双待 香槟金【购机送蓝牙耳机+蓝牙自拍杆】5.0英寸大屏显示·八核双卡双待·Hi-Fi移动KTV'),('50','Apple iPhone 6 (A1586)',4399,4288,'products/1/c_0015.jpg','2015-11-02','Apple iPhone 6 (A1586) 16GB 金色 移动联通电信4G手机长期省才是真的省!点击购机送费版,月月送话费,月月享优惠,畅享4G网络,就在联通4G!'),('51','小米 4c 标准版',1399,1299,'products/1/c_0001.jpg','2015-11-02','小米 4c 标准版 全网通 白色 移动联通电信4G手机 双卡双待'),('17','华为 Ascend Mate7',2699,2599,'products/1/c_0010.jpg','2015-11-02','华为 Ascend Mate7 月光银 移动4G手机 双卡双待双通6英寸高清大屏,纤薄机身,智能超八核,按压式指纹识别!!选择下方“移动老用户4G飞享合约”,无需换号,还有话费每月返还!');

/*Table structure for table `role` */

DROP TABLE IF EXISTS `role`;

CREATE TABLE `role` (
  `rid` int(11) NOT NULL AUTO_INCREMENT COMMENT '角色的主键',
  `rname` varchar(20) NOT NULL COMMENT '角色名称',
  `rinfo` varchar(100) DEFAULT NULL COMMENT '角色的描述',
  PRIMARY KEY (`rid`),
  UNIQUE KEY `rname` (`rname`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;

/*Data for the table `role` */

insert  into `role`(`rid`,`rname`,`rinfo`) values (1,'用户','一个管理员'),(2,'管理员','哈哈'),(4,'超级管理员','有所有权限');

/*Table structure for table `role_permission` */

DROP TABLE IF EXISTS `role_permission`;

CREATE TABLE `role_permission` (
  `rp_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '角色和权限表的主键',
  `rid` int(11) DEFAULT NULL COMMENT '角色表主键',
  `pid` int(11) DEFAULT NULL COMMENT '权限表主键',
  PRIMARY KEY (`rp_id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;

/*Data for the table `role_permission` */

insert  into `role_permission`(`rp_id`,`rid`,`pid`) values (1,1,2),(2,2,1),(3,2,2);

/*Table structure for table `user` */

DROP TABLE IF EXISTS `user`;

CREATE TABLE `user` (
  `uid` int(11) NOT NULL AUTO_INCREMENT COMMENT '用户的主键',
  `username` varchar(30) NOT NULL COMMENT '用户账号',
  `PASSWORD` varchar(200) NOT NULL COMMENT '用户密码',
  `nickname` varchar(20) DEFAULT '二狗子' COMMENT '用户昵称',
  PRIMARY KEY (`uid`),
  UNIQUE KEY `username` (`username`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;

/*Data for the table `user` */

insert  into `user`(`uid`,`username`,`PASSWORD`,`nickname`) values (1,'customer','1111','二狗子'),(2,'admin','1111','二狗子');

/*Table structure for table `user_role` */

DROP TABLE IF EXISTS `user_role`;

CREATE TABLE `user_role` (
  `ur_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '用户和角色的中间表主键',
  `uid` int(11) DEFAULT NULL COMMENT '用户的id',
  `rid` int(11) DEFAULT NULL COMMENT '角色的id',
  PRIMARY KEY (`ur_id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;

/*Data for the table `user_role` */

insert  into `user_role`(`ur_id`,`uid`,`rid`) values (1,1,1),(2,2,2);

/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值