------------吾亦无他,唯手熟尔,谦卑若愚,好学若饥-------------
本此博客记录一套考试题,随后我把项目以及题目发到github上,简单的说一下springboot的开发
本此考试题用Spring+SpringMVC+MyBatis+SpringBoot+MySQL+Druid+.yml配置文件+thymeleaf模板引擎
我会把大量源码放上来,以及整合需要的注意点,大家可以一会去github上下载观看
项目概览:
一,jar包,pom.xml中的配置
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 z05springbootmyself_exam war z05springbootmyself_exam Maven Webapp http://www.example.com org.springframework.boot spring-boot-starter-parent 2.0.3.RELEASE UTF-8 UTF-8 1.8 org.springframework.boot spring-boot-starter org.springframework.boot spring-boot-starter-logging org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-devtools true runtime mysql mysql-connector-java runtime org.springframework.boot spring-boot-starter-test test org.mybatis.spring.boot mybatis-spring-boot-starter 1.3.1 com.alibaba fastjson 1.2.12 com.alibaba druid 1.0.18 org.mybatis mybatis 3.4.1 org.springframework.boot spring-boot-starter-thymeleaf org.springframework.boot spring-boot-starter-jdbc com.github.pagehelper pagehelper-spring-boot-starter 1.2.3 z05springbootmyself_exam org.springframework.boot spring-boot-maven-plugin src/main/java **/*.properties **/*.xml
注意点:如果自己工程不是通过官网骨架创建,自己粘的话,小心粘了俩个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}">
<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>Titletitle>
<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(""+ dom.id + " "+dom.id+")'>"+dom.district+"" + " " + dom.monitorTime + " " + dom.pm10 + " " + dom.pm25 + " "+
dom.monitoringStation+" ");
});
$("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(""+ dom.id + " "+dom.id+")'>"+dom.district+"" + " " + dom.monitorTime + " " + dom.pm10 + " " + dom.pm25 + " "+
dom.monitoringStation+" ");
});
$("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>Titletitle>
<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>Titletitle>
<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{ 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" > <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 ListfindAll() throws Exception; //添加 public int addAir(AirModel model) throws Exception; //修改 public int updateAir(AirModel model) throws Exception; //按条件查询 public List 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 ListfindAll() 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 findAirByCondition(String district) throws Exception { Map map=new HashMap (); 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 { Listlist = 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 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地址:(一会上传完成之后,发出来)
如果上方博客有错误或者疑惑,请指出,感激不敬!!!!!!!!!!!!!!