快速搭建SSM框架,Spring,SpringMVC, mybaties,(不灵找我)

8 篇文章 0 订阅

Ssm学习笔记

文档版本
V1.0
说明:介绍ssm的基本使用。
Ssm介绍
Ssm是从持久层到页面控制层的一系列框架,此笔记中的ssm由springmvc,spring,mybaits构成。数据库mysql。

学习过程是mysql——》mybatis——》spring——》springmvc。在企业中,一个项目的开发过程也是如此。

Mysql。

Mybatis
Mybatis简介。
Mybatis是一个持久层轻量级的ORM框架,它是一个半自动框架。优点是小巧灵活,简单易学。缺点是没办法切换数据库。Mybatis的前身是ibatis,所以一些mybatis的jar包的接口中都是用ibatis命名。
特点
基于SQL语法,简单易学
能了解底层封装过程
SQL语句封装在配置文件中,便于统一管理与维护,降低程序的耦合度
方便程序代码调试。

MyBatis框架优缺点

优点
与JDBC相比,减少了50%以上的代码量
最简单的持久化框架,小巧并简单易学
SQL代码从程序代码中彻底分离,可重用
提供XML标签,支持编写动态SQL
提供映射标签,支持对象与数据库的ORM字段映射
缺点
SQL语句编写工作量大,对开发人员有一定要求
数据库移植性差
持久化与ORM
持久化是程序数据在瞬时状态和持久状态间转换的过程

ORM(Object Relational Mapping)
编写程序的时候,以面向对象的方式处理数据
保存数据的时候,却以关系型数据库的方式存储
ORM解决方案包含下面四个部分
在持久化对象上执行基本的增、删、改、查操作
对持久化对象提供一种查询语言或者API
对象关系映射工具
提供与事务对象交互、执行检查、延迟加载以及其他优化功能    
Mybatis的使用

搭建MyBatis开发环境

使用MyBatis的开发步骤
1,下载mybatis-3.2.2.jar包并导入工程
2,编写MyBatis核心配置文件(configuration.xml)
3,创建实体类-POJO
4,DAO层-SQL映射文件(mapper.xml)
5,创建测试类
读取核心配置文件mybatis-config.xml
创建SqlSessionFactory对象,读取配置文件
创建SqlSession对象
调用mapper文件进行数据操作
需要的jar包
使用Mybatis需要的基本jar包有
 

核心配置文件
Mybatis的核心配置文件可以对mybatis框架进行全局控制。核心配置文件中的标签(或者说是元素)的顺序是固定的,编写时,如果顺序错了就会报错。
核心配置文件中的元素
configuration
properties    可以配置在Java 属性配置文件中
settings    修改 MyBatis 在运行时的行为方式
typeAliases   为 Java 类型命名一个别名(简称)
typeHandlers   类型处理器
objectFactory   对象工厂
plugins   插件
environments   环境
environment   环境变量
transactionManager  事务管理器
dataSource   数据源
mappers    映射器

Sql映射文件
Mybatis的sql映射文件是相当于dao层的实现类,用来编写数据

动态sql
If
Set
Where
Trim
Choose
Foreach
Mybatis的相关插件
分页插件
需要的jar包
 

使用方法(演示代码)
@Test
    public void testPageHelper() throws IOException {

        InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
        SqlSession session = sqlSessionFactory.openSession(true);

        // 分页处理,显示第一页的10条数据
        //每页显示4条 相当于  SELECT * FROM table limit 0,4;  
        PageHelper.startPage(1, 4);
        List<Brand> brandList = session.getMapper(BrandRepository.class).findAll();
        // 取分页信息
        PageInfo<Brand> pageInfo = new PageInfo<Brand>(brandList);
        
        long total = pageInfo.getTotal();// 总记录数
        System.out.println("total:" + total);
        int pages = pageInfo.getPages();
        System.out.println("pages:" + pages);// 总页数
        int pageSize = pageInfo.getPageSize();
        System.out.println("pageSize:" + pageSize);// 每页的展示数
        List<Brand> list = pageInfo.getList();
        for (Brand brand : list) {
            System.out.println(brand.getId()+"=="+brand.getName());
        }
    }

Mybatis逆向工程


Spring
Spring简介
Spring是一个企业级的,轻量级框架,本身是一个大容器,可以整合其他框架。Spring有两个核心概念IOC和AOP。
IOC 、DI
ioc控制反转,di依赖注入

