当前位置: 首页 > news >正文

SSM基础框架搭建

    SSM(Spring + SpringMVC + MyBatis)三个开源框架的简称,是WEB项目开发的不二之选,是码农进阶全栈工程师心路历程上的驿站。大公司开源框架和算法制定标准规范引领行业趋势,小公司拿来主义面向业务敏捷开发快速迭代在夹缝中艰难生存。SSM框架完美的符合了当下的这种行业现状,对于底层是如何实现的开发人员完全不必关注,踏踏实实梳理好业务逻辑,做好质量把控年底KPI基本问题就不大了。

    Spring是一个轻量级IoC及AOP容器框架,配置又多又细,SpringBoot简化了大量通用且不常用的配置项,使构建一个微服务变得超简单;SpringMVC是目前最优秀的MVC框架,注解用得好事半功倍;MyBatis用于数据持久化,MyBatisPlus增强版内置分页功能简化开发流程自动化代码生成,唯一要做的事情就剩下写写SQL了。

    无私的分享从这里开始: git clone git@gitee.com:gonglibin/kirin.git

文件夹 PATH 列表
卷序列号为 0009-68A2
D:\WORKSPACES\KIRIN
│  kirin.iml
│  pom.xml
│  
├─.idea
│  │  .name
│  │  compiler.xml
│  │  encodings.xml
│  │  misc.xml
│  │  modules.xml
│  │  uiDesigner.xml
│  │  workspace.xml
│  │  
│  ├─copyright
│  │      profiles_settings.xml
│  │      
│  ├─inspectionProfiles
│  │      profiles_settings.xml
│  │      Project_Default.xml
│  │      
│  └─libraries
│         (略)
│          
└─src
    ├─main
    │  ├─java
    │  │  └─com
    │  │      └─kirin
    │  │          ├─api
    │  │          │  ├─controller
    │  │          │  │      KrnStatisticAdownerController.java
    │  │          │  │      
    │  │          │  ├─request
    │  │          │  └─response
    │  │          │          KrnResponse.java
    │  │          │          
    │  │          ├─dao
    │  │          │  ├─entity
    │  │          │  │      StatisticAdowner.java
    │  │          │  │      
    │  │          │  ├─impl
    │  │          │  │      KrnStatisticAdownerServiceImpl.java
    │  │          │  │      
    │  │          │  ├─mapper
    │  │          │  │      KrnStatisticAdownerMapper.java
    │  │          │  │      
    │  │          │  └─service
    │  │          │          KrnStatisticAdownerService.java
    │  │          │          
    │  │          └─web
    │  │              ├─server
    │  │              │      KrnApplication.java
    │  │              │      KrnInterceptor.java
    │  │              │      KrnMvcConfig.java
    │  │              │      
    │  │              └─tools
    │  │                      KrnAutoMysql.java
    │  │                      
    │  └─resources
    │      │  application.properties
    │      │  kirin.properties
    │      │  
    │      ├─mybatis
    │      │      mybatis-config.xml
    │      │      spring-jdbc.xml
    │      │      spring-mybatis.xml
    │      │      
    │      ├─spring
    │      │      spring-web-entry.xml
    │      │      
    │      └─xml
    │              StatisticAdowner.xml
    │              
    └─test
        └─java
            └─com
                └─kirin
wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

kirin/src/main/java/com/kirin/web/server/KrnApplication.java

@SpringBootApplication
@ImportResource("classpath:spring/spring-web-entry.xml")
@EnableAutoConfiguration(exclude = {DataSourceAutoConfiguration.class})
public class KrnApplication {
    private static Logger logger = LoggerFactory.getLogger(KrnApplication.class);

    public static void main(String[] args) {
        SpringApplication.run(KrnApplication.class, args);
    }
}
wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

    1行@SpringBootApplication表示该对象为当前应用的启动类;

    2行@ImportResource表示引入配置文件资源读取解析及加载;

    8行启动,就这么简单~~~

kirin/src/main/java/com/kirin/web/server/ KrnMvcConfig.java

@Configuration
public class KrnMvcConfig extends WebMvcConfigurerAdapter {
    private static Logger logger = LoggerFactory.getLogger(KrnMvcConfig.class);

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        super.addResourceHandlers(registry);
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new KrnInterceptor()).addPathPatterns("/**");
    }
}
wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

KrnMvcConfig类继承自WebMvcConfigurerAdapter抽象类(该类实现了WebMvcConfigurer接口方法为空并交给子类去实现);

    1行@Configuration表示希望Spring将该类作为配置项资源;

    6行实现静态资源处理;

    11行向资源中添加拦截器;

kirin/src/main/java/com/kirin/web/server/ KrnInterceptor.java

public class KrnInterceptor implements HandlerInterceptor {
    /**
     * 该方法将在请求处理之前被调用,只有该方法返回true,才会继续
     * 执行后续的Interceptor和Controller,当返回值为true时就会
     * 继续调用下一个Interceptor的preHandle方法,如果已经是最后
     * 一个Interceptor的时候就会是调用当前请求的Controller方法。
     */
    @Override
    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
        boolean rst = true;
        String err = "{\"code\":500,\"message\":\"操作错误\",\"data\":null}";

        if (true != httpServletRequest.getMethod().equals("GET")) {
            httpServletResponse.setCharacterEncoding("UTF-8");
            httpServletResponse.setContentType("text/html; charset=utf-8");

            try {
                PrintWriter writer = httpServletResponse.getWriter();
                writer.print(err);
                writer.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
            rst = false;
        }

        return rst;
    }

    /**
     * 该方法将在请求处理之后,DispatcherServlet进行视图
     * 返回渲染之前进行调用,可以在这个方法中对Controller
     * 处理之后的ModelAndView 对象进行操作。
     */
    @Override
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
    }

    /**
     * 该方法也是需要当前对应的Interceptor的preHandle方法的返回值为true
     * 时才会执行,该方法将在整个请求结束之后,也就是在DispatcherServlet
     * 渲染了对应的视图之后执行。用于进行资源清理。
     */
    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
    }
}
wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

    KrnInterceptor类继承自HandlerInterceptor接口,接口定义了三个方法,分别对应在不同的阶段启动拦截事件,详情见注释,preHandle方法为演示,当HTTP请求不为GET时返回报错信息。

kirin/src/main/java/com/kirin/api/controller/KrnStatisticAdownerController.java

@RestController
@RequestMapping("/statisticadowner")
public class KrnStatisticAdownerController {
    @Autowired
    KrnStatisticAdownerService krnStatisticAdownerService;

    @ResponseBody
    @RequestMapping("display")
    public Object getStatisticAdownerInfo() {
        return new KrnResponse<StatisticAdowner>(200, "操作成功", krnStatisticAdownerService.getStatisticAdownerInfo());
    }
}
wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

    1行@RestController (@ResponseBody + @Controller),表示将返回结果按照response的type直接写到HTTP的response body中去,且该类是一个控制器;

    2行@RequestMapping表示将请求路径映射到的类上;

    5行注入KrnStatisticAdownerService资源;

    8行@RequestMapping表示将多级路径映射到该类的具体方法上;

kirin/src/main/java/com/kirin/dao/entity/StatisticAdowner.java

@TableName("t_statistic_adowner")
public class StatisticAdowner implements Serializable {

    private static final long serialVersionUID = 1L;

    @TableId(value = "id", type = IdType.AUTO)
    private Integer id;
    /**
     * 展示量
     */
    @TableField("sad_viewAccount")
    private Integer sadViewaccount;
    // (省略)
}
wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

    1行表示该类映射自哪张表,并将表结构映射成对象的成员变量;

    6行@TableId为主键;

    11行@TableField("sad_viewAccount")为表字段名;

    需要说明的一点是数据表到类声明的自动化生成最好遵循一定的命名规则否则后果很严重;

kirin/src/main/java/com/kirin/dao/service/KrnStatisticAdownerService.java

    自定义KrnStatisticAdownerService接口继承自IService接口,其中定义了大量常用的增删改查的方法,基本涵盖了常用的数据库操作,自定义接口中的方法在控制器中被当作资源注入并调用。

kirin/src/main/java/com/kirin/dao/ impl/KrnStatisticAdownerServiceImpl.java

@Service
public class KrnStatisticAdownerServiceImpl extends ServiceImpl<KrnStatisticAdownerMapper, StatisticAdowner> implements KrnStatisticAdownerService {
    @Autowired
    KrnStatisticAdownerMapper krnStatisticAdownerMapper;

    @Override
    public StatisticAdowner getStatisticAdownerInfo() {
        return krnStatisticAdownerMapper.getStatisticAdownerInfo();
    }
}
wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

    KrnStatisticAdownerServiceImpl类是KrnStatisticAdownerService接口的实现对象,它同时继承自ServiceImpl类,该类是IService接口中方法的具体实现。

    4行注入KrnStatisticAdownerMapper资源;

    7行覆盖KrnStatisticAdownerService接口中的方法;

kirin/src/main/java/com/kirin/dao/ mapper/KrnStatisticAdownerMapper.java

public interface KrnStatisticAdownerMapper extends BaseMapper<StatisticAdowner> {
    StatisticAdowner getStatisticAdownerInfo();
}
wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

    2行调用具体实现,建议在XML配置中书写SQL,好维护好管理逻辑清晰方便编辑修改;

kirin/src/main/resources/xml/StatisticAdowner.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.kirin.dao.mapper.KrnStatisticAdownerMapper">

    <!-- 通用查询映射结果 -->
    <resultMap id="BaseResultMap" type="com.kirin.dao.entity.StatisticAdowner">
        <id column="id" property="id" />
        <result column="sad_viewAccount" property="sadViewaccount" />
        <result column="sad_clickAccount" property="sadClickaccount" />
        <result column="sad_costAmount" property="sadCostamount" />
        <result column="sad_adOwnerId" property="sadAdownerid" />
        <result column="sad_createTime" property="sadCreatetime" />
    </resultMap>

    <!-- 通用查询结果列 -->
    <sql id="Base_Column_List">
        id, sad_viewAccount AS sadViewaccount, sad_clickAccount AS sadClickaccount, sad_costAmount AS sadCostamount, sad_adOwnerId AS sadAdownerid, sad_createTime AS sadCreatetime
    </sql>

    <select id="getStatisticAdownerInfo" resultType="com.kirin.dao.entity.StatisticAdowner">
        SELECT <include refid="Base_Column_List" /> FROM db_charm_app.t_statistic_adowner WHERE id = 1000123
    </select>
</mapper>
wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

    select块部分是需要开发者实现的,把调试好的SQL复制到这里就OK了。

    SSM框架设计的异常出色,使用起来异常便利,不过坑很多,踩一个少一个,都踩遍了工作起来就会变得很轻松,但是也会很乏味,剩下的事情全是面对不断的需求变更、业务调整和功能扩展,在日复一日的重复中慢慢老去~~~

相关文章:

  • 黄聪:如何扩展Chrome DevTools来获取页面请求
  • 来,搞个侧栏导航
  • Oracle RAC/Clusterware 多种心跳heartbeat机制介绍 RAC超时机制分析
  • 手机点击输入框时,当键盘弹起,界面上弹,键盘收起,界面下来
  • Python 偏函数 partial function
  • php课程 12-41 多态是什么
  • 设计模式快速学习(三)单例模式
  • hadoop实操篇:hadoop基础教程汇总
  • python2.7用socks和socket设置代理
  • 关于VS2017编译UE4项目,输出窗口有乱码的解决方案
  • Java全栈程序员之01:做个Linux下的程序猿
  • 如何靠谱地查到Tomcat的版本
  • Maven根据pom文件中的Profile标签动态配置编译选项
  • openlayers+geoserver+wms实现空间查询,属性查询
  • 关于 HandlerMethodArgumentResolver 类 以及 WebArgumentResolver 类 自定义解析参数
  • IE9 : DOM Exception: INVALID_CHARACTER_ERR (5)
  • 【许晓笛】 EOS 智能合约案例解析(3)
  • Android单元测试 - 几个重要问题
  • Apache Zeppelin在Apache Trafodion上的可视化
  • Django 博客开发教程 8 - 博客文章详情页
  • Docker容器管理
  • electron原来这么简单----打包你的react、VUE桌面应用程序
  • JavaScript函数式编程(一)
  • MD5加密原理解析及OC版原理实现
  • node.js
  • Vue.js 移动端适配之 vw 解决方案
  • vue2.0开发聊天程序(四) 完整体验一次Vue开发(下)
  • Zsh 开发指南(第十四篇 文件读写)
  • 两列自适应布局方案整理
  • 如何优雅的使用vue+Dcloud(Hbuild)开发混合app
  • 如何正确配置 Ubuntu 14.04 服务器?
  • 微信小程序上拉加载:onReachBottom详解+设置触发距离
  • 物联网链路协议
  • 进程与线程(三)——进程/线程间通信
  • ​人工智能之父图灵诞辰纪念日,一起来看最受读者欢迎的AI技术好书
  • # Swust 12th acm 邀请赛# [ E ] 01 String [题解]
  • ###C语言程序设计-----C语言学习(6)#
  • #pragma multi_compile #pragma shader_feature
  • #stm32驱动外设模块总结w5500模块
  • $.proxy和$.extend
  • (arch)linux 转换文件编码格式
  • (二十三)Flask之高频面试点
  • (附源码)ssm基于jsp的在线点餐系统 毕业设计 111016
  • (附源码)计算机毕业设计SSM智慧停车系统
  • (六)激光线扫描-三维重建
  • (七)Knockout 创建自定义绑定
  • (亲测有效)解决windows11无法使用1500000波特率的问题
  • (一)ClickHouse 中的 `MaterializedMySQL` 数据库引擎的使用方法、设置、特性和限制。
  • (一)使用IDEA创建Maven项目和Maven使用入门(配图详解)
  • (已解决)报错:Could not load the Qt platform plugin “xcb“
  • (轉貼) 寄發紅帖基本原則(教育部禮儀司頒布) (雜項)
  • .“空心村”成因分析及解决对策122344
  • .net core webapi Startup 注入ConfigurePrimaryHttpMessageHandler
  • .NET Core WebAPI中使用swagger版本控制,添加注释
  • .Net 知识杂记