zoukankan      html  css  js  c++  java
  • SSM整合开发

    Spring + Spring MVC + Mybatis 整合

    实现SSM的登录、注册功能。

    首先对SSM框架有一个整体意识

    建立目录结构:

    controller service mapper 三者关系:

    调用:controller --> service --> mapper

    返回:mapper --> service  --> controller 

    controller:作为请求转发,调用service接口处理逻辑,页面所有路径的访问方法:控制层的命名空间+@RequestMapping的value
    service:接口,处理业务逻辑(impl里面实现,调用mapper操作数据库)
    mapper:操作数据库的接口

    第一,导入springspring mvcmybatis所需要的包

    第二,配置applicationContext.xml

     1 <!-- 配置包扫描 -->
     2     <context:component-scan base-package="com.krry"></context:component-scan>
     3         
     4     <!-- 导入外部资源文件 -->
     5     <!-- <context:property-placeholder location="classpath:jdbc.properties" />  -->
     6     <bean class="com.krry.core.des.EncryptPropertyPlaceholderConfigurer"
     7         p:location="classpath:db/jdbc.properties" p:fileEncoding="utf-8" />
     8         
     9     <!-- proxool连接池 -->
    10     <bean id="dataSource" class="org.logicalcobwebs.proxool.ProxoolDataSource">
    11         <!-- 驱动的名字,mysql -->
    12         <property name="driver" value="${db.driver}"></property>
    13         <!--proxool 的 url连接串,这个必须确定用户名和密码 -->
    14         <property name="driverUrl" value="${db.url}"></property>
    15         <!-- 用户名(proxool没有使用,但是不能没有) -->
    16         <property name="user" value="${db.username}"></property>
    17         <!-- 密码(proxool没有使用,但是不能没有) -->
    18         <property name="password" value="${db.password}"></property>
    19         <!-- proxool自动侦察各个连接状态的时间间隔(毫秒),侦察到空闲的连接就马上回收,超时的销毁 现在设置为4秒) -->
    20         <property name="houseKeepingSleepTime" value="3000"></property><!-- 自动检查连接是否断掉开关 -->
    21         <property name="testBeforeUse" value="true"></property>
    22         <!--  如果发现了空闲的数据库连接.house keeper 将会用这个语句来测试.这个语句最好非常快的被执行.如果没有定义,测试过程将会被忽略 -->
    23         <property name="houseKeepingTestSql" value="SELECT count(1) from dual"></property>
    24         <!--  如果housekeeper 检测到某个线程的活动时间大于这个数值.它将会杀掉这个线程.所以确认一下你的服务器的带宽.然后定一个合适的值.默认是5分钟. 现在设置 10 秒--> 
    25         <property name="maximumActiveTime" value="10000"></property>
    26         <!-- 最少保持的空闲连接数 (现在设置20个) -->
    27         <property name="prototypeCount" value="20"></property>
    28         <!-- 最大连接数 (现在设置100个) -->
    29         <property name="maximumConnectionCount" value="200"></property>
    30         <!-- 最小连接数 (现在设置50个) -->
    31         <property name="minimumConnectionCount" value="50"></property>
    32         <!-- 如果为true,那么每个被执行的SQL语句将会在执行期被log记录(DEBUG LEVEL).你也可以注册一个ConnectionListener (参看ProxoolFacade)得到这些信息. -->
    33         <property name="trace" value="false"></property>
    34         <property name="verbose" value="true"></property>
    35     </bean>
    36     
    37     <!-- 注册事务管理器 -->
    38     <bean id="txMgr"
    39         class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    40         <property name="dataSource" ref="dataSource"></property>
    41     </bean>
    42 
    43     <!-- 开启事务注解驱动 -->
    44     <tx:annotation-driven transaction-manager="txMgr" />
    45     
    46     <!-- 配置mybatis的sqlSessionFactory -->
    47     <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
    48         <property name="dataSource" ref="dataSource"></property>
    49         <property name="configLocation" value="classpath:mybatis-config.xml"></property>
    50     </bean>
    51     
    52     <!-- 配置可以整体扫描Mapper的一个扫描器 -->
    53     <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
    54         <!--如果有多个报路径,用逗号分开即可  -->
    55         <property name="basePackage" value="com.krry.mapper"></property>
    56         <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property>
    57     </bean>

    第三,配置springmvc.xml

      1 <?xml version="1.0" encoding="UTF-8" ?>
      2 <beans xmlns="http://www.springframework.org/schema/beans"
      3     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
      4     xmlns:p="http://www.springframework.org/schema/p"
      5     xmlns:context="http://www.springframework.org/schema/context"
      6     xmlns:util="http://www.springframework.org/schema/util" 
      7     xmlns:mvc="http://www.springframework.org/schema/mvc"
      8     xsi:schemaLocation="http://www.springframework.org/schema/beans
      9        http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
     10        http://www.springframework.org/schema/context 
     11        http://www.springframework.org/schema/context/spring-context-3.0.xsd
     12        http://www.springframework.org/schema/util 
     13        http://www.springframework.org/schema/util/spring-util-3.0.xsd 
     14        http://www.springframework.org/schema/mvc 
     15        http://www.springframework.org/schema/mvc/spring-mvc.xsd
     16       ">
     17    
     18          <!-- 开启注解模式驱动 -->    
     19         <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" /> 
     20         <!-- 开启mvc的注解模式 user 还会注册一个ConversionService 子类FormattingConversionServiceFactoryBean-->
     21          <mvc:annotation-driven>
     22             <mvc:message-converters register-defaults="true">
     23                 <bean class="com.krry.core.UTF8StringHttpMessageConverter">
     24                     <property name="supportedMediaTypes">
     25                         <list>  
     26                             <value>text/plain;charset=UTF-8</value>  
     27                             <value>text/html;charset=UTF-8</value>  
     28                         </list>  
     29                     </property>
     30                 </bean> 
     31                 <bean class="org.springframework.http.converter.BufferedImageHttpMessageConverter"/>
     32                 <bean class="org.springframework.http.converter.ByteArrayHttpMessageConverter"/> 
     33                 <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
     34                     <property name="prefixJson" value="false" />
     35                     <property name="objectMapper">
     36                          <bean class="com.fasterxml.jackson.databind.ObjectMapper">
     37                                <!-- 处理responseBody 里面日期类型 --> 
     38                                <property name="dateFormat">  
     39                                    <bean class="java.text.SimpleDateFormat">  
     40                                        <constructor-arg type="java.lang.String" value="yyyy-MM-dd HH:mm:ss" />  
     41                                    </bean>  
     42                                </property> 
     43                                <!-- 为null字段时不显示 -->
     44                                <property name="serializationInclusion">
     45                                    <value type="com.fasterxml.jackson.annotation.JsonInclude.Include">NON_NULL</value>
     46                                </property> 
     47                            </bean>  
     48                     </property>
     49                      <property name="supportedMediaTypes">  
     50                         <list>  
     51                             <value>application/json;charset=UTF-8</value>  
     52                             <value>application/x-www-form-urlencoded;charset=UTF-8</value>  
     53                         </list>  
     54                     </property>
     55                 </bean>
     56                 </mvc:message-converters> 
     57         </mvc:annotation-driven>
     58         
     59          <!-- 扫包 -->
     60          <context:component-scan base-package="com.krry.controller"></context:component-scan>
     61          
     62          <!--对静态资源文件的访问  必须要设置,因为在springmvc的配置中配置了/匹配所有请求,
     63         此工程所有的请求(.do ,addUser,js/image/css)都会被springmvc解析,
     64         必须对所有的静态资源文件进行过滤放行 -->
     65       <!-- 静态资源过滤  下面二选一-->
     66       <!--<mvc:default-servlet-handler/> -->
     67       <mvc:resources mapping="/resourse/**" location="/resourse/" />
     68       
     69       <!-- 拦截器定义 -->
     70       <mvc:interceptors>    
     71           <mvc:interceptor>
     72              <!-- 个人中心也需要登陆  以admin开头的配置都会进行拦截-->
     73                <mvc:mapping path="/admin/**"></mvc:mapping> 
     74                    <!-- 这个是设置不会进入拦截器的路径 -->
     75                    <mvc:exclude-mapping path="/resourse/**"/>
     76             <!-- 拦截器进入的类,返回false表示不会进入输入的路径 -->
     77             <bean class="com.krry.core.filter.LoginInterceptor" />       
     78           </mvc:interceptor>
     79       </mvc:interceptors>
     80        
     81            <!-- 配置文件解析器 -->
     82         <bean id="multipartResolver"
     83             class="org.springframework.web.multipart.commons.CommonsMultipartResolver"
     84             p:defaultEncoding="utf-8">
     85             <property name="uploadTempDir" value="/temp"></property>
     86             <property name="maxUploadSize">
     87                 <value>209715200</value><!-- 200MB -->
     88             </property>
     89             <property name="maxInMemorySize">
     90                 <value>4096</value><!-- 4KB大小读写 -->
     91             </property>
     92         </bean>
     93            
     94    
     95        <!-- 视图渲染 jsp/freemaker/velocity-->
     96        <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
     97                <!-- 制定页面存放的路径 -->
     98                <property name="prefix" value="/WEB-INF/pages/"></property>
     99                <!-- 文件的后缀 -->
    100                <property name="suffix" value=".jsp"></property>
    101        </bean> 
    102     
    103 </beans>

    第四,配置mybatis-config.xml

     1 <configuration> 
     2     <settings>  
     3          <!-- 全局映射器启用缓存 -->  
     4         <setting name="cacheEnabled" value="true" />  
     5          <!-- 查询时,关闭关联对象即时加载以提高性能 -->  
     6         <setting name="lazyLoadingEnabled" value="true" />  
     7         <!-- 设置关联对象加载的形态,此处为按需加载字段(加载字段由SQL指定),不会加载关联表的所有字段,以提高性能 -->  
     8         <setting name="aggressiveLazyLoading" value="false" />  
     9         <!-- 对于未知的SQL查询,允许返回不同的结果集以达到通用的效果 -->  
    10         <setting name="multipleResultSetsEnabled" value="true" />  
    11         <!-- 允许使用列标签代替列名 -->  
    12         <setting name="useColumnLabel" value="true" />  
    13         <!-- 允许使用自定义的主键值(比如由程序生成的UUID 32位编码作为键值),数据表的PK生成策略将被覆盖 -->  
    14         <setting name="useGeneratedKeys" value="true" />  
    15          <!-- 给予被嵌套的resultMap以字段-属性的映射支持 -->  
    16         <setting name="autoMappingBehavior" value="FULL" />  
    17         <!-- 对于批量更新操作缓存SQL以提高性能  -->  
    18         <setting name="defaultExecutorType" value="BATCH" />  
    19          <!-- 数据库超过25000秒仍未响应则超时 -->  
    20         <setting name="defaultStatementTimeout" value="25" />  
    21          <setting name="lazyLoadTriggerMethods" value="equals,clone,hashCode,toString"/>
    22     </settings>  
    23     
    24     <typeAliases>
    25         <!--自定义user对象的别名  -->
    26         <!-- <typeAlias type="com.krry.mybatis.sysmanage.entity.User" alias="user"/> -->
    27         <!-- 批量定义别名 -->
    28         <package name="com.krry.entity" />
    29     </typeAliases>
    30 
    31     <!-- 配置pageHelper分页插件 -->
    32     <plugins>
    33         <plugin interceptor="com.github.pagehelper.PageHelper">
    34             <!-- 设置数据库类型 Oracle,Mysql,MariaDB,SQLite,Hsqldb,PostgreSQL六种数据库 -->
    35             <property name="dialect" value="mysql" />
    36             <!--当设置为true的时候,如果pagesize设置为0 就不执行分页,返回全部结果 -->
    37             <property name="pageSizeZero" value="true" />
    38             <!--合理化查询 比如如果pageNum<1会查询第一页;如果pageNum>pages会查询最后一页(设置为false返回空) -->
    39             <property name="reasonable" value="false" />
    40             <!-- 支持通过Mapper接口参数来传递分页参数 -->
    41             <property name="supportMethodsArguments" value="false" />
    42             <!-- 总是返回PageInfo类型,check检查返回类型是否为PageInfo,none返回Page -->
    43             <property name="returnPageInfo" value="none" />
    44         </plugin>
    45     </plugins>
    46     
    47     
    48 </configuration>

    在mybatis相应的xml文件配置mybatis的sql文件和mapper转换器(也就是说的mapper下面的接口) 注入到sqlSessionFactory (放入到内存中)

    1.  mapper的xml中,这里的命名空间可以随便定义(必须唯一),但是为了方便,定义成mapper包下的类的目录,调用mapper下面类的接口方法的时候,调用的路径是:mapper包下的类的目录+方法名,即是与这个命名空间+id一样,自动用了这个sql语句(id对应这个类的接口里面的方法)这里面必定有executeQuery方法,会执行这条sql语句。

    2.  如果自己自定义名命名空间,调用下面的sql语句的方法为:在mapper里的方法执行以下语句:
    SqlSession session = sessionFactory.openSession();
    List<User> users = session.selectList("命名空间+id");   //根据实际结果集类型和sql语句类型,写这条代码就可以获取结果集

    推荐使用第一种命名方式。

     mybatis执行流程:

    第五,配置web.xml

     1 <?xml version="1.0" encoding="UTF-8"?>
     2 <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
     3   
     4   <display-name>krry_SSM</display-name>
     5   
     6   <welcome-file-list>
     7     <welcome-file>index</welcome-file>
     8   </welcome-file-list>
     9   
    10   <!-- 加载Spring IOC容器 -->
    11   <context-param>
    12     <param-name>contextConfigLocation</param-name>
    13     <param-value>classpath:spring/applicationContext*.xml</param-value>
    14   </context-param>
    15   
    16   <!-- spring上下文监听器 -->
    17   <listener>
    18     <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    19   </listener>
    20   
    21   <!-- Introspector缓存清除监听器 -->
    22   <listener>
    23     <listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class>
    24   </listener>
    25   
    26   <filter>
    27     <filter-name>encoding</filter-name>
    28     <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    29     <init-param>
    30       <param-name>encoding</param-name>
    31       <param-value>UTF-8</param-value>
    32     </init-param>
    33   </filter>
    34   
    35   <filter-mapping>
    36     <filter-name>encoding</filter-name>
    37     <url-pattern>/*</url-pattern>
    38   </filter-mapping>
    39   
    40   <!-- 配置DispatcherServlet -->
    41   <servlet>
    42     <servlet-name>krry_SSM</servlet-name>
    43     <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    44     <!-- 配置springMVC的配置文件 -->
    45     <!-- 如果不配置下面选项,系统默认加载classpath下面名为[servlet-name]-servlet.xml的文件 springmvc01-servlet.xml -->
    46     <init-param>
    47       <param-name>contextConfigLocation</param-name>
    48       <param-value>classpath:spring/springmvc.xml</param-value>
    49     </init-param>
    50   </servlet>
    51   
    52   <servlet-mapping>  
    53       <servlet-name>krry_SSM</servlet-name>  
    54       <url-pattern>/index</url-pattern>  
    55   </servlet-mapping>  
    56   
    57   <!-- 可以配*.do, *.action(了解) / (重点): 所有的请求都会被spring mvc解析,但必须对静态资源文件进行过滤放行,建议大家使用这种方式 
    58         /* : 不建议大家使用  -->
    59   <servlet-mapping>
    60     <servlet-name>krry_SSM</servlet-name>
    61     <url-pattern>/</url-pattern>
    62   </servlet-mapping>
    63  
    64 </web-app>

    这里注意一点欢迎页面,welcome-file-list一般情况下只能使用静态网页,如果非要把他配置成SpringMVC的控制器(通过controller进入欢迎页)URL就会报错404,

    解决方法:

    在web.xml上首先设置

    1   <welcome-file-list>
    2     <welcome-file>index</welcome-file>
    3   </welcome-file-list>

    再增加一个/index 的映射

    1   <servlet-mapping>  
    2       <servlet-name>krry_SSM</servlet-name>  
    3       <url-pattern>/index</url-pattern>  
    4   </servlet-mapping>  

    最后在controller层添加一个首页控制器得到index的请求

    1 @RequestMapping("/index")

    controller层:

      1 package com.krry.controller.login;
      2 
      3 import java.sql.Date;
      4 import java.sql.Timestamp;
      5 import java.text.SimpleDateFormat;
      6 import java.util.UUID;
      7 
      8 import javax.servlet.http.HttpServletRequest;
      9 
     10 import org.springframework.beans.factory.annotation.Autowired;
     11 import org.springframework.stereotype.Controller;
     12 import org.springframework.web.bind.annotation.RequestMapping;
     13 import org.springframework.web.bind.annotation.RequestMethod;
     14 
     15 import com.krry.entity.User;
     16 import com.krry.service.IUserService;
     17 import com.krry.util.TmStringUtils;
     18 
     19 /**
     20  * Controller层,作为请求转发
     21  * 页面所有路径的访问方法:控制层的命名空间+@RequestMapping的value
     22  * 如这里的/login/index.krry(后缀在xml文件配置)
     23  * */
     24 @Controller  //表示是多例模式,每个用户返回的web层是不一样的
     25 @RequestMapping("/login")
     26 public class LoginController {
     27 
     28     @Autowired
     29     private IUserService userService;
     30     
     31     /**
     32      * 若在下面的@RequestMapping前面加上@ResponseBody,
     33      * 若方法是String类型则直接返回的是字符串,不会跳转到该字符串的路径jsp文件
     34      * 
     35      * 所以要想跳转到某一jsp页面,不能加上@ResponseBody
     36      * 这个@ResponseBody适合ajax返回的数据
     37      * 
     38      */
     39     
     40     /**
     41      * 在控制层不加@ResponseBody的情况下,return值默认是转发到某路径,不会显示转发路径,显示的是未转发前的路径
     42      * 若要重定向,加上redirect:这里默认是当前命名空间的转发,要跳转到另一个control层,需要返回上一级../
     43      * 
     44         这里使用重定向,返回命名空间的上一级,重定向到命名空间为Krry下的index 
     45         return "redirect:../index";
     46         
     47         注意:
     48         转发不会显示转发路径,显示的是未转发前的路径
     49      *  重定向显示的是跳转之后的路径
     50      */
     51     
     52     /**
     53      * 进入登录界面
     54      * @return
     55      */
     56     @RequestMapping("/index")
     57     public String index(){
     58 //        ModelAndView modelAndView = new ModelAndView();
     59 //        modelAndView.setViewName("index/login"); //跳到此页面
     60 //        return modelAndView;
     61         return "index/login";   //默认是转发,不会显示转发路径
     62     }
     63     
     64     /**
     65      * 点击登录
     66      * com.krry.controller.login 
     67      * 方法名:login
     68      * @author krry 
     69      * @param request
     70      * @return String
     71      * @exception 
     72      * @since  1.0.0
     73      */
     74     @RequestMapping(method=RequestMethod.POST,value="/logined")
     75     public String login(HttpServletRequest request){
     76         //获取用户和密码
     77         String username = request.getParameter("username");
     78         String password = request.getParameter("password");
     79         
     80         //如果邮箱和密码为null,那么就返回已null标识
     81         if(TmStringUtils.isEmpty(username) )return "index/allError";
     82         if(TmStringUtils.isEmpty(password))return "index/allError";
     83         
     84         //密码进行加密处理
     85         password = TmStringUtils.md5Base64(password);
     86         
     87         //根据邮箱或昵称查询,用户是否存在
     88         User user = userService.getLogin(username);
     89         
     90         //如果存在
     91         if(user!=null){
     92             
     93             User userpas = userService.getpass(username, password);
     94             if(userpas!=null){
     95                 //如果密码正确
     96                 //将用户信息放入到会话中...
     97                 request.getSession().setAttribute("user", user);
     98                 
     99                 //这里使用重定向,返回命名空间的上一级,重定向到命名空间为Krry下的index.krry
    100                 return "redirect:../index";
    101             }else{
    102                 //如果密码错误
    103                 System.out.println("密码错误");
    104                 return "index/error";
    105             }
    106         }else{
    107             //如果不存在,代码邮箱和密码输入有误
    108             System.out.println("用户不存在");
    109             return "index/error";
    110         }
    111     }
    112     
    113     /**
    114      * 退出登录控制层
    115      * com.krry.controller.login 
    116      * 方法名:logout
    117      * @author krry 
    118      * @param request
    119      * @return String
    120      * @exception 
    121      * @since  1.0.0
    122      */
    123     @RequestMapping(method=RequestMethod.GET,value="/logout")
    124     public String logout(HttpServletRequest request){
    125         request.getSession().invalidate(); //清空session值
    126         return "index/index";
    127     }
    128     
    129     /**
    130      * 打开注册界面层
    131      * @return
    132      */
    133     @RequestMapping("/rege")
    134     public String rege(){
    135 //        ModelAndView modelAndView = new ModelAndView();
    136 //        modelAndView.setViewName("index/login"); //跳到此页面
    137 //        return modelAndView;
    138         return "index/resgi";
    139     }
    140     
    141     /**
    142      * 注册控制层
    143      * com.krry.controller.login 
    144      * 方法名:resig
    145      * @author krry 
    146      * @param request
    147      * @return String
    148      * @exception 
    149      * @since  1.0.0
    150      */
    151     @RequestMapping(method=RequestMethod.POST,value="/resig")
    152     public String resig(HttpServletRequest request){
    153         //获取用户和密码
    154         String name = request.getParameter("username");
    155         String email = request.getParameter("email");
    156         String password = request.getParameter("password");
    157 
    158         //如果邮箱和密码为null,那么就返回已null标识
    159         if(TmStringUtils.isEmpty(name) )return "index/allError";
    160         if(TmStringUtils.isEmpty(email))return "index/allError";
    161         if(TmStringUtils.isEmail(password))return "index/allError";
    162         
    163         //密码进行加密处理
    164         password = TmStringUtils.md5Base64(password);
    165         //根据昵称查询,用户是否存在
    166         User user1 = userService.getothernameres(name);
    167         //根据账号查询,用户是否存在
    168         User user2 = userService.getemailres(email);
    169         
    170         //若存在
    171         if(user1 != null){ //昵称重复
    172             return "index/allError";
    173         }
    174         if(user2 != null){ //email重复
    175             return "index/allError";
    176         }
    177 
    178         Date time = new Date(System.currentTimeMillis());
    179         
    180         String id = UUID.randomUUID().toString();
    181         //执行到这里,说明可以注册
    182         User newUser = new User(id, name, password, email,time);
    183         //调用注册方法
    184         userService.saveUser(newUser);
    185         
    186         //将信息设置session作用域
    187         request.getSession().setAttribute("user", newUser);
    188 
    189         /**
    190          * 这里使用重定向,返回命名空间的上一级,重定向到index
    191          */
    192         return "redirect:../index";
    193     }
    194     
    195 }

     重要的点,以上的说到了,还有一些前端页面、数据库操作就不在这展示了

    以上ssm整合的链接展示:https://www.ainyi.com/krry_SSM

    JavaWeb容器初始化过程

  • 相关阅读:
    CQUOJ 10819 MUH and House of Cards
    CQUOJ 9920 Ladder
    CQUOJ 9906 Little Girl and Maximum XOR
    CQUOJ 10672 Kolya and Tandem Repeat
    CQUOJ 9711 Primes on Interval
    指针试水
    Another test
    Test
    二分图匹配的重要概念以及匈牙利算法
    二分图最大匹配
  • 原文地址:https://www.cnblogs.com/ainyi/p/8527984.html
Copyright © 2011-2022 走看看