AOP
面向切面编程:把系统中公共部分抽离出来,通过配置的方式,集中解决问题。
Spring的使用
Spring有三个核心jar包
Spring-core.jar  核心包
Spring-context.jar  上下文
Spring-beans.jar spring是面向bean的编程。所以需要beans的包

Spring还有许多扩展包。
         

Spring的使用步骤
导入jar包。
 
编写配置文件
<?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:aop="http://www.springframework.org/schema/aop"
    xsi:schemaLocation="
    http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
    http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd"
    default-lazy-init="true">

    <!-- 导入数据库属性文件 -->
    <context:property-placeholder location="classpath:database.properties" />

    <!-- 包扫描 -->
    <context:component-scan base-package="com.ssm" />

    <!-- 配置数据源 -->
    <bean id="dataSource"
        class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="${jdbc.driver}" />
        <property name="url" value="${jdbc.url}" />
        <property name="username" value="${jdbc.username}" />
        <property name="password" value="${jdbc.password}" />
    </bean>
    <!-- spring整合mybatis -->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <!-- 引用数据源 -->
        <property name="dataSource" ref="dataSource" />
        <!-- 配置映射器 -->
        <property name="mapperLocations" value="classpath:com/ssm/repository/*.xml" />
        <!-- 定义别名 -->
        <property name="typeAliasesPackage" value="com.ssm.pojo" />
    </bean>

    <!-- 扫描Repository -->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="com.ssm.repository" />
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
    </bean>
    
    <!-- 开启Aspect注解驱动 -->
    <aop:aspectj-autoproxy />
    <!-- 配置切面 -->
    <bean class="com.ssm.aop.AroundLogger"></bean>


</beans>

编写业务逻辑层代码 service
 
添加aop部分(注解方式)
添加通用切点类
package com.ssm.aop;

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;

@Aspect
public class PointCut {
    
    @Pointcut("execution(public void *(*))")
    public void pointcut() {
    }

}
编写切面类
package com.ssm.aop;

import java.util.Arrays;

import org.apache.log4j.Logger;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;

@Aspect
public class AroundLogger {
    
    private static final Logger log = Logger.getLogger(AroundLogger.class);

    /**
     * 环绕通知
     * @param jp
     * @return
     * @throws Throwable
     */
    @Around("com.ssm.aop.PointCut.pointcut()")
    public Object aroundLogger(ProceedingJoinPoint jp) throws Throwable {
        log.info("调用 " + jp.getTarget() + " 的 " + jp.getSignature().getName()
                + " 方法。方法入参:" + Arrays.toString(jp.getArgs()));
        try {
            Object result = jp.proceed();
            log.info("调用 " + jp.getTarget() + " 的 "
                    + jp.getSignature().getName() + " 方法。方法返回值:" + result);
            return result;
        } catch (Throwable e) {
            log.error(jp.getSignature().getName() + " 方法发生异常:" + e);
            throw e;
        } finally {
            log.info(jp.getSignature().getName() + " 方法结束执行。");
        }

    }
}

编写测试类

package com.ssm.service;

import java.util.List;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.ssm.pojo.Brand;

public class BrandServiceTest {

    @Test
    public void testFindAll() {
        ApplicationContext context = new ClassPathXmlApplicationContext("classpath:spring.xml");
        BrandService brancService = (BrandService) context.getBean("brandServiceImpl");
        List<Brand> brandList = brancService.findAll();
        for (Brand brand : brandList) {
            System.out.println(brand);
        }
        
    }
}

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

SpringMVC前端控制器是DispatcherServlet;应用控制器其实拆为处理器映射器(Handler Mapping)进行处理器管理和视图解析器(View Resolver)进行视图管理;页面控制器/动作/处理器为Controller接口(仅包含ModelAndView handleRequest(request, response) 方法)的实现(也可以是任何的POJO类);支持本地化(Locale)解析、主题(Theme)解析及文件上传等;提供了非常灵活的数据验证、格式化和数据绑定机制;提供了强大的约定大于配置(惯例优先原则)的契约式编程支持。

Springmvc处理请求的流程

 

图中具体执行步骤如下:
1、  首先用户发送请求————>前端控制器,前端控制器根据请求信息(如URL)来决定选择哪一个页面控制器进行处理并把请求委托给它,即以前的控制器的控制逻辑部分;图中的1、2步骤;
2、  页面控制器接收到请求后,进行功能处理,首先需要收集和绑定请求参数到一个对象,这个对象在Spring Web MVC中叫命令对象,并进行验证,然后将命令对象委托给业务对象进行处理;处理完毕后返回一个ModelAndView(模型数据和逻辑视图名);图2-1中的3、4、5步骤;
3、  前端控制器收回控制权,然后根据返回的逻辑视图名,选择相应的视图进行渲染,并把模型数据传入以便视图渲染;图中的步骤6、7;
4、  前端控制器再次收回控制权,将响应返回给用户,图中的步骤8;至此整个结束。

