------------吾亦無他,唯手熟爾,謙卑若愚,好學若飢-------------
本此博客記錄一套考試題,隨后我把項目以及題目發到github上,簡單的說一下springboot的開發
本此考試題用Spring+SpringMVC+MyBatis+SpringBoot+MySQL+Druid+.yml配置文件+thymeleaf模板引擎
我會把大量源碼放上來,以及整合需要的注意點,大家可以一會去github上下載觀看
項目概覽:
一,jar包,pom.xml中的配置

<?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> <artifactId>z05springbootmyself_exam</artifactId> <packaging>war</packaging> <name>z05springbootmyself_exam Maven Webapp</name> <!-- FIXME change it to the project's website --> <url>http://www.example.com</url> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.3.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</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-logging</artifactId> </dependency> <!-- 核心依賴 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- 可以實現熱部署,在IDEA上實現熱部署還需一些額外的配置,請查閱資料 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <optional>true</optional> <scope>runtime</scope> </dependency> <!-- JDBC for mysql --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <!-- mybatis --> <!--mybatis--> <!-- https://mvnrepository.com/artifact/org.mybatis.spring.boot/mybatis-spring-boot-starter --> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>1.3.1</version> </dependency> <!--fastJson--> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.12</version> </dependency> <!--druid--> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.0.18</version> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.4.1</version> </dependency> <!--thymeleaf 新的模板引擎,比jsp要出色--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <!--jdbc--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency> <!-- 分頁插件 --> <dependency> <groupId>com.github.pagehelper</groupId> <artifactId>pagehelper-spring-boot-starter</artifactId> <version>1.2.3</version> </dependency> </dependencies> <build> <finalName>z05springbootmyself_exam</finalName> <!--maven插件--> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> <!--xml配置,此是為了將來整合Hibernate或者mybatis 默認沒有需要配置 --> <resources> <resource> <directory>src/main/java</directory> <includes> <include>**/*.properties</include> <include>**/*.xml</include> </includes> </resource> </resources> </build> </project>
注意點:如果自己工程不是通過官網骨架創建,自己粘的話,小心粘了倆個parent節點,他不會報錯,但是在后續就不會下載jar包了
二,數據庫腳本,我給一份

DROP TABLE IF EXISTS `air_quality_index`; CREATE TABLE `air_quality_index` ( `id` int(11) NOT NULL AUTO_INCREMENT, `district` varchar(255) NOT NULL, `monitorTime` datetime NOT NULL ON UPDATE CURRENT_TIMESTAMP, `pm10` int(255) NOT NULL, `pm25` int(255) NOT NULL, `monitoringStation` varchar(255) NOT NULL, `createDate` datetime NOT NULL ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=12 DEFAULT CHARSET=utf8; -- ---------------------------- -- Records of air_quality_index -- ---------------------------- INSERT INTO `air_quality_index` VALUES ('1', '西城區', '2018-05-22 09:34:05', '243', '176', '靈境胡同監測站', '2018-05-22 10:57:21'); INSERT INTO `air_quality_index` VALUES ('2', '東城區', '2018-05-22 09:34:05', '27', '33', '東四監測站', '2018-05-22 09:34:35'); INSERT INTO `air_quality_index` VALUES ('3', '海淀區', '2018-05-22 09:34:05', '21', '30', '航天橋監測站', '2018-05-22 09:34:35'); INSERT INTO `air_quality_index` VALUES ('4', '豐台區', '2018-05-22 09:34:05', '24333', '17', '七里庄監測站', '2018-05-22 10:55:20'); INSERT INTO `air_quality_index` VALUES ('5', '西城區', '2018-05-22 09:58:03', '100', '1', '北京某地', '2018-06-22 16:41:51'); INSERT INTO `air_quality_index` VALUES ('6', '東城區', '2018-05-22 09:58:03', '22', '22', '山東某地222333', '2018-05-22 10:54:36'); INSERT INTO `air_quality_index` VALUES ('7', '西城區', '2018-05-22 09:58:03', '22', '22', '天津某地', '2018-05-22 10:57:41'); INSERT INTO `air_quality_index` VALUES ('8', '西城區', '2018-05-22 09:58:03', '122', '232', '山東222', '2018-05-22 10:58:59'); INSERT INTO `air_quality_index` VALUES ('9', '0', '2018-05-22 09:58:03', '22', '22', '北京某地', '2018-05-22 11:26:42'); INSERT INTO `air_quality_index` VALUES ('10', '西城區', '2018-05-22 09:58:03', '22', '22', '天津某地', '2018-06-22 16:42:17'); INSERT INTO `air_quality_index` VALUES ('11', '西城區', '2018-05-22 09:58:03', '1', '22', '靈境胡同監測站', '2018-06-22 16:42:50');
三,application.yml的配置

server: #端口號 port: 8080 spring: #模板引擎 thymeleaf: prefix: classpath:/templates/ mode: HTML5 cache: false #阿里的druid datasource: name: test url: jdbc:mysql:///exam_air username: root password: type: com.alibaba.druid.pool.DruidDataSource driver-class-name: com.mysql.jdbc.Driver filters: stat maxActive: 20 initialSize: 1 maxWait: 60000 minIdle: 1 timeBetweenEvictionRunsMillis: 60000 minEvictableIdleTimeMillis: 300000 validationQuery: select 'x' testWhileIdle: true testOnBorrow: false testOnReturn: false poolPreparedStatements: true maxOpenPreparedStatements: 20 mybatis: #映射的xml文件 mapper-locations: classpath:mapping/*.xml #別名 type-aliases-package: com.happy.entity
注意點:他是一種新的模板,yml不可以使用制表符TAB,它通過空格表示層級關系,同樣的節點反復出現會有問題
我在里面配置了tomcat的端口,druid的數據源,以及mybatis的部分配置
四,項目骨架預覽
五,thymeleaf模板的創建,他是以.html后綴名結尾的文件
1.主頁面:
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <link rel="stylesheet" th:href="@{/css/bootstrap.min.css}"> <!--引入js的時候切記 不需要加 springboot的默認文件名稱--> <script type="text/javascript" th:src="@{/js/jquery-1.8.3.min.js}"></script> <script type="text/javascript" th:src="@{/js/jquery.pagination.js}"></script> <script type="text/javascript" th:src="@{/js/bootstrap-modal.js}"></script> <script type="text/javascript"> window.onload=function () { $("tr:odd").css("background","pink"); } </script> <title>Title</title> <style type="text/css"> table{ border-collapse: collapse; } </style> </head> <body> <table width="70%" border="1" align="center" id="list"> <caption><h1 style="height: 50px;line-height5:0px;border: 1px">空氣質量檢測信息庫</h1> 按區域查詢 <select name="district" id="ourSelect"> <option value="0">不限</option> <option value="西城區">西城區</option> <option value="東城區">東城區</option> <option value="海淀區">海淀區</option> <option value="豐台區">豐台區</option> </select> <input type="button" onclick="myselect()" value="查找"/> <a href="/goAddPage">添加空氣質量信息</a> </caption> <thead> <tr class="t_head"> <th>序號</th> <th>區域</th> <th>檢測時間</th> <th>PM10數據</th> <th>PM2.5數據局</th> <th>監測站</th> </tr> </thead> <tbody id="list-content"> </tbody> </table> <div class="pagination" id="pagination"></div> <div id="isOK"></div> <script type="text/javascript"> $(function () { $("#update").hide(); }) load(); //默認初始化 /*點擊查詢的觸發事件*/ function load() { $.ajax({ url: "/findAll", type: "post", success: function (data) { //清空數據 $("#list-content").html(''); //追加數據 $.each(data, function (i, dom) { //一個dom就是一個新聞對象 $("#list-content").append("<tr><td>"+ dom.id + "</td><td><a onclick='update("+dom.id+")'>"+dom.district+"</a>" + "</td><td>" + dom.monitorTime + "</td><td>" + dom.pm10 + "</td><td >" + dom.pm25 + "</td><td>"+ dom.monitoringStation+"</td></tr>"); }); $("tr:odd").css("background","pink"); } }); }; function myselect() { $.ajax({ url: "/selectByCondition", type: "post", data:{"district":$("#ourSelect").val()}, success: function (data) { //清空數據 $("#list-content").html(''); //追加數據 $.each(data, function (i, dom) { //一個dom就是一個新聞對象 $("#list-content").append("<tr><td>"+ dom.id + "</td><td><a onclick='update("+dom.id+")'>"+dom.district+"</a>" + "</td><td>" + dom.monitorTime + "</td><td>" + dom.pm10 + "</td><td >" + dom.pm25 + "</td><td>"+ dom.monitoringStation+"</td></tr>"); }); $("tr:odd").css("background","pink"); } }); }; function update(id) { $("#update").show(); $("#list").hide(); $.ajax({ url:'/goUpdatePage', type:"post", data:{"id":id}, success:function(data){ $("[name=id]").val(data.id); $("[name=district]").val(data.district); $("[name=monitorTime]").val(data.monitorTime); $("[name=pm10]").val(data.pm10); $("[name=pm25]").val(data.pm25); $("[name=monitoringStation]").val(data.monitoringStation); } }); } </script> <center> <div id="update"> <h2>空氣質量信息維護頁面</h2> <form method="post" action="/updateAir"> <input type="hidden" name="id"/> <p>監測區域: <select name="district"> <option value="0">不限</option> <option value="西城區">西城區</option> <option value="東城區">東城區</option> <option value="海淀區">海淀區</option> <option value="豐台區">豐台區</option> </select></p> <p>監測日期: <input type="text" name="monitorTime" /></p> <p>PM10值: <input type="text" name="pm10" /></p> <p>PM2.5值: <input type="text" name="pm25" /></p> <p>監測站: <input type="text" name="monitoringStation"/></p> <input type="submit" value="更新"/> <input type="button" onclick="javascript:$('#list').show();$('#update').hide()" value="返回"/> </form> </div> </center> </body> </html>
main.html
2.添加頁面:

<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>Title</title> <script type="text/javascript" th:src="@{/js/jquery-1.8.3.min.js}"></script> <style type="text/css"> #box{ width:30%; margin: 0px auto; } </style> <script type="text/javascript"> function checkInfo() { var district=$("[name=district]").val(); var monitorTime=$("[name=monitorTime]").val(); var pm10temp=$("[name=pm10]").val(); var pm10=parseInt(pm10temp); var pm25temp=$("[name=pm25]").val(); var pm25=parseInt(pm25temp); var monitoringStation=$("[name=monitoringStation]").val(); if(monitorTime==""){ alert("檢測時間不能為空"); return false; } if(pm10temp==""){ alert("pm10的值不能為空"); return false; } var reg=/^\d+$/; if(!reg.test(pm10)){ alert('pm10只能為正整數'); return false; } if(pm25temp==""){ alert("pm25不能為空"); return false; } if(monitoringStation==""){ alert("監測站不能為空"); return false; } if(district=="不限"){ alert("監測區域不能選擇不限"); return false; } return true; } $(function () { $("#form1").submit(function () { return checkInfo(); }); }); </script> </head> <body> <div id="box"> <h2>添加空氣質量信息</h2> <form id="form1" method="post" action="/addAir"> <p>監測區域: <select name="district"> <option value="不限">不限</option> <option value="西城區">西城區</option> <option value="東城區">東城區</option> <option value="海淀區">海淀區</option> <option value="豐台區">豐台區</option> </select></p> <p>監測日期: <input type="text"name="monitorTime"/></p> <p>PM10值: <input type="text"name="pm10"/></p> <p>PM2.5值: <input type="text"name="pm25"/></p> <p>監測站: <input type="text"name="monitoringStation"/></p> <input type="submit" value="提交"/> </form> </div> <script type="text/javascript"> </script> </body> </html>
3.修改頁面:

<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>Title</title> <script type="text/javascript" th:src="@{/js/jquery-1.8.3.min.js}"></script> <style type="text/css"> #box{ width:30%; margin: 0px auto; } </style> <script type="text/javascript"> </script> </head> <body> <div id="box"> <h2>空氣質量信息維護頁面</h2> <form method="post" action="/updateAir"> <input type="hidden" name="id" value="${air.id}"/> <p>監測區域: <select name="district"> <option value="0">不限</option> <option value="西城區">西城區</option> <option value="東城區">東城區</option> <option value="海淀區">海淀區</option> <option value="豐台區">豐台區</option> </select></p> <p>監測日期: <input type="text"value="${air.monitorTime}"/></p> <p>PM10值: <input type="text"value="${air.pm10}"/></p> <p>PM2.5值: <input type="text"value="${air.pm25}"/></p> <p>監測站: <input type="text"value="${air.monitoringStation}"/></p> <input type="submit" value="更新"/> <input type="button" value="返回"/> </form> </div> <script type="text/javascript"> </script> </body> </html>
注意點:他是一種新的模板,與jsp寫法有不同,展示數據的方式,引用js,css都不太一樣,也不同與EL,JSTL,需要摸索
它的核心th
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
六,實體類

package cn.happy.entity; import cn.happy.util.JsonDateSerializer; import com.fasterxml.jackson.databind.annotation.JsonSerialize; import org.springframework.format.annotation.DateTimeFormat; import java.util.Date; public class AirModel { private Integer id; private String district; @DateTimeFormat(pattern = "yyyy-MM-dd hh:mm:ss") @JsonSerialize(using = JsonDateSerializer.class) /*處理日期格式*/ private Date monitorTime; private Integer pm10; private Integer pm25; private String monitoringStation; private Date createDate; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getDistrict() { return district; } public void setDistrict(String district) { this.district = district; } public Date getMonitorTime() { return monitorTime; } public void setMonitorTime(Date monitorTime) { this.monitorTime = monitorTime; } public Integer getPm10() { return pm10; } public void setPm10(Integer pm10) { this.pm10 = pm10; } public Integer getPm25() { return pm25; } public void setPm25(Integer pm25) { this.pm25 = pm25; } public String getMonitoringStation() { return monitoringStation; } public void setMonitoringStation(String monitoringStation) { this.monitoringStation = monitoringStation; } public Date getCreateDate() { return createDate; } public void setCreateDate(Date createDate) { this.createDate = createDate; } }
注意點:日期類型處理格式
@DateTimeFormat(pattern = "yyyy-MM-dd hh:mm:ss") @JsonSerialize(using = JsonDateSerializer.class) /*處理日期格式*/ private Date monitorTime;
七,工具類---就是處理日期格式的那個工具類

package cn.happy.util; import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonSerializer; import com.fasterxml.jackson.databind.SerializerProvider; import java.io.IOException; import java.text.SimpleDateFormat; import java.util.Date; public class JsonDateSerializer extends JsonSerializer<Date> { private SimpleDateFormat dateFormat=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); @Override public void serialize(Date date, JsonGenerator gen, SerializerProvider provider) throws IOException, JsonProcessingException { String value = dateFormat.format(date); gen.writeString(value); } }
八,Dao層
1.接口:

package cn.happy.mapper; import cn.happy.entity.AirModel; import java.util.List; import java.util.Map; public interface IAirDAO { //查詢所有 public List<AirModel> findAll() throws Exception; //添加 public int addAir(AirModel model) throws Exception; //修改 public int updateAir(AirModel model) throws Exception; //按條件查詢 public List<AirModel> findAirByCondition(Map<String,Object> map) throws Exception; //根據編號查詢對象的方法 public AirModel selectOneById(Integer id) throws Exception; }
注意:他是一個普通的接口,沒有注解是因為我在別處配置了一道,在yml有配置,在啟動的那個main方法上面也有一道配置
2.dao層的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="cn.happy.mapper.IAirDAO" > <!--01.查詢所有記錄--> <select id="findAll" resultType="cn.happy.entity.AirModel"> select * from air_quality_index </select> <insert id="addAir"> insert into air_quality_index(district,monitorTime,pm10,pm25,monitoringStation,createDate) values(#{district},#{monitorTime},#{pm10},#{pm25},#{monitoringStation},now()) </insert> <!--修改--> <update id="updateAir"> update air_quality_index set district=#{district},monitorTime=#{monitorTime},pm10=#{pm10},pm25=#{pm25},monitoringStation=#{monitoringStation},createDate=now() where id=#{id} </update> <!--按條件查詢--> <select id="findAirByCondition" resultType="cn.happy.entity.AirModel"> select * from air_quality_index <where> <if test='district!="0"'> district=#{district} </if> </where> </select> <!--查詢單項--> <select id="selectOneById" resultType="cn.happy.entity.AirModel"> select * from air_quality_index where id=#{id} </select> </mapper>
注意:命名空間,別名
還有那個智能標簽if test里面的寫法
直接傳的String類型他會報錯,說沒有getString的方法,所以用map往里傳參數
假如test='address!=0',他會報錯,說不可以轉換為數字,故寫為test='address!="0"'即可
九,service層:
1.接口:

package cn.happy.service; import cn.happy.entity.AirModel; import java.util.List; public interface IAirService { //查詢所有 public List<AirModel> findAll() throws Exception; //添加 public int addAir(AirModel model) throws Exception; //修改 public int updateAir(AirModel model) throws Exception; //按條件查詢 public List<AirModel> findAirByCondition(String district) throws Exception; //根據編號查詢對象的方法 public AirModel selectOneById(Integer id) throws Exception; }
2.實現類:

package cn.happy.service.impl; import cn.happy.entity.AirModel; import cn.happy.mapper.IAirDAO; import cn.happy.service.IAirService; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import javax.annotation.Resource; import java.util.HashMap; import java.util.List; import java.util.Map; @Service("airService") public class AirServiceImpl implements IAirService { @Resource(name = "IAirDAO") private IAirDAO dao; @Override public List<AirModel> findAll() throws Exception { return dao.findAll(); } @Override @Transactional public int addAir(AirModel model) { try { return dao.addAir(model); } catch (Exception e) { e.printStackTrace(); return 0; } } @Override public int updateAir(AirModel model) throws Exception { return dao.updateAir(model); } @Override public List<AirModel> findAirByCondition(String district) throws Exception { Map<String,Object> map=new HashMap<String,Object>(); map.put("district",district); return dao.findAirByCondition(map); } @Override public AirModel selectOneById(Integer id) throws Exception { return dao.selectOneById(id); } }
注意點:和普通的SSM注解開發沒有什么太大的區別,值得注意的是事務的運用,需要在main那邊開啟一道配置
十,controller層:

package cn.happy.controller; import cn.happy.entity.AirModel; import cn.happy.service.IAirService; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import javax.annotation.Resource; import javax.validation.constraints.FutureOrPresent; import java.util.List; @Controller public class FirstController { //植入Service @Resource(name = "airService") private IAirService myAirService; @RequestMapping("/goHome") public String getHome(){ return "main"; } @RequestMapping("/findAll") @ResponseBody public Object findAll() throws Exception { List<AirModel> list = myAirService.findAll(); return list; } @RequestMapping("/goAddPage") public String goAddPage(){ return "addAir"; } //添加數據 @RequestMapping("/addAir") public String addAir(AirModel model, Model modelData) throws Exception { int count = myAirService.addAir(model); if (count>0){ return "redirect:goHome"; }else{ modelData.addAttribute("erroMsg","添加失敗"); return "redirect:goHome"; } } @RequestMapping("/goUpdatePage") @ResponseBody public Object goUpdatePage(int id) throws Exception { AirModel air = myAirService.selectOneById(id); return air; } @RequestMapping("/updateAir") public String updateAir(AirModel model) throws Exception { int count = myAirService.updateAir(model); return "redirect:goHome"; } //按條件查詢 @RequestMapping("selectByCondition") @ResponseBody public Object selectByCondition(String district) throws Exception { List<AirModel> list = myAirService.findAirByCondition(district); return list; } }
普普通通,做過SSM的發現,沒什么不同
十一,SpringBoot核心啟動類的配置
package cn.happy; import org.mybatis.spring.annotation.MapperScan; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.transaction.annotation.EnableTransactionManagement; @SpringBootApplication //掃描mapper映射 @MapperScan("cn.happy.*") /*開啟事務*/ @EnableTransactionManagement public class ExamApplication { public static void main(String[] args) { SpringApplication.run(ExamApplication.class, args); } }
注意點:開啟事務和mybatis的掃描
十二,可以啟動項目和調試了
注意:
我沒仔細講js,css,logback,logback就普通配置,無關緊要,css,js放在static下面即可,引入方式可以參考案例,我引用了一個bootstrap的js,這無關緊要,不影響,只需要jquery即可
作者:晨曦Dawn
轉載請注明出處,地址:https://www.cnblogs.com/DawnCHENXI/p/9221212.html
github地址:(一會上傳完成之后,發出來)
如果上方博客有錯誤或者疑惑,請指出,感激不敬!!!!!!!!!!!!!!