前言:很早以前就想要寫一個本身的博客了,趁着如今學校安排的實習有不少的空檔,決定把它給作出來,也順便完成實習的任務(搞一個項目出來...)html
整體目標:設計一套自適應/簡潔/美觀/易於文章管理髮布的一個屬於我我的的博客,最後一頁能展現我我的的簡歷,由於大三快結束了立刻就該去找工做了...哦忘了,最重要的仍是要支持Markdown才行,由於已經習慣了...前端
首先,前端的頁面要求是:java
而後,思考了一下可能出現的頁面:
mysql
1)首頁:git
2)文章頁:github
3)簡歷頁:web
這是預留的頁面,到時候用來顯示我的的簡歷;spring
4)關於頁:sql
用來介紹項目的搭建編寫過程,還有使用的技術棧啊之類的,而後留下我的的聯繫方式,Nice;數據庫
5)留言頁:
由於是我的的博客,因此我並不想要限制看官們留言的權利,我但願他們能本身能定義用於顯示的用戶名,可是須要填寫一個Email,否則搞得我不能回覆,那搞個啥...固然也能夠不留Email,也就是不但願獲得回覆唄(那可能有些留言會讓我難受死吧..思考...)...
最初的思考是這樣的:
後來一想,文章置頂這個都給忘了...而後發現其實有一個很關鍵的問題就是Markdown的文章應該怎樣保存?一開始仍是想要保存爲.md文件保存在服務器的硬盤上的,但想一想直接保存在數據庫裏也不錯,省的麻煩,並且我很明確一點的是:我並不會直接在博客上寫Markdown,由於有許許多多成熟的產品能讓我寫的舒心的多,我不必去搞這麼麻煩複雜繁瑣,並且不必定好,因此我只須要用博客來展現我寫的Markdown格式的博文就行了,Nice啊...又成功騙本身少寫了好多代碼hhhhh(沒有啦..需求就這樣的嘛...)
順着這樣的思路,我一般寫文都是先在簡書上寫好的,而且簡書有一個特色是全部的圖片,無論是已經發布的文章仍是沒有發佈的私人文章,都能經過地址取得,能夠利用這一點讓簡書當個圖牀,誒又少弄了一部分代碼,而後分析分析着就把需求搞成下面這樣了:
1)博文管理:
這個比較常規,就不說了;
2)網站數據統計:
做爲網站的擁有者和設計者,我固然但願能但願知道這些數據了,而後單獨做爲擁有者來講,最好再分爲日訪問量/月訪問量/總訪問量這樣子顯示出來,再搞搞樣式,簡直不要太爽;
3)緩存管理:
圖片就沒緩存了,由於保存文章內容我須要保存md源碼,因此可能須要在Redis裏緩存最近常訪問的文章的md轉HTML後渲染好的HTML源碼;
4)系統設置:
網站標題能夠改呀,而後導航欄的名字也能夠弄弄呀,其實這個也能夠不用去搞,只是以防有時候心情很差給一整搗鼓可能心情就行了,hhhhh....;
5)留言管理:
有一些流氓留言能夠刪掉,最近學習到的比較好的方法是讓該條數據的狀態爲置爲0,而不是直接刪除該條數據,這個設計數據庫的時候就須要多設計一個字段,也能夠經過用戶留下的Email地址進行回覆,最好搞一個自動通知,完美;
經過需求分析,而後嚴格按照《阿里巴巴Java開發手冊》(下面所說的規範均來自於此)反覆分析了不少遍,最終肯定了以下的幾張表:
而後來具體說一下各個表:
1)日誌表(sys_log):
CREATE TABLE `sys_log` ( `id` bigint(40) NOT NULL AUTO_INCREMENT COMMENT '主鍵', `ip` varchar(20) NOT NULL DEFAULT '' COMMENT '操做地址的IP', `create_by` datetime NOT NULL COMMENT '操做時間', `remark` varchar(255) NOT NULL DEFAULT '' COMMENT '操做內容', `operate_url` varchar(50) NOT NULL DEFAULT '' COMMENT '操做的訪問地址', `operate_by` varchar(20) DEFAULT '' COMMENT '操做的瀏覽器', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
這張表就是拿來保存日誌,用來記錄每個用戶訪問了哪些地址,使用了什麼樣的瀏覽器,操做內容能夠做爲一個保留字段,若是之後想要監控用戶行爲,那也是能夠的~
這裏首先遵照的規範是(下面雷同則再也不重複贅述):
想要拿出來跟你們討論的一則規範是:
像如上設計的日誌表,它插入進去了就不會再更新了,並且對於我這個系統也很大機率不會有趣操做這個表的可能,那麼對於這樣不會更新和操做的表,gmt_modified這個字段還有必要存在嗎?
emmm..事實上我問了孤盡大大本人,他回答的簡潔有力:「要的,以備不時之需;」然而原諒我仍是沒有聽話,hhhhh,另一點我想說的是,我忘了是在哪裏看到的了,可是像gmt_create這樣的字段最好設計成create_by這樣,字段自己就是很好的註釋,摁,就喜歡這樣滿滿的細節...
2)瀏覽量表(sys_view):
CREATE TABLE `sys_view` ( `id` bigint(40) NOT NULL AUTO_INCREMENT, `ip` varchar(20) NOT NULL COMMENT '訪問IP', `create_by` datetime NOT NULL COMMENT '訪問時間', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
這張表用於保存每一次訪問主頁的記錄,我想的是每訪問主頁就記錄增長一條數據,簡單同時也增長訪問量嘛,hhhhh,也是不會更新的一張表,因此沒modifield_by字段;
3)留言/評論表(tbl_message)
CREATE TABLE `tbl_message` ( `id` bigint(40) NOT NULL AUTO_INCREMENT COMMENT '主鍵', `content` varchar(200) NOT NULL DEFAULT '' COMMENT '留言/評論內容', `create_by` datetime NOT NULL COMMENT '建立日期', `email` varchar(20) NOT NULL DEFAULT '' COMMENT '郵箱,用於回覆消息', `name` varchar(20) NOT NULL DEFAULT '' COMMENT '用戶本身定義的名稱', `ip` varchar(20) NOT NULL DEFAULT '' COMMENT '留言/評論IP', `is_effective` tinyint(1) NOT NULL DEFAULT '1' COMMENT '是否有效,默認爲1爲有效,0爲無效', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='由於message分爲兩種,一種是留言,一種是評論,這裏搞成一張表是由於它們幾乎是擁有相同的字段,我以爲不必分紅兩張表來進行維護';
這是評論/留言表,由於考慮到留言和評論有幾乎相同的字段,因此給弄成了一張表,這張表一樣的不須要更新沒有modifield_by字段,這裏遵照的規範是:
4)分類信息表(tbl_sort_info):
CREATE TABLE `tbl_sort_info` ( `id` bigint(40) NOT NULL AUTO_INCREMENT, `name` varchar(20) NOT NULL COMMENT '分類名稱', `number` tinyint(10) NOT NULL DEFAULT '0' COMMENT '該分類下的文章數量', `create_by` datetime NOT NULL COMMENT '分類建立時間', `modified_by` datetime NOT NULL COMMENT '分類修改時間', `is_effective` tinyint(1) NOT NULL DEFAULT '1' COMMENT '是否有效,默認爲1有效,爲0無效', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
這張表是文章的分類,一開始都忘記設計了....
5)文章信息表(tbl_article_info):
CREATE TABLE `tbl_article_info` ( `id` bigint(40) NOT NULL AUTO_INCREMENT COMMENT '主鍵', `title` varchar(50) NOT NULL DEFAULT '' COMMENT '文章標題', `summary` varchar(300) NOT NULL DEFAULT '' COMMENT '文章簡介,默認100個漢字之內', `is_top` tinyint(1) NOT NULL DEFAULT '0' COMMENT '文章是否置頂,0爲否,1爲是', `traffic` int(10) NOT NULL DEFAULT '0' COMMENT '文章訪問量', `create_by` datetime NOT NULL COMMENT '建立時間', `modified_by` datetime NOT NULL COMMENT '修改日期', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
這是文章信息表,都是一些基礎經常使用的字段就再也不多作解釋了
6)文章內容表(tbl_article_content):
CREATE TABLE `tbl_article_content` ( `id` bigint(40) NOT NULL AUTO_INCREMENT, `content` text NOT NULL, `article_id` bigint(40) NOT NULL COMMENT '對應文章ID', `create_by` datetime NOT NULL COMMENT '建立時間', `modifield_by` datetime NOT NULL COMMENT '更新時間', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
這是文章內容表,咱們並無直接把內容字段設計在文章信息表裏,而是單獨建了一個表用來保存文章的內容,而後使用主鍵來關聯,咱們這裏遵照的規範是:
我試過我如今最長的一篇文章長度大概能存儲8W長度的varchar,因此我就給單獨建一個表分離出來了,使用text類型來保存文章的md源碼
7)文章評論表(tbl_article_message):
CREATE TABLE `tbl_article_message` ( `id` bigint(40) NOT NULL AUTO_INCREMENT, `article_id` bigint(40) NOT NULL COMMENT '文章ID', `message_id` bigint(40) NOT NULL COMMENT '對應的留言ID', `create_by` datetime NOT NULL COMMENT '建立時間', `is_effective` tinyint(1) NOT NULL DEFAULT '1' COMMENT '是否有效,默認爲1有效,置0無效', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
這實際上是一個關聯表,關聯了文章和tbl_message表,用於專門存儲某個文章下的評論信息
8)文章分類表(tbl_article_sort):
CREATE TABLE `tbl_article_sort` ( `id` bigint(40) NOT NULL AUTO_INCREMENT, `sort_id` bigint(40) NOT NULL COMMENT '分類id', `article_id` bigint(40) NOT NULL COMMENT '文章id', `create_by` datetime NOT NULL COMMENT '建立時間', `modified_by` datetime NOT NULL COMMENT '更新時間', `is_effective` tinyint(1) DEFAULT '1' COMMENT '表示當前數據是否有效,默認爲1有效,0則無效', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
一樣是一張關聯表,鏈接了文章和分類,而且同一篇文章能屬於多個分類;
9)文章題圖表(tbl_article_picture):
CREATE TABLE `tbl_article_picture` ( `id` bigint(40) NOT NULL AUTO_INCREMENT, `article_id` bigint(40) NOT NULL COMMENT '對應文章id', `picture_url` varchar(100) NOT NULL DEFAULT '' COMMENT '圖片url', `create_by` datetime NOT NULL COMMENT '建立時間', `modified_by` datetime NOT NULL COMMENT '更新時間', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='這張表用來保存題圖url,每一篇文章都應該有題圖';
這個是保存每一篇文章的題圖,每一篇文章都因該有題圖;
事實上,我是直接先去找的原型,去參考了一下大概我須要作成什麼樣子...
在這裏先給你們推薦一個設計網站吧,找素材啊之類的還挺方便的:
站酷:http://www.zcool.com.cn/
因此我在裏面找到了我想要的前端原型,大概就像這個樣子:
1)首頁:
2)博客頁:
3)博文詳情頁:
4)博文列表頁:
不能再酷了..
emmmm...大概就像這樣了吧,具體的樣式能夠到時候再調...
整體是酷的就行!
先來介紹一下此次想要使用的一些技術:
SpringBoot 項目搭建過程就再也不贅述了,不熟悉的童鞋戳這邊:https://www.jianshu.com/p/70963ab49f8c,這裏就簡單給一下配置信息:
後臺確定是須要加安全驗證的,要簡單點我能夠搞一個攔截器來簡單弄弄,也能夠用現有的安全框架,這裏暫時就不加入這方面的東西了,把基本的弄進來就OK,而後它默認加入的東西不可以支持咱們的業務,因此還須要手動添加進一些包:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>cn.wmyskxz</groupId> <artifactId>blog</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>blog</name> <description>Demo project for Spring Boot</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.2.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!--MyBatis--> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>1.3.2</version> </dependency> <!--MyBatis逆向工程--> <dependency> <groupId>org.mybatis.generator</groupId> <artifactId>mybatis-generator-core</artifactId> <version>1.3.6</version> </dependency> <!--SpringBoot測試支持--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <!--MySQL--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> <!--SpringBoot熱部署--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <optional>true</optional> <!-- 這個須要爲 true 熱部署纔有效 --> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
熱部署仍是要的呀,而後再在【resrouces】下新建一個【banner.txt】文件,修改一下SpringBoot啓動的提示信息:
__ __ __ /\ \ __/\ \ /\ \ \ \ \/\ \ \ \ ___ ___ __ __ ____\ \ \/'\ __ _ ____ \ \ \ \ \ \ \ /' __` __`\ /\ \/\ \ /',__\\ \ , < /\ \/'\/\_ ,`\ \ \ \_/ \_\ \/\ \/\ \/\ \\ \ \_\ \ /\__, `\\ \ \\`\ \/> </\/_/ /_ \ `\___x___/\ \_\ \_\ \_\\/`____ \\/\____/ \ \_\ \_\/\_/\_\ /\____\ '\/__//__/ \/_/\/_/\/_/ `/___/> \\/___/ \/_/\/_/\//\/_/ \/____/ /\___/ \/__/
弄弄結構,最後整個項目的目錄看起來大概是這個樣子:
下面對這些目錄進行一些簡要的說明:
而後我使用application.yml文件代替了application.properties,這個東西結構清晰一點兒,反正用哪一個都無所謂,配置好就OK了:
spring: datasource: url: jdbc:mysql://127.0.0.1:3306/blog?characterEncoding=UTF-8 username: root password: 123456 driver-class-name: com.mysql.jdbc.Driver #Druid鏈接池配置相關 druid: # 初始大小,最大,最小 initial-size: 5 min-idle: 5 max-active: 20 # 配置獲取鏈接等待超時的時間 max-wait: 60000 # 配置間隔多久才進行一次檢測,檢測須要關閉的空閒鏈接,單位是毫秒 time-between-eviction-runs-millis: 60000 # 配置一個鏈接在池中最小生存的時間,單位是毫秒 min-evictable-idle-time-millis: 300000
不須要檢測數據庫,不要整這麼複雜,不過卻是須要給數據庫密碼加個密,明文的配置實在不安全,可是如今先不搞了;
使用過MyBatis逆向工程的朋友都應該知道,這東西有個BUG,就是重複生成的時候它並不會覆蓋掉原來的內容(特指xml映射文件),而是會在後面從新生成一遍,這有點兒頭疼,因此首先須要解決這個問題:
首先在【util】包下新建一個【OverIsMergeablePlugin】工具類:
package cn.wmyskxz.blog.util; import org.mybatis.generator.api.GeneratedXmlFile; import org.mybatis.generator.api.IntrospectedTable; import org.mybatis.generator.api.PluginAdapter; import java.lang.reflect.Field; import java.util.List; /** * 避免MyBatiis重複生成的工具類 * * @author:wmyskxz * @create:2018-06-14-上午 9:50 */ public class OverIsMergeablePlugin extends PluginAdapter { @Override public boolean validate(List<String> warnings) { return true; } @Override public boolean sqlMapGenerated(GeneratedXmlFile sqlMap, IntrospectedTable introspectedTable) { try { Field field = sqlMap.getClass().getDeclaredField("isMergeable"); field.setAccessible(true); field.setBoolean(sqlMap, false); } catch (Exception e) { e.printStackTrace(); } return true; } }
而後在【generatorConfig.xml】中配置上該工具類:
<plugin type="cn.wmyskxz.blog.util.OverIsMergeablePlugin"/>
好的這樣就搞定了,咱們就正式開始咱們的逆向工程:
1)編寫generatorConfig.xml逆向工程配置文件:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE generatorConfiguration PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN" "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd"> <generatorConfiguration> <context id="DB2Tables" targetRuntime="MyBatis3"> <!--避免生成重複代碼的插件--> <plugin type="cn.wmyskxz.blog.util.OverIsMergeablePlugin"/> <!--是否在代碼中顯示註釋--> <commentGenerator> <property name="suppressDate" value="true"/> <property name="suppressAllComments" value="true"/> </commentGenerator> <!--數據庫連接地址帳號密碼--> <jdbcConnection driverClass="com.mysql.jdbc.Driver" connectionURL="jdbc:mysql://127.0.0.1:3306/blog?characterEncoding=UTF-8" userId="root" password="123456"> </jdbcConnection> <!--生成pojo類存放位置--> <javaModelGenerator targetPackage="cn.wmyskxz.blog.entity" targetProject="src/main/java"> <property name="enableSubPackages" value="true"/> <property name="trimStrings" value="true"/> </javaModelGenerator> <!--生成xml映射文件存放位置--> <sqlMapGenerator targetPackage="mapper" targetProject="src/main/resources"> <property name="enableSubPackages" value="true"/> </sqlMapGenerator> <!--生成mapper類存放位置--> <javaClientGenerator type="XMLMAPPER" targetPackage="cn.wmyskxz.blog.dao" targetProject="src/main/java"> <property name="enableSubPackages" value="true"/> </javaClientGenerator> <!--生成對應表及類名--> <table tableName="sys_log" domainObjectName="SysLog" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="true" selectByExampleQueryId="false"> <!--使用自增加鍵--> <property name="my.isgen.usekeys" value="true"/> <!--使用數據庫中實際的字段名做爲生成的實體類的屬性--> <property name="useActualColumnNames" value="true"/> <generatedKey column="id" sqlStatement="JDBC"/> </table> <table tableName="sys_view" domainObjectName="SysView" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="true" selectByExampleQueryId="false"> <property name="my.isgen.usekeys" value="true"/> <property name="useActualColumnNames" value="true"/> <generatedKey column="id" sqlStatement="JDBC"/> </table> <table tableName="tbl_article_content" domainObjectName="ArticleContent" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="true" selectByExampleQueryId="false"> <property name="my.isgen.usekeys" value="true"/> <property name="useActualColumnNames" value="true"/> <generatedKey column="id" sqlStatement="JDBC"/> </table> <table tableName="tbl_article_info" domainObjectName="ArticleInfo" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="true" selectByExampleQueryId="false"> <property name="my.isgen.usekeys" value="true"/> <property name="useActualColumnNames" value="true"/> <generatedKey column="id" sqlStatement="JDBC"/> </table> <table tableName="tbl_article_message" domainObjectName="ArticleMessage" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="true" selectByExampleQueryId="false"> <property name="my.isgen.usekeys" value="true"/> <property name="useActualColumnNames" value="true"/> <generatedKey column="id" sqlStatement="JDBC"/> </table> <table tableName="tbl_message" domainObjectName="Message" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="true" selectByExampleQueryId="false"> <property name="my.isgen.usekeys" value="true"/> <property name="useActualColumnNames" value="true"/> <generatedKey column="id" sqlStatement="JDBC"/> </table> <table tableName="tbl_sort_info" domainObjectName="SortInfo" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="true" selectByExampleQueryId="false"> <property name="my.isgen.usekeys" value="true"/> <property name="useActualColumnNames" value="true"/> <generatedKey column="id" sqlStatement="JDBC"/> </table> <table tableName="tbl_article_sort" domainObjectName="ArticleSort" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="true" selectByExampleQueryId="false"> <property name="my.isgen.usekeys" value="true"/> <property name="useActualColumnNames" value="true"/> <generatedKey column="id" sqlStatement="JDBC"/> </table> </context> </generatorConfiguration>
注意表名/生成目標目錄之類的有沒有寫錯,表名最好就直接去複製數據庫中的名稱;
2)編寫逆向工程生成類:
package cn.wmyskxz.blog.generator; import org.mybatis.generator.api.MyBatisGenerator; import org.mybatis.generator.config.Configuration; import org.mybatis.generator.config.xml.ConfigurationParser; import org.mybatis.generator.exception.XMLParserException; import org.mybatis.generator.internal.DefaultShellCallback; import java.io.IOException; import java.io.InputStream; import java.sql.SQLException; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.List; /** * MyBatis逆向工程生成類 * * @author:wmyskxz * @create:2018-06-14-上午 10:10 */ public class MybatisGenerator { public static void main(String[] args) throws Exception { String today = "2018-6-14"; SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); Date now = sdf.parse(today); Date d = new Date(); if (d.getTime() > now.getTime() + 1000 * 60 * 60 * 24) { System.err.println("——————未成成功運行——————"); System.err.println("——————未成成功運行——————"); System.err.println("本程序具備破壞做用,應該只運行一次,若是必需要再運行,須要修改today變量爲今天,如:" + sdf.format(new Date())); return; } if (false) return; List<String> warnings = new ArrayList<String>(); boolean overwrite = true; InputStream is = MybatisGenerator.class.getClassLoader().getResource("generatorConfig.xml").openStream(); ConfigurationParser cp = new ConfigurationParser(warnings); Configuration config = cp.parseConfiguration(is); is.close(); DefaultShellCallback callback = new DefaultShellCallback(overwrite); MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config, callback, warnings); myBatisGenerator.generate(null); System.out.println("生成代碼成功,只能執行一次,之後執行會覆蓋掉mapper,pojo,xml 等文件上作的修改"); } }
這個是參考自how2j.cn的逆向工程,這個能夠說是很成熟的模塊了,寫的很棒,考慮了安全方面的一些東西,連接在這裏:http://how2j.cn/k/tmall_ssm/tmall_ssm-1547/1547.html
3)點擊運行:
控制檯看到成功的信息以後,就能看到項目中自動多了一堆文件了:
爲了實現先後端分離,好的RESTful API是離不開的,正好前一段時間學習了這方面的知識,因此決定先來設計一套RESTful API,以前學習的文章連接在這裏:https://www.jianshu.com/p/91600da4df95
1)引入Swagger2來構造RESTful API:
既然想弄一下先後端分離,那就完全一點兒,寫後臺徹底無論前臺,先後臺的交互靠一套RESTful API和JSON數據來弄,因此須要一個文檔來瞅瞅,首先在pox.xml添加相關依賴:
<!--Swagger2支持--> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger2</artifactId> <version>2.2.2</version> </dependency> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger-ui</artifactId> <version>2.2.2</version> </dependency>
2)建立Swagger2配置類:
在SpringBoot啓動類的同級目錄下建立Swagger2的配置類【Swagger2】:
/** * Swagger2 配置類 * * @author:wmyskxz * @create:2018-06-14-上午 10:40 */ @Configuration @EnableSwagger2 public class Swagger2 { @Bean public Docket createRestApi() { return new Docket(DocumentationType.SWAGGER_2) .apiInfo(apiInfo()) .select() .apis(RequestHandlerSelectors.basePackage("cn.wmyskxz.blog")) .paths(PathSelectors.any()) .build(); } private ApiInfo apiInfo() { return new ApiInfoBuilder() .title("Wmyskxz我的博客RESTful APIs") .description("原文地址連接:http://blog.didispace.com/springbootswagger2/") .termsOfServiceUrl("http://blog.didispace.com/") .contact("@我沒有三顆心臟") .version("1.0") .build(); } }
這樣,就能夠在咱們啓動項目以後,訪問http://localhost:8080/swagger-ui.html
地址來查看當前項目中的RESTful風格的API:
3)設計RESTful API:
好的,搗鼓了半天,終於有了一些雛形:
可是這也只是設計了API,具體都尚未實現,這些就在寫後臺的時候來完善了,具體的這些內容怎麼顯示出來的,我給一個【SortController】的參考類:
/** * 分類信息控制器 * * @author:wmyskxz * @create:2018-06-14-下午 13:25 */ @RestController @RequestMapping("/api/sort") public class SortController { /** * 獲取全部分類信息 * * @return */ @ApiOperation("獲取全部分類信息") @GetMapping("/list") public List<SortInfo> listAllSortInfo() { return null; } /** * 經過id獲取一條分類信息 * * @param id * @return */ @ApiOperation("獲取某一條分類信息") @ApiImplicitParam(name = "id", value = "分類ID", required = true, dataType = "Long") @GetMapping("/{id}") public SortInfo getSortInfoById(@PathVariable Long id) { return null; } /** * 增長一條分類信息數據 * * @return */ @ApiOperation("增長分類信息") @ApiImplicitParam(name = "name", value = "分類名稱", required = true, dataType = "String") @PostMapping("") public String addSortInfo() { return null; } /** * 更新/編輯一條數據 * * @param id * @return */ @ApiOperation("更新/編輯分類信息") @ApiImplicitParam(name = "id", value = "分類ID", required = true, dataType = "Long") @PutMapping("/{id}") public String updateSortInfo(@PathVariable Long id) { return null; } /** * 根據ID刪除分類信息 * * @param id * @return */ @ApiOperation("刪除分類信息") @ApiImplicitParam(name = "id", value = "分類ID", required = true, dataType = "Long") @DeleteMapping("/{id}") public String deleteSortInfo(@PathVariable Long id) { return null; } }
簡單介紹一下這些Swagger2的註解吧:
這裏沒有具體實現因此就不足以完成測試,等到後臺編寫的時候再進行測試吧...
至此呢,咱們項目所須要的準備就差很少完成了,想要去作一個東西必需要清楚的知道要的是一個什麼東西,這樣才能更加好的完成咱們的產品,這也是我喜歡和堅信的事情:方向永遠比努力重要!(強行有聯繫..hhhh)
另一個問題: 我在想文章信息和內容分紅了兩個表的問題,這樣的設計我以爲是沒有問題的,可是做爲前端並不關心這些數據庫的設計,他只要能拿到對象就能夠了,在設計 API 的時候,就發現得到一篇文章,須要從三個表(文章信息/文章內容/評論)去獲取信息並封裝返回前端,這就須要本身在後臺另外寫一個實體類去封裝這些信息,這無疑增長了咱們的代碼工做量,有沒有什麼好的方法解決呢?
歡迎轉載,轉載請註明出處!
簡書ID:@我沒有三顆心臟
github:wmyskxz 歡迎關注公衆微信號:wmyskxz_javaweb 分享本身的Java Web學習之路以及各類Java學習資料