问题:
1、  请求如何给前端控制器(DispatchServlet)?
2、  前端控制器如何根据请求信息选择页面控制器进行功能处理?
3、  如何支持多种页面控制器呢?
4、  如何页面控制器如何使用业务对象?
5、  页面控制器如何返回模型数据?
6、  前端控制器如何根据页面控制器返回的逻辑视图名选择具体的视图进行渲染?
7、  不同的视图技术如何使用相应的模型数据?
首先我们知道有如上问题,那这些问题如何解决呢?请让我们先继续,在后边依次回答。

Spring Web MVC架构
Spring Web MVC核心架构图,如图2-2

 
架构图对应的DispatcherServlet核心代码如下:
//前端控制器分派方法
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
        HttpServletRequest processedRequest = request;
        HandlerExecutionChain mappedHandler = null;
        int interceptorIndex = -1;

        try {
            ModelAndView mv;
            boolean errorView = false;

            try {
                   //检查是否是请求是否是multipart(如文件上传),如果是将通过MultipartResolver解析
                processedRequest = checkMultipart(request);
                   //步骤2、请求到处理器(页面控制器)的映射,通过HandlerMapping进行映射
                mappedHandler = getHandler(processedRequest, false);
                if (mappedHandler == null || mappedHandler.getHandler() == null) {
                    noHandlerFound(processedRequest, response);
                    return;
                }
                   //步骤3、处理器适配,即将我们的处理器包装成相应的适配器(从而支持多种类型的处理器)
                HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());

                  // 304 Not Modified缓存支持
                //此处省略具体代码

                // 执行处理器相关的拦截器的预处理(HandlerInterceptor.preHandle)
                //此处省略具体代码

                // 步骤4、由适配器执行处理器(调用处理器相应功能处理方法)
                mv = ha.handle(processedRequest, response, mappedHandler.getHandler());

                // Do we need view name translation?
                if (mv != null && !mv.hasView()) {
                    mv.setViewName(getDefaultViewName(request));
                }

                // 执行处理器相关的拦截器的后处理(HandlerInterceptor.postHandle)
                //此处省略具体代码
            }
            catch (ModelAndViewDefiningException ex) {
                logger.debug("ModelAndViewDefiningException encountered", ex);
                mv = ex.getModelAndView();
            }
            catch (Exception ex) {
                Object handler = (mappedHandler != null ? mappedHandler.getHandler() : null);
                mv = processHandlerException(processedRequest, response, handler, ex);
                errorView = (mv != null);
            }

            //步骤5 步骤6、解析视图并进行视图的渲染
//步骤5 由ViewResolver解析View(viewResolver.resolveViewName(viewName, locale))
//步骤6 视图在渲染时会把Model传入(view.render(mv.getModelInternal(), request, response);)
            if (mv != null && !mv.wasCleared()) {
                render(mv, processedRequest, response);
                if (errorView) {
                    WebUtils.clearErrorRequestAttributes(request);
                }
            }
            else {
                if (logger.isDebugEnabled()) {
                    logger.debug("Null ModelAndView returned to DispatcherServlet with name '" + getServletName() +
                            "': assuming HandlerAdapter completed request handling");
                }
            }

            // 执行处理器相关的拦截器的完成后处理(HandlerInterceptor.afterCompletion)
            //此处省略具体代码


        catch (Exception ex) {
            // Trigger after-completion for thrown exception.
            triggerAfterCompletion(mappedHandler, interceptorIndex, processedRequest, response, ex);
            throw ex;
        }
        catch (Error err) {
            ServletException ex = new NestedServletException("Handler processing failed", err);
            // Trigger after-completion for thrown exception.
            triggerAfterCompletion(mappedHandler, interceptorIndex, processedRequest, response, ex);
            throw ex;
        }

        finally {
            // Clean up any resources used by a multipart request.
            if (processedRequest != request) {
                cleanupMultipart(processedRequest);
            }
        }
    }


核心架构的具体流程步骤如下:
1、  首先用户发送请求——>DispatcherServlet,前端控制器收到请求后自己不进行处理,而是委托给其他的解析器进行处理,作为统一访问点,进行全局的流程控制;
2、  DispatcherServlet——>HandlerMapping, HandlerMapping将会把请求映射为HandlerExecutionChain对象(包含一个Handler处理器(页面控制器)对象、多个HandlerInterceptor拦截器)对象,通过这种策略模式,很容易添加新的映射策略;
3、  DispatcherServlet——>HandlerAdapter,HandlerAdapter将会把处理器包装为适配器,从而支持多种类型的处理器,即适配器设计模式的应用,从而很容易支持很多类型的处理器;
4、  HandlerAdapter——>处理器功能处理方法的调用,HandlerAdapter将会根据适配的结果调用真正的处理器的功能处理方法,完成功能处理;并返回一个ModelAndView对象(包含模型数据、逻辑视图名);
5、  ModelAndView的逻辑视图名——> ViewResolver, ViewResolver将把逻辑视图名解析为具体的View,通过这种策略模式,很容易更换其他视图技术;
6、  View——>渲染,View会根据传进来的Model模型数据进行渲染,此处的Model实际是一个Map数据结构,因此很容易支持其他视图技术;
7、返回控制权给DispatcherServlet,由DispatcherServlet返回响应给用户,到此一个流程结束。
 
此处我们只是讲了核心流程,没有考虑拦截器、本地解析、文件上传解析等,后边再细述。
 
到此,再来看我们前边提出的问题:
 
 
1、  请求如何给前端控制器?这个应该在web.xml中进行部署描述,在HelloWorld中详细讲解。
2、  前端控制器如何根据请求信息选择页面控制器进行功能处理? 我们需要配置HandlerMapping进行映射
3、  如何支持多种页面控制器呢?配置HandlerAdapter从而支持多种类型的页面控制器
4、  页面控制器如何使用业务对象?可以预料到,肯定利用Spring IoC容器的依赖注入功能
5、  页面控制器如何返回模型数据?使用ModelAndView返回
6、  前端控制器如何根据页面控制器返回的逻辑视图名选择具体的视图进行渲染? 使用ViewResolver进行解析
7、  不同的视图技术如何使用相应的模型数据? 因为Model是一个Map数据结构,很容易支持其他视图技术
 
在此我们可以看出具体的核心开发步骤:
1、  DispatcherServlet在web.xml中的部署描述,从而拦截请求到Spring Web MVC
2、  HandlerMapping的配置,从而将请求映射到处理器
3、  HandlerAdapter的配置,从而支持多种类型的处理器
4、  ViewResolver的配置,从而将逻辑视图名解析为具体视图技术
5、处理器(页面控制器)的配置,从而进行功能处理

Spring Web MVC优势
1、清晰的角色划分:前端控制器(DispatcherServlet)、请求到处理器映射(HandlerMapping)、处理器适配器(HandlerAdapter)、视图解析器(ViewResolver)、处理器或页面控制器(Controller)、验证器(   Validator)、命令对象(Command  请求参数绑定到的对象就叫命令对象)、表单对象(Form Object 提供给表单展示和提交到的对象就叫表单对象)。
2、分工明确,而且扩展点相当灵活,可以很容易扩展,虽然几乎不需要;
3、由于命令对象就是一个POJO,无需继承框架特定API,可以使用命令对象直接作为业务对象;
4、和Spring 其他框架无缝集成,是其它Web框架所不具备的;
5、可适配,通过HandlerAdapter可以支持任意的类作为处理器;
6、可定制性,HandlerMapping、ViewResolver等能够非常简单的定制;
7、功能强大的数据验证、格式化、绑定机制;
8、利用Spring提供的Mock对象能够非常简单的进行Web层单元测试;
9、本地化、主题的解析的支持,使我们更容易进行国际化和主题的切换。
10、强大的JSP标签库,使JSP编写更容易。
………………还有比如RESTful风格的支持、简单的文件上传、约定大于配置的契约式编程支持、基于注解的零配置支持等等。


Springmvc的使用
这里只将springmvc和spring整合的用法,不把springmvc作为一个单独的框架使用。
Springmvc和spring的整合步骤
Springmvc和spring的整合
导入相关jar包
 
编写web.xml
编写springmvc.xml
编写controller
全局异常和局部异常
Springmvc的文件上传
服务器端验证(jsr303)
相关资料
mybatis核心配置文件的文件头

<?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">

Mybatis的sql映射文件的文件头

<?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">

Spring配置文件的文件头
<?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"
    xsi:schemaLocation="
    http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
    default-lazy-init="true">

</beans>

Springmvc配置文件的文件头

<?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:mvc="http://www.springframework.org/schema/mvc"
    xmlns:p="http://www.springframework.org/schema/p" 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">

</beans>

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值