空气质量管理系统+SSM(Spring+SpringMVC+Mybatis)+前后端分离总结
程序员文章站
2022-04-10 13:56:04
空气质量管理系统+SSM(Spring+SpringMVC+Mybatis)+前后端分离总结 ......
作者:故事我忘了¢
个人微信公众号:程序猿的月光宝盒
个人微信公众号:程序猿的月光宝盒
点我进ssm演示地址
1.目录结构:
2.需要注意的地方
2.1在web-info下新建
2.1.1 springmvc-servlet.xml
<?xml version="1.0" encoding="utf-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/xmlschema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemalocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd "> <context:component-scan base-package="monster._52cc"/> <bean id="datasource" class="org.springframework.jdbc.datasource.drivermanagerdatasource"> <property name="driverclassname" value="com.mysql.jdbc.driver"/> <property name="url" value="jdbc:mysql:///kh75?useunicode=true&characterencoding=utf-8"/> <property name="username" value="root"/> <property name="password" value="admin"/> </bean> <bean id="sqlsessionfactory" class="org.mybatis.spring.sqlsessionfactorybean"> <property name="datasource" ref="datasource"/> <property name="typealiasespackage" value="monster._52cc.pojo"/> <property name="typealiases" value="monster._52cc.util.pageutils"/> </bean> <bean id="transactionmanager" class="org.springframework.jdbc.datasource.datasourcetransactionmanager"> <property name="datasource" ref="datasource"/> </bean> <tx:annotation-driven/> <bean class="org.mybatis.spring.mapper.mapperscannerconfigurer"> <property name="basepackage" value="monster._52cc.mapper"/> </bean> <!--这是从controller层使用@restcontroller注解引起从数据库到前台时间出现long类型的时间(从1970-1-1至今的毫秒),解决springmvc 中@restcontroller 返回日期格式为时间戳--> <mvc:annotation-driven> <mvc:message-converters> <bean class="org.springframework.http.converter.json.mappingjackson2httpmessageconverter"> <property name="objectmapper"> <bean class="com.fasterxml.jackson.databind.objectmapper"> <property name="dateformat"> <bean class="java.text.simpledateformat"> <constructor-arg type="java.lang.string" value="yyyy-mm-dd hh:mm:ss"/> </bean> </property> </bean> </property> </bean> </mvc:message-converters> </mvc:annotation-driven> </beans>
2.1.2 web.xml
<!doctype web-app public "-//sun microsystems, inc.//dtd web application 2.3//en" "http://java.sun.com/dtd/web-app_2_3.dtd" > <web-app> <display-name>archetype created web application</display-name> <filter> <filter-name>encodingfilter</filter-name> <filter-class>org.springframework.web.filter.characterencodingfilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>utf-8</param-value> </init-param> </filter> <filter-mapping> <filter-name>encodingfilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <servlet> <servlet-name>springmvc</servlet-name> <servlet-class>org.springframework.web.servlet.dispatcherservlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>springmvc</servlet-name> <url-pattern>*.do</url-pattern> </servlet-mapping> <welcome-file-list> <welcome-file>list.html</welcome-file> </welcome-file-list> </web-app>
2.2实体类,对应数据库中data的字段上加注解 @datetimeformat(pattern = "yyyy-mm-dd")
@data @allargsconstructor @noargsconstructor public class airqualityindex { /** * 记录编号 */ private integer id; /** * 区域编号 */ private integer districtid; /** * 检测时间 */ @datetimeformat(pattern = "yyyy-mm-dd") private date monitortime; /** * pm10值 */ private integer pm10; /** * pm2.5值 */ private integer pm2_5; /** * 监测站 */ private string monitoringstation; /** * 最后修改时间 */ private string lastmodifytime; }
2.3 暂时没有用到mybatis的分页插件,所以自己写分页工具类
@tostring public class pageutils { private integer pagesize; private integer pageno; private integer totalcount; private integer totalpages; private integer startrow; /** * 需要分页的对象 */ private airqualityindex airqualityindex; public pageutils() { } public pageutils(integer pagesize, integer pageno, integer totalcount, airqualityindex airqualityindex) { this.pagesize = pagesize; this.pageno = pageno; this.totalcount = totalcount; this.airqualityindex = airqualityindex; setstartrow(pagesize,pageno); settotalpages(pagesize,totalcount); } public integer getpagesize() { return pagesize; } public void setpagesize(integer pagesize) { this.pagesize = pagesize; } public integer getpageno() { return pageno; } public void setpageno(integer pageno) { this.pageno = pageno; } public integer gettotalcount() { return totalcount; } public void settotalcount(integer totalcount) { this.totalcount = totalcount; } public integer gettotalpages() { return totalpages; } public void settotalpages(integer pagesize,integer totalcount) { this.totalpages = totalcount%pagesize==0?totalcount/pagesize:totalcount/pagesize+1; } public integer getstartrow() { return startrow; } public void setstartrow(integer pagesize,integer pageno) { this.startrow = (pageno-1)*pagesize; } public airqualityindex getairqualityindex() { return airqualityindex; } public void setairqualityindex(airqualityindex airqualityindex) { this.airqualityindex = airqualityindex; } }
2.4 省去mapper的xml,使用注解写sql
注意查询的动态sql上要用<script></script>
包起来
airqualityindexmapper.java
public interface airqualityindexmapper { @delete("delete from air_quality_index where id = #{id}") int deletebyprimarykey(integer id); @insert("insert into air_quality_index values (null,#{districtid}, #{monitortime}, #{pm10}, #{pm2_5}, #{monitoringstation}, #{lastmodifytime})") int insert(airqualityindex airqualityindex); @update("update air_quality_index set districtid = #{districtid},monitortime = #{monitortime},pm10 = #{pm10},pm2_5 = #{pm2_5},monitoringstation = #{monitoringstation},lastmodifytime = #{lastmodifytime} where id = #{id}") int updatebyprimarykey(airqualityindex airqualityindex); @select("<script>" + "select a.*,d.name from air_quality_index a,district d where a.districtid = d.id" + "<if test='airqualityindex != null and airqualityindex.id != null'>" + " and a.id=#{airqualityindex.id}" + "</if>" + "<if test='airqualityindex != null and airqualityindex.districtid != -1 and airqualityindex.districtid != null'>" + " and a.districtid=#{airqualityindex.districtid}" + "</if>" + "<if test='pagesize != null and startrow != null'>" + " limit #{startrow},#{pagesize}" + "</if>" + "</script>") list<map<string,object>> selectbyprimarykey(pageutils pageutils); @select("<script>" + " select count(0) from air_quality_index" + " <where>" + " <if test='districtid != null and districtid != -1'>" + " and districtid=#{districtid}" + " </if>" + " </where>" + "</script>") int gettotalcount(airqualityindex airqualityindex); }
2.5 service中要注意的事情
2.5.1因为分页逻辑属于service要做的事,所以贴上对应serviceimp中的逻辑
airqualityindexserviceimpl.java
中的selectbyprimarykey(pageutils pageutils)
@service @transactional public class airqualityindexserviceimpl implements airqualityindexservice { @autowired private airqualityindexmapper airqualityindexmapper; @override public int deletebyprimarykey(integer id) { return airqualityindexmapper.deletebyprimarykey(id); } @override public int insert(airqualityindex airqualityindex) { //todo获取当前系统时间 date d = new date(); simpledateformat sdf = new simpledateformat("yyyy-mm-dd hh:mm:ss"); //2019-10-23 10:31:37 airqualityindex.setlastmodifytime(sdf.format(d)); if (airqualityindex.getdistrictid() == -1) { return 0; } return airqualityindexmapper.insert(airqualityindex); } @override public int updatebyprimarykey(airqualityindex airqualityindex) { //todo获取当前系统时间 date d = new date(); simpledateformat sdf = new simpledateformat("yyyy-mm-dd hh:mm:ss"); //2019-10-23 10:31:37 //设置时区 sdf.settimezone(timezone.gettimezone("asia/shanghai")); airqualityindex.setlastmodifytime(sdf.format(d)); if (airqualityindex.getdistrictid() == -1) { return 0; } system.out.println(airqualityindex); return airqualityindexmapper.updatebyprimarykey(airqualityindex); } @override public list<map<string, object>> selectbyprimarykey(pageutils pageutils) { if(pageutils.getpageno()==null){ return airqualityindexmapper.selectbyprimarykey(pageutils); } pageutils.settotalcount(airqualityindexmapper.gettotalcount(pageutils.getairqualityindex())); pageutils.setpagesize(5); pageutils.settotalpages(pageutils.getpagesize(), pageutils.gettotalcount()); pageutils.setstartrow(pageutils.getpagesize(), pageutils.getpageno()); return airqualityindexmapper.selectbyprimarykey(pageutils); } }
2.5.2其中,因为要实时保存修改时间,所以也在service中实现
//todo获取当前系统时间 date d = new date(); simpledateformat sdf = new simpledateformat("yyyy-mm-dd hh:mm:ss"); //2019-10-23 10:31:37 //设置时区 sdf.settimezone(timezone.gettimezone("asia/shanghai")); airqualityindex.setlastmodifytime(sdf.format(d)); if (airqualityindex.getdistrictid() == -1) { return 0; } system.out.println(airqualityindex);
2.6最终的controller文件
centercontrollerofair.java
@restcontroller public class centercontrollerofair{ @autowired private airqualityindexservice airqualityindexservice; @autowired private districtservice districtservice; @requestmapping("/deletebyprimarykey.do") public int deletebyprimarykey(integer id) { return airqualityindexservice.deletebyprimarykey(id); } @requestmapping("/insert.do") public int insert(airqualityindex airqualityindex) { if(airqualityindex.getdistrictid()==-1 || airqualityindex.getmonitoringstation()==null || airqualityindex.getmonitortime()==null || airqualityindex.getpm2_5()==null || airqualityindex.getpm10()==null){ return 0; } return airqualityindexservice.insert(airqualityindex); } @requestmapping("/updatebyprimarykey.do") public int updatebyprimarykey(airqualityindex airqualityindex) { if(airqualityindex.getdistrictid()==-1 || airqualityindex.getmonitoringstation()==null || "".equals(airqualityindex.getmonitoringstation().trim()) || airqualityindex.getmonitortime()==null || airqualityindex.getpm2_5()==null || airqualityindex.getpm10()==null){ return 0; } return airqualityindexservice.updatebyprimarykey(airqualityindex); } @requestmapping("/selectbyprimarykey.do") public map<string, object> selectbyprimarykey(pageutils pageutils) { map<string, object> map = new hashmap<>(16); list<map<string, object>> airqualityindexlist = airqualityindexservice.selectbyprimarykey(pageutils); map.put("airqualityindexlist",airqualityindexlist); map.put("pageutils",pageutils); return map; } @requestmapping("/showalldistrict.do") public list<map<string, object>> showalldistrict() { return districtservice.showalldistrict(); } @requestmapping("/info.do") public map<string, object> info(pageutils pageutils) { map<string, object> map = new hashmap<>(16); map.put("airqualityindex",airqualityindexservice.selectbyprimarykey(pageutils).get(0)); map.put("optiondata",districtservice.showalldistrict()); return map; } }
2.7对应的几个页面要注意的:
list.html
<!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <title>title</title> </head> <body> <center> <h1>空气质量监测信息库</h1> <form id="seldistrictform"> 按区域查询 <select name="districtid" id="seldistrictsel" title="区域查询"> <option value="-1">不限</option> </select> <input type="button" name="sel" value="查找"/> <a href="add.html">添加空气质量信息</a> </form> <br/> <table> <tr> <th>序号</th> <th>区域</th> <th>监测时间</th> <th>pm10</th> <th>pm2.5</th> <th>监测站</th> </tr> </table> <p class="pagefoot"></p> </center> <script rel="script" type="text/javascript" src="js/jquery-1.11.2.min.js"></script> <script rel="script" type="text/javascript" src="js/initoptionsel.js"></script> <script rel="script" type="text/javascript" src="js/list.js"></script> </body> </html>
list.js
$(function () { // 初始化分页数据 initpagedata(1); //条件查找 $("[type=button]").click(function () { initpagedata(1); }); }); function initpagedata(pageno) { var table = $("table"); var pagefoot = $("[class=pagefoot]"); var districtid = $("[name=districtid]").val(); $.ajax({ url: "selectbyprimarykey.do", type: "post", datatype: "json", data: {"pageno": pageno, "airqualityindex.districtid": districtid}, async: true, success: function (obj) { var tablestr = ""; console.log(obj.airqualityindexlist.length===0); if (obj.airqualityindexlist.length===0){ $("tr:gt(0)").remove(); tablestr=` <tr style="text-align: center"> <td colspan="6"><strong>抱歉,暂无数据</strong></td> </tr> `; }else{ //在循环的前面清空标题以下的所有行 //获取行>0的那行.移除方法 $("tr:gt(0)").remove(); $.each(obj.airqualityindexlist, function (i) { tablestr += ` <tr> <td>${obj.airqualityindexlist[i].id}</td> <td> <a href="edit.html?id=${obj.airqualityindexlist[i].id}">${obj.airqualityindexlist[i].name}</a></td> <td>${obj.airqualityindexlist[i].monitortime}</td> <td>${obj.airqualityindexlist[i].pm10}</td> <td>${obj.airqualityindexlist[i].pm2_5}</td> <td>${obj.airqualityindexlist[i].monitoringstation}</td> </tr> `; }); } table.attr("width", "600"); table.append(tablestr); $("tr").first().attr("style", "background-color:#add8e6"); $("tr:gt(0):odd").attr("style", "background-color:#90ee90"); //分页 //在分页前,清空原来分页的内容 pagefoot.html(""); var pagestr = ""; if(obj.pageutils.totalcount===0){//如果没有数据,就不显示分页条 return ; } if (obj.pageutils.pageno === 1 && obj.pageutils.pageno !== obj.pageutils.totalpages) {//如果是第一页,并且还有下一页 pagestr = ` <a href="javascript:void(0);" style="text-decoration: none;color: grey;cursor:no-drop;">首 页</a>| <a href="javascript:void(0);" style="text-decoration: none;color: grey;cursor:no-drop;"><< 上一页</a>| <a href="javascript:void(0);" onclick="initpagedata(${obj.pageutils.pageno + 1 });">下一页>></a>| <a href="javascript:void(0);" onclick="initpagedata(${obj.pageutils.totalpages});">尾 页</a> ` }else if (obj.pageutils.pageno === 1 && obj.pageutils.pageno !== obj.pageutils.totalpages) {//如果是第一页,并且没有有下一页 pagestr = ``//nothing to do }else if(obj.pageutils.pageno !== 1 && obj.pageutils.pageno !== obj.pageutils.totalpages){//如果不是第一页,并且还有下一页 pagestr = ` <a href="javascript:void(0);" onclick="initpagedata(1)">首 页</a>| <a href="javascript:void(0);" onclick="initpagedata(${obj.pageutils.pageno - 1 });"><< 上一页</a>| <a href="javascript:void(0);" onclick="initpagedata(${obj.pageutils.pageno + 1 });">下一页>></a>| <a href="javascript:void(0);" onclick="initpagedata(${obj.pageutils.totalpages});">尾 页</a> ` }else if(obj.pageutils.pageno !== 1 && obj.pageutils.pageno === obj.pageutils.totalpages){//如果不是第一页,且是最后一页 pagestr = ` <a href="javascript:void(0);" onclick="initpagedata(1)">首 页</a>| <a href="javascript:void(0);" onclick="initpagedata(${obj.pageutils.pageno - 1 })"><< 上一页</a>| <a href="javascript:void(0);" style="text-decoration: none;color: grey;cursor:no-drop;">下一页>></a>| <a href="javascript:void(0);" style="text-decoration: none;color: grey;cursor:no-drop;">尾 页</a> ` } pagestr += ` 第 ${obj.pageutils.pageno} 页/共 ${obj.pageutils.totalpages} 页(${obj.pageutils.totalcount}条) `; pagefoot.append(pagestr); }, error: function () { alert("initpagedata error"); } }) }
2.7.1其中,分页逻辑可以以后稍作修改直接使用
//分页 //在分页前,清空原来分页的内容 pagefoot.html(""); var pagestr = ""; if(obj.pageutils.totalcount===0){//如果没有数据,就不显示分页条 return ; } if (obj.pageutils.pageno === 1 && obj.pageutils.pageno !== obj.pageutils.totalpages) {//如果是第一页,并且还有下一页 pagestr = ` <a href="javascript:void(0);" style="text-decoration: none;color: grey;cursor:no-drop;">首 页</a>| <a href="javascript:void(0);" style="text-decoration: none;color: grey;cursor:no-drop;"><< 上一页</a>| <a href="javascript:void(0);" onclick="initpagedata(${obj.pageutils.pageno + 1 });">下一页>></a>| <a href="javascript:void(0);" onclick="initpagedata(${obj.pageutils.totalpages});">尾 页</a> ` }else if (obj.pageutils.pageno === 1 && obj.pageutils.pageno !== obj.pageutils.totalpages) {//如果是第一页,并且没有有下一页 pagestr = ``//nothing to do }else if(obj.pageutils.pageno !== 1 && obj.pageutils.pageno !== obj.pageutils.totalpages){//如果不是第一页,并且还有下一页 pagestr = ` <a href="javascript:void(0);" onclick="initpagedata(1)">首 页</a>| <a href="javascript:void(0);" onclick="initpagedata(${obj.pageutils.pageno - 1 });"><< 上一页</a>| <a href="javascript:void(0);" onclick="initpagedata(${obj.pageutils.pageno + 1 });">下一页>></a>| <a href="javascript:void(0);" onclick="initpagedata(${obj.pageutils.totalpages});">尾 页</a> ` }else if(obj.pageutils.pageno !== 1 && obj.pageutils.pageno === obj.pageutils.totalpages){//如果不是第一页,且是最后一页 pagestr = ` <a href="javascript:void(0);" onclick="initpagedata(1)">首 页</a>| <a href="javascript:void(0);" onclick="initpagedata(${obj.pageutils.pageno - 1 })"><< 上一页</a>| <a href="javascript:void(0);" style="text-decoration: none;color: grey;cursor:no-drop;">下一页>></a>| <a href="javascript:void(0);" style="text-decoration: none;color: grey;cursor:no-drop;">尾 页</a> ` } pagestr += ` 第 ${obj.pageutils.pageno} 页/共 ${obj.pageutils.totalpages} 页(${obj.pageutils.totalcount}条) `; pagefoot.append(pagestr);
initoptionsel.js
初始化下拉列表
$(function () { //初始化查询下啦列表 initseloption();} ); function initseloption() { $.ajax({ url: "showalldistrict.do", type: "post", datatype: "json", data: {}, async: true, success: function (obj) { var str = ""; $.each(obj, function (i) { str += ` <option value="${obj[i].id}">${obj[i].name}</option> ` }); //获取下拉列表 $("#seldistrictsel").append(str); }, error: function () { alert("initseloption error"); } }) }
以上,结束