• 空气质量管理系统+SSM(Spring+SpringMVC+Mybatis)+前后端分离总结


    作者:故事我忘了
    个人微信公众号:程序猿的月光宝盒

    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&amp;characterEncoding=UTF-8"/>
            <property name="username" value="root"/>
            <property name="password" value="xxx"/>
        </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="查找"/>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
            <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;">首&nbsp;页</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});">尾&nbsp;页</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)">首&nbsp;页</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});">尾&nbsp;页</a>
                    `
                }else if(obj.pageUtils.pageNo !== 1 && obj.pageUtils.pageNo === obj.pageUtils.totalPages){//如果不是第一页,且是最后一页
                    pageStr = `
                    <a href="javascript:void(0);" onclick="initPageData(1)">首&nbsp;页</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;">尾&nbsp;页</a>
                    `
                }
                pageStr += `
                第&nbsp;
                    ${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;">首&nbsp;页</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});">尾&nbsp;页</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)">首&nbsp;页</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});">尾&nbsp;页</a>
                    `
                }else if(obj.pageUtils.pageNo !== 1 && obj.pageUtils.pageNo === obj.pageUtils.totalPages){//如果不是第一页,且是最后一页
                    pageStr = `
                    <a href="javascript:void(0);" onclick="initPageData(1)">首&nbsp;页</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;">尾&nbsp;页</a>
                    `
                }
                pageStr += `
                第&nbsp;
                    ${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");
            }
        })
    }
    

    以上,结束

    点我进入对应的项目源码下载

  • 相关阅读:
    c++——if语句
    Hausdorff距离--模板匹配
    牛人(周志华)推荐的人工智能网站
    用VC++实现图像检索技术(转)
    经典的机器学习方面源代码库(非常全,数据挖掘,计算机视觉,模式识别,信息检索相关领域都适用的了)
    2013计算机视觉代码合集四
    2013计算机视觉代码合集三
    2013计算机视觉代码合集二
    2013计算机视觉代码合集一
    [IC]Lithograph(2)光刻技术的分辨率与分辨率增强技术
  • 原文地址:https://www.cnblogs.com/jsccc520/p/11976748.html
Copyright © 2020-2023  润新知