天天看點

SSM基礎架構搭建

    SSM(Spring + SpringMVC + MyBatis)三個開源架構的簡稱,是WEB項目開發的不二之選,是碼農進階全棧工程師心路曆程上的驿站。大公司開源架構和算法制定标準規範引領行業趨勢,小公司拿來主義面向業務靈活開發快速疊代在夾縫中艱難生存。SSM架構完美的符合了當下的這種行業現狀,對于底層是如何實作的開發人員完全不必關注,踏踏實實梳理好業務邏輯,做好品質把控年底KPI基本問題就不大了。

    Spring是一個輕量級IoC及AOP容器架構,配置又多又細,SpringBoot簡化了大量通用且不常用的配置項,使建構一個微服務變得超簡單;SpringMVC是目前最優秀的MVC架構,注解用得好事半功倍;MyBatis用于資料持久化,MyBatisPlus增強版内置分頁功能簡化開發流程自動化代碼生成,唯一要做的事情就剩下寫寫SQL了。

    無私的分享從這裡開始: git clone [email protected]: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
           

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);
    }
}           

    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("/**");
    }
}           

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 {
    }
}           

    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());
    }
}           

    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;
    // (省略)
}           

    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();
    }
}           

    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();
}           

    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>           

    select塊部分是需要開發者實作的,把調試好的SQL複制到這裡就OK了。

    SSM架構設計的異常出色,使用起來異常便利,不過坑很多,踩一個少一個,都踩遍了工作起來就會變得很輕松,但是也會很乏味,剩下的事情全是面對不斷的需求變更、業務調整和功能擴充,在日複一日的重複中慢慢老去~~~