46-Spring Boot 综合实践应用--活动模块实现

Spring Boot 综合应用分析

1.1 业务需求分析及设计

从数据库查询所有活动(Activity)信息,然后呈现在页面上(基于thymeleaf,标签应用参考官网thymeleaf.org)。并可以基于其活动信息进行关操作。对于软件开发人员在需求分析时通常会有这样的过程:

第一:需求调研 (与软件使用人之间的一个沟通,了解其业务)

第二:需求分析 (对需求调研内容的总结和细化)

第三:原型设计 (是对需求分析结果的更好呈现)

第四:需求评审 (签字确认,确认边界,确定业务模块)
简历:参与了需求调研,需求分析,原型设计,需求评审。

1.2 系统架构分析及设计

如何理解架构设计?(所有的架构设计必须以业务为前提,脱离业务谈架构就是耍流氓)

第一:架构模式?(CS/BS)

第二:单体架构,分布式架构,微服务架构?

第三:部署架构?(web服务器一台,数据库服务器一台,…)

第四:系统整体分层架构?(基础设施,操作系统,中间件,应用软件,接入层)

第五:软件应用的分层架构?(表示层,请求处理层,业务层,数据层)

1.3 业务代码分析及设计

第一步骤:原型设计(省略)

第二步骤:数据库及表设计并初始化。(基于source指令去实现 )

第三步骤:应用架构设计(MVC)

第四步骤:业务设计,API设计,时序设计?

第五步骤:POJO对象,数据层对象,业务层对象,控制层对象,表示层。

SpringBoot 综合实践实现

搭建项目初始环境

2.1 搭建项目初始环境

第一步:初始化数据库数据(命令行执行)

打开mysql控制台,然后按如下步骤执行activity.sql文件:

1)登录mysql
mysql -uroot -p1234

2)设置客户端编码
set names utf8

3)执行activity.sql文件
source c:/activity.sql
drop database if exists dbactivity;
create database dbactivity default character set utf8;
use dbactivity;
create table tb_activity(
     id bigint primary key auto_increment,
     title varchar(100) not null,
     category varchar(100) not null,
	 startTime datetime not null,
	 endTime datetime not null,
	 remark text,
	 state tinyint,
     createdTime datetime not null,
	 createdUser varchar(100)
)engine=InnoDB;
insert into tb_activity values (null,'ABS','cuoxiao','2020-02-02 15:00:00','2020-02-03 15:00:00','...',1,now(),'xiaoli');
insert into tb_activity values (null,'VALIDATE','cuoxiao','2020-02-02 15:00:00','2020-02-03 15:00:00','...',1,now(),'xiaoli');
insert into tb_activity values (null,'VALIDATE','cuoxiao','2020-02-02 15:00:00','2020-02-03 15:00:00','...',1,now(),'xiaoli');
......

第二步: 创建SpringBoot maven项目

第三步:添加项目依赖(MySql,Jdbc API,MyBatis,Spring Web,Thymeleaf)

第四步:修改application.properties文件,进行资源配置

1)添加数据源配置(使用内置的HikariCP连接池)
2)添加mybatis配置
3)添加thymeleaf配置
4)添加日志配置

具体配置代码如下:

#spring datasource
spring.datasource.url=jdbc:mysql:///dbactivity?serverTimezone=GMT%2B8&characterEncoding=utf8
spring.datasource.username=root
spring.datasource.password=1234
#spring mybatis
mybatis.mapper-locations=classpath:/mapper/*/*.xml
#spring web
spring.thymeleaf.prefix=classpath:/templates/pages/
#Spring log
logging.level.com.cy=debug

活动模块API设计

活动模块的API对象类型及业务关系设计:

1593921598290

活动模块查询业务实现

服务端实现

第一步:定义pojo对象(com.cy.pj.activity.pojo.Activity)

package com.cy.pj.activity.pojo;
import java.util.Date;
public class Activity {	
	private Long id;
	private String title;
	private String category;
	private Date startTime;
	private Date endTime;
	private String remark;
	private Integer state;
	private Date createdTime;
	private String createdUser;//有登录模块,需要用登录人员
	@Override
	public String toString() {
		return "Activity [id=" + id + ", title=" + title + ", category=" + category + ", startTime=" + startTime
				+ ", endTime=" + endTime + ", remark=" + remark + ", state=" + state + ", createdTime=" + createdTime
				+ ", createdUser=" + createdUser + "]";
	}
	public Long getId() {
		return id;
	}
	public void setId(Long id) {
		this.id = id;
	}
	public String getTitle() {
		return title;
	}
	public void setTitle(String title) {
		this.title = title;
	}
	public String getCategory() {
		return category;
	}
	public void setCategory(String category) {
		this.category = category;
	}
	public Date getStartTime() {
		return startTime;
	}
	public void setStartTime(Date startTime) {
		this.startTime = startTime;
	}
	public Date getEndTime() {
		return endTime;
	}
	public void setEndTime(Date endTime) {
		this.endTime = endTime;
	}
	public String getRemark() {
		return remark;
	}
	public void setRemark(String remark) {
		this.remark = remark;
	}
	public Integer getState() {
		return state;
	}
	public void setState(Integer state) {
		this.state = state;
	}
	public Date getCreatedTime() {
		return createdTime;
	}
	public void setCreatedTime(Date createdTime) {
		this.createdTime = createdTime;
	}
	public String getCreatedUser() {
		return createdUser;
	}
	public void setCreatedUser(String createdUser) {
		this.createdUser = createdUser;
	}

}

第二步:定义ActivityDao接口及方法

package com.cy.pj.activity.dao;

import java.util.List;

import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;

import com.cy.pj.activity.pojo.Activity;

@Mapper
public interface ActivityDao {
	
	@Select("select * from tb_activity")
	List<Activity> findActivitys();
}

第三步:定义ActivityService接口及实现类

package com.cy.pj.activity.service;
import java.util.List;
import com.cy.pj.activity.pojo.Activity;
public interface ActivityService {
	List<Activity> findActivitys();
}

实现类

package com.cy.pj.activity.service.impl;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.cy.pj.activity.dao.ActivityDao;
import com.cy.pj.activity.pojo.Activity;
import com.cy.pj.activity.service.ActivityService;
@Service
public class ActivityServiceImpl implements ActivityService {
	@Autowired
	private ActivityDao activityDao;
	@Override
	public List<Activity> findActivitys() {
		List<Activity> list = activityDao.findActivitys();
		return list;
	}
}

第四步:定义ActivityController对象及url映射

package com.cy.pj.activity.controller;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

import com.cy.pj.activity.pojo.Activity;
import com.cy.pj.activity.service.ActivityService;

@Controller
@RequestMapping("/activity")
public class ActivityController {
	@Autowired
	private ActivityService activityService;	
	@RequestMapping("/doFindActivitys")
	public String doFindActivitys(Model model) {
		List<Activity> list = activityService.findActivitys();
		model.addAttribute("list", list);
		return "activity";
	}
}

客户端实现

第一步:定义activity.html页面,在templates/pages/下定义改页面

第二步:通过Thymeleaf模板引擎将活动数据呈现在页面上。

<!DOCTYPE html>
<html lang="zh-CN">
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <!-- 上述3个meta标签*必须*放在最前面,任何其他内容都*必须*跟随其后! -->
        <title>Bootstrap 101 Template</title>

        <!-- Bootstrap -->
        <link href="../bootstrap/css/bootstrap.min.css" rel="stylesheet">	
    </head>
    <body>
        <div class="container">
            <button type="button" class="btn btn-primary" onclick="javascript:location.href='/activity/activity-add.html'">创建活动 </button>
            <table class="table table-striped">
                <thead>
                    <td><input type="checkbox">全选</td>
                    <th>id</th>
                    <th>标题</th>
                    <th>类型</th>
                    <th>开始时间</th>
                    <th>结束时间</th>
                    <th>备注</th>
                    <th>状态</th>
                    <th>创建时间</th> 
                    <th>操作</th>
                </thead>
                <tbody>
                    <tr th:each="lists,status:${list}">
                        <td><input type="checkbox"></td>
                        <td th:text="${lists.id}" id="id">1</td>
                        <td th:text="${lists.title}"></td>
                        <td th:text="${lists.category}"></td>
                        <td th:text="${#dates.format(lists.startTime, 'yyyy/MM/dd HH:mm')}"></td>
                        <td th:text="${#dates.format(lists.endTime, 'yyyy/MM/dd HH:mm')}"></td>
                        <td th:text="${lists.remark}"></td>
                        <td th:text="有效" th:if="${lists.state==1}"></td>
                        <td th:text="无效" th:if="${lists.state==0}"></td>
                        <td th:text="${#dates.format(lists.createdTime, 'yyyy/MM/dd HH:mm')}"></td>


                    </tr>
                </tbody>
            </table>

        </div>

        <!-- jQuery (Bootstrap 的所有 JavaScript 插件都依赖 jQuery,所以必须放在前边) -->
        <script src="../jquery/jquery.min.js"></script>
        <!-- 加载 Bootstrap 的所有 JavaScript 插件。你也可以根据需要只加载单个插件。 -->
        <script src="../bootstrap/js/bootstrap.min.js"></script>     
    </body>
</html>

活动模块添加业务实现

服务端实现

第一步:在ActivityDao中定义insertObject(Activity activity)方法以及SQL映射

int insertObject(Activity activity);
<?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="com.cy.pj.activity.dao.ActivityDao">
    <insert id="insertObject" >
        insert into tb_activity
        (title,category,startTime,endTime,remark,state,createdTime,createdUser)
        values
        (#{title},#{category},#{startTime},#{endTime},#{remark},1,now(),#{createdUser})		
    </insert>	
</mapper>

第二步:在ActivityService接口及实现类中添加saveActivity(Activity entity)

int insertObject(Activity activity);

实现类

@Override
public int insertObject(Activity activity) {
    int rows = activityDao.insertObject(activity);
    return rows;
}

第三步:在ActivityController对象中添加doSaveActivity方法并定义url映射

@RequestMapping("/activity-add.html")
public String doActivityAddUI() {
    return "activity_add";
}
@RequestMapping("/doSaveObject")
public String doSaveObject(Activity activity) {
    System.out.println(activity);
    activityService.insertObject(activity);
    return "redirect:doFindActivitys";
}

添加活动的页面activity_add.html

<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- 上述3个meta标签*必须*放在最前面,任何其他内容都*必须*跟随其后! -->
<title>活动添加页面</title>
<!-- Bootstrap -->
<link href="../bootstrap/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
	<h2>活动添加页面</h2>
	<div class="container">
		<form action="doSaveObject" method="post">
			<div class="form-group">
				<label for="title">活动标题</label> <input
					type="text" class="form-control" id="title" name="title"
					placeholder="please input title">
			</div>
			<div class="form-group">
				<label for="category">活动类型</label> <input
					type="text" class="form-control" id="category" name="category"
					placeholder="please input title">
			</div>
			<div class="form-group">
				<label for="startTime">开始时间</label> <input
					type="text" class="form-control" id="startTime" name="startTime"
					placeholder="please input title">
			</div>
			<div class="form-group">
				<label for="endTime">结束时间</label> <input
					type="text" class="form-control" id="endTime" name="endTime"
					placeholder="please input title">
			</div>			
			<div class="form-group">
				<label for="remark">备注</label> <textarea row="5" cols="100"
					type="text" class="form-control" id="remark" name="remark"
					placeholder="please input title"></textarea>
			</div>			
			<button type="submit" class="btn btn-default">保存</button>
		</form>

	</div>
	<!-- jQuery (Bootstrap 的所有 JavaScript 插件都依赖 jQuery,所以必须放在前边) -->
	<script src="../jquery/jquery.min.js"></script>
	<!-- 加载 Bootstrap 的所有 JavaScript 插件。你也可以根据需要只加载单个插件。 -->
	<script src="../bootstrap/js/bootstrap.min.js"></script>

</body>
</html>

活动模块删除操作实现

服务端实现

第一步:ActivityDao中定义基于id删除记录的方法 deleteById(Integer id);

@Delete("delete from tb_activity where id =#{id}")
int deleteById(Integer id);

第二步:ActivityService及实现类中定义deleteById(Integer id)方法用于执行记录删除

int deleteById(Integer id);

实现类

@Override
public int deleteById(Integer id) {
    int rows = activityDao.deleteById(id);
    return rows;
}

第三步:ActivityController中定义doDeleteById(Integer id)方法用于处理删除请求

@RequestMapping("/doDeleteById")
public String doDeleteById(Integer id,Model model) {
    activityService.deleteById(id);
    //		List<Activity> list = activityService.findActivitys();
    //		model.addAttribute("list", list);
    return "redirect:doFindActivitys";
}

客户端实现

第一步:Activity.html中删除按钮事件注册以及事件处理函数定义

<button type="button" class="btn btn-danger" id="delete" th:onclick="doDelete([[${lists.id}]])" >删除</button>

第二步:在删除事件处理函数内部向服务端发请求执行删除操作。

<!-- jQuery (Bootstrap 的所有 JavaScript 插件都依赖 jQuery,所以必须放在前边) -->
<script src="../jquery/jquery.min.js"></script>
<!-- 加载 Bootstrap 的所有 JavaScript 插件。你也可以根据需要只加载单个插件。 -->
<script src="../bootstrap/js/bootstrap.min.js"></script>
<script type="text/javascript">
    function doDelete(id){
        //confirm 为window的一个方法,此方法的返回值是一个boolean
        if(!confirm("确认删除吗?"))return;
        {//基于id执行删除操作
          window.location.href="http://localhost:8080/activity/doDeleteById?id="+id;   		 }	
    }
</script>

活动模块修改表单数据的呈现

活动模块修改操作中表单数据的提交

posted on 2020-07-05 15:32  liqiangbk  阅读(391)  评论(0编辑  收藏  举报

导航