Java | SSM简要笔记

作者: 寒食君 | 来源:发表于2018-02-04 14:10 被阅读104次
    Spring
    MyBatis

    最近有一个项目需要去做,在选择语言时确定用Java。首先是因为很长一段时间没有使用Java,再不重拾多半是要废了;再则是暑假准备找个实习了,首选肯定还是Java方向。

    这篇文章主要是我复习SSM(SpringMVC,Spring,MyBatis)框架时所做的笔记,侧重于回忆和梳理,写得比较粗糙,适用于理解结构和快速上手。
    所以本篇适合人群:有Java基础,对SSM框架有所了解但是基础不牢概念模糊者。

    后面有空的话我会针对单个框架,写一些更加细节与原理有关的文章,帮助一些初学者,也使自己更加深入理解其中思想,毕竟这些都是开源世界的精髓!

    Spring

    最基本的几个jar包:

    • commons-logging
    • spring-beans
    • spring-context
    • spring-core
    • spring-expression

    依赖注入

    基本配置:resource/application-context

    <bean id="user" class="...">
      <constructor-arg type="int" value="111"></constructor>
      <constructor-arg type="java.lang.String" value="hanshijun"></constructor>
    </bean>
    
    <bean id="user" class="...">
     <property name="id" value="111"/>
     <property name="name" value="hanshijun"/>
    </bean>
    

    在函数中调用:

    ApplicationContext context=new ClassPathXmlApplicationContext("./xx/xx/resource/application-context");
    User user=(User)context.getBean("user")//根据id获得
    User user=context.getrBean(User.Class)//根据类型获得
    

    注解方式注入:

    1. 四大注解:
    • @Service:业务层
    • @Component:公共组件
    • @Controller:控制用户请求,SpringMVC核心注解
    • @Repository
    1. 需要jar包支持:
    • aopalliance
    • spring-sop
    • aspectjweaver
    1. 简单实现:
    public  interface UserService{
      void hello();
    }
    
    @Service
    public class UserServiceImpl implements UserService{
      @override
      public void hello(){
      }
    }
    

    此时,在使用了Service注解后,不需要再在resource/application-context.xml中声明bean,只需加入一个包扫描声明,即可将所有打上注解的组件读取。

    <context:component-scan base-packge="xxxx.xxx.*"/>
    

    面向切面编程

    统一组织代码,拦截某些方法,在其执行前后,做一些操作。一种基于注解,一种基于xml。

    • 基于注解
    1. 在application-context.xml中配置
      <aop:aspectj-autoproxy>
    2. 新建一个切面
    @Component
    @Aspect //声明切面
    public class UserAspect{
      @PointCut(value="execution(* cn.jihangyu.service.*.*(..))")//声明切点以及切点所应用的范围
      public void pointCut(){}
    
      @After(value="pointCut()")//声明切点之后要做的
      public void doAfter(JoinPoint joinPoint){//连接点,程序执行的点,多指程序的方法
    }
    
      @Before(value="pointCut()")//声明切点之前要做的
      public void doBefore(JoinPoint joinPoint){
    }
      @AfterReturning(value="pointCut()",returning="result")//获取切点方法返回值的方法
      public void afterReturning(JoinPoint joinPoint,Object result){
    }
      @Around(value="pointCut()")//在整个运行过程中环绕运行
      public void around(ProceedingJoinPoint proceedingJoinPoint){
       proceedingJoinPoint.proceed();
    }
      //等等
    }
    
    • 基于xml配置
      在application-context.xml中
    <bean id="userAop" class="..."></bean>
    <aop:config>
      <aop:aspect id="userAspect" ref="userAop">
          <aop:around method=" around" pointcut="XXX"/>
      </aop:aspect>
    </aop:config>
    

    切面编程原理

    两种实现方式

    1. JDK的Proxy,InvocationHandler。
      要求:必须实现接口
      优势:使用反射,创建效率高。

    2. cglib,使用asm,有关字节码
      基于继承
      优势:执行效率高


    SpringMVC

    Browser-DispatcherServlet-HandlerMapping-Controller-Service-ModelAndView-Model-ViewResolver

    需要:

    • 以上spring相关包
    • spring-web
    • spring-webmvc

    配置:

    • /resource/spring-mvc.xml下
      mvc:annotation-driven //注解驱动
      context:component-scan base-package="cn.jihangyu.*.*"//包扫描
    <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value=""/>
        <property name="suffix" value=""/>
        <property name="viewClass" value=""/>
    </bean>
    

    //配置viewResolver

    • web.xml 下
    <servlet>
        <servlet-name>test</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
          <param-name>contextConfigLocation</param-name>
          <param-value>classpath:XXX/resource/spring-mvc.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>//优先级
    </servlet>
    
    <servlet-mapping>
      <servlet-name>test</servlet-name>
      <url-pattern>/</url-pattern>
    </servlet-mapping>
    

    //配置DispatcherServlet

    GET,POST

    • 获取带参数Get 请求方式
    @RequestMapping("/test/{id}/{name}")
    public String test(ModelMap modelMap,@PathVariable(“id”) Integer sid,@PathVariable String name){
      //PathVariable 获取传过来值的参数名在不用(“”)标注的情况下,需要和传过来参数的名字一致,如@PathVariable String name;如业务对变量名有特殊需要,可使用@PathVariable(“id”) Integer sid方式。
      //ModelMap是用来返回的model的map,其中放键值对即可。
      return "user"//返回名为test的view
    }
    
    • 获取POST请求
    @RequestMapping("/test")
    public String test(ModelMap modelMap,HttpServletRequest request){
      String id=request.getParameter("id")
      return "user"
    }
    

    @RequestMapping("/test")
    public String test(ModelMap modelMap,User user){
      //直接操作封装好的user对象
      return "user"
    }
    
    • 使用阿里fastjson
    1. 导包
    2. /resource/spring-mvc.xml
    <mvc:annotation-driven>
      <mvc:mesage-converters>
          <bean></bean>//具体配置就不写了,随用随查
      </mvc:mesage-converters>
    </mvc:annotation-driven>
    

    //【重要】注意书写顺序,要写在全局<mvc:annotation-driven>/之前,否则会有406错误

    1. 返回json数据体
    @RequestMapping("/test")
    @ResponseBody//这个注解将会被上述配置的注解驱动识别,表示返回数据体
    public User test(){
       User user=new User(20,"hanshijun");
        return user;
    }
    
    1. 接收json数据体
    @RequestMapping("/test")
    public String test(@RequestBody User user){
        
        return "user";//返回view
    }
    

    拦截器

    • 拦截器和过滤器的比较
      拦截器:基于反射,和Spring结合紧密,可以拿到处理IOC中的bean。
      过滤器:基于Servlet,基于函数回调,可以拦截所有请求。

    • 实现:
      /src/xxx/xxx/interceptor

    public class TestInterceptor implements HandlerInterceptor{
      //三个重写函数preHandler,postHandler,afterHandler
    }
    

    /src/xxx/xxx/resource/spring-mvc.xml

    <mvc:interceptors>
      <bean class=""/>//拦截所有请求
      <mvc:interceptor>//拦截指定请求
          <mvc:mapping path="test"/>
          <bean class=""/>
      </mvc:interceptor>
    </mvc:interceptors>
    

    上传下载

    1. 导包
      commons-io,commons-upload
    2. /src/xxx/xxx/resource/spring-mvc.xml
    <bean  id="multipartResolver" class="org,springframework.web.multipart.commons.CommonsMultipartResolver">
      <property name="" value="">
      <property name="" value="">
    </bean>
    
    1. controller(上传)
    @RequestMapping("/upload")
    public String upload(MultipartFile file,HttpServletRequest request){
      String name=file.getOriginalFileName();
      File uploadfile=new File("/"+name);
      file.transFerTo(uploadfile);
      return  "upload"
    }
    
    1. controller(下载)
    @RequestMapping("download")
    public ResponseEntity<byte []> download(){
      String path="e:/xxx.txt";
      File file=new File(path);
      HttpHeaders headers=new HttpHeaders();
      headers.setContentDispositionFormData("attachment",path);
      headers.setContentType(MediaType.TXT);
      return new  ResponseEntity<byte []>(FileUtils.readFileToByteArray(file),headers,HttpStatus.CREATE);
    }
    

    MyBatis

    1. 导包
      mysql-connector,mybatis
    2. 流程
      App-Configuration(AqlMapConfig.xml,Config.xml)-SqlSessionFactory-SqlSession-MappedStatements-Transaction
    3. 配置
      jdbc.properties
    jdbc.driver=com.mysql.jdbc.Driver
    jdbc.url=jdbc:mysql://localhost:3306/test
    jdbc.username=
    jdbc.password=
    

    mybatis-cfg.xml

    <configuration>
      
      <properties resource="jdbc.properties" />//读取数据库连接配置
    
      <typeAliases>
        <package name=""/>
      </typeAliases>//需要封装的实体
    
      <environments default="test">//配置环境
        <environment id="mybatis-test">
            <transactionManager type="JDBC" />
            <dataSource type="POOLED">
              <property name="driver" value="${jdbc.driver}"
              <property name="url" value="${jdbc.url}"
              <property name="username" value="${jdbc.username}"
              <property name="password" value="${jdbc.password}"
            </dataSource>
        </environment>
      </environments >
    
      <mappers>//指定mapper的位置
        <package name="">
      </mappers>
    </configuration>
    

    UserMapper.xml

    <mapper namespace="dao.UserMapper">
      <resultMap id="userMapper" type="entity.User">
        <id  column="Sid" property="id"/>//主键
        <result column="" property="">//其余字段和实体属性一一匹配
         <result column="" property="">
         <result column="" property="">
      </resultMap>
    </mapper>
    

    Main.java

    public static void main(String [] args){
      InputStream in=Main.class.getResourceAsStream("resource/mybatis-cfg.xml");//加载配置文件
      SQLSessionFactory factory=new SQLSessionFactoryBuilder().build(in);//构建工厂
      SqlSesion session=factory.openSession();创建会话
    
      UserMapper mappr=session.getMapper(UserMapper.class);
      //可以开始调用mapper的操作数据库方法
      session.commit();
      session.close();
    }
    

    SSM整合

    1. 导包
      mybatis-spring
      druid连接池
      spring-jdbc
      spring-tx管理事务
    2. spring-config.xml
    <aop:aspectj-autoproxy proxy-target-class="true"/>//开启切面
    
    <context:annotation-config/>
    
    <context:component-scan base-package="cn.jihangyu"/>//扫描组件注解
    
    <context:property-placeholder location="cn/jihangyu/resource/jdbc.properties"/>//读取配置文件
    
    //配置sqlsession工厂
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
      <property name="dataSource" ref="dataSource"/>//数据源位置
      <property name="mapperLocations" value="cn/jihangyu/dao/**.xml"/>//mapper位置
    </bean>
    
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
      <property name="backPackage" value="cn.jihangyu.dao"/>
      <property name="SqlSessionFactoryBeanName" value="sqlSessionFactory"/>
    </bean>
    
    //配置事务管理
    <tx:annotation-driven transaction-manager="transactionManager"/>
    <bean  class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
      <property  in="transactionManager" name="dataSource" ref="dataSource"/>
    </bean>
    
    //配置数据源(略)
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" destory-method="close" init-method="init">
      <property />
      <property />
      <property />
      <property />
    //等等
    </bean>
    
    
    
    1. spring-mvc.xml
      同上文mvc配置

    2. web.xml

    <context-param>
      <param-name>contextConfigLoader</param-name>
      <param-value>cn/jihangyu/resource/spring-config.xml</param-value>
    </context-param>
    <listener>
      <listen-class>org.springframework.web.context.ContextLoaderListener</listen-class>
    </listener>
    

    事务传播机制

    springMVC作为spring的子容器,假如在springMVC配置文件中扫描全局注解,那么会将springMVC需要的除了controller以外的组件也扫描进去,而mvc子容器中扫描到的service是没用事务能力的,所以会造成sql回滚失败,导致数据库插入脏数据。

    所以需要在mvc配置文件中扫描注解组件时加入额外的声明。

    <context:component-scan base-package="cn.jihangyu.**">
      <context:exclude-filter type="annotation"  expression="org.springframework.stereotype.Service"/>//声明除去service注解
    </context>
    

    事务传播机制有七种

    • REQUIRED:spring的默认事务传播级别,特点是,如果上下文已经存在事务,那么就加到事务中执行,如果不存在,就新建事务。
    @Transactional("propagation=Propagation.REQUIRED")
    
    • 其他的遇到实际的业务场景手动查资料

    扫一扫,关注公众号

    一个点赞,一次转发,是对原创者的莫大支持。

    相关文章

      网友评论

        本文标题:Java | SSM简要笔记

        本文链接:https://www.haomeiwen.com/subject/nskjzxtx.html