JavaFramework_03_SpringBoot综合实战_活动模块

1. SpringBoot加强

1.1 健康检查

1.1.1 添加依赖

<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

1.1.2 健康检查分析

在浏览器中输入如下地址:http://localhost/actuator/health

假如希望查看更多actuator选项,可以在spring boot中配置文件application.properties中添加如下语句:(生产环境不加),此时在浏览器地址栏可以输入http://localhost/actuator/beans 查看所有的spring 容器中的bean信息。

management.endpoints.web.exposure.include=*

说明:当需要以一种更好的结构化方式查看bean相关信息,可以对Google浏览器安装jsonView插件或者使用Postman等工具进行资源请求然后查询bean信息,还可以直接在sts工具的Boot Dashboard中选中项目,查看其属性(show properties)。

1.2 热部署

基于SpringBoot的Web项目,修改了某个类以后,默认不会自动重新部署和加载,需要我们手动重启服务器。假如我们希望项目可以自动部署,可以添加如下依赖,进行热部署实现。

1.2.1 添加依赖

<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-devtools</artifactId>
		<scope>runtime</scope>
</dependency>

说明:当我们修改了src/main/java目录下的java文件或修改了src/main/resources目录下的配置文件时,默认都会重启你的web服务器,但是修改了测试类或html文件不会自动重启和部署。

1.3 Lombok插件

Lombok是一个第三库,可以基于lombok中提供的API,在程序编译时自动织入一些方法。这样做的话可以简化我们对某些方法的编写,例如,省略pojo类中的set方法,get方法,toString等方法的编写。我们写的java程序可以在编译时,通过lombok自动将这些方法添加到.class文件中。

1.3.1 添加依赖

<dependency>
	<groupId>org.projectlombok</groupId>
	<artifactId>lombok</artifactId>
</dependency>

1.3.2 安装lombok

1)找到下载的lombok-xxx.jar依赖所在的位置(例如:C:\Users\Administrator.m2\repository\org\projectlombok\lombok\1.18.16)

image-20201203231118918

2)在当前目录下打开cmd窗口,运行如下命令

java -jar lombok-1.18.16.jar

image-20201203231100969

3)选择sts所在目录

image-20201203231228985

image-20201203231310454

4)点击安装

image-20201203231330761

5)安装成功后效果如下

image-20201203231356420

6)安装成功以后可在STS工具的根目录看到一个lombok.jar文件

image-20201203231519468

同时会在SpringToolSuite4.ini文件的尾部添加lombok.jar文件所在的具体路径,例如 “-javaagent:C:\SoftWare\sts-4.6.1.RELEASE\lombok.jar”

image-20201203231530730

7)重启sts工具

1.3.3 Lombok常用注解

@Setter // 用于为描述的类生成setter方法,不包含final修饰属性。
@Getter // 用于为描述的类生成getter方法。 
@ToString // 用于为描述的类添加toString方法。 
@EqualsAndHashCode // 用于为描述的类,生成hashCode和equals方法。 
@NoArgsConstructor // 用于为描述的类生成无参的构造方法。 
@AllArgsConstructor // 用于为描述的类生成包含类中所有字段的构造方法。 
@Data // 用于为描述的类生成setter/getter、equals、canEqual、hashCode、toString方法,如为final属性,则不会为该属性生成setter方法。 
@Slf4J // 用于为描述的类添加一个日志属性对象,private static final Logger log =LoggerFactory.getLogger(Xxx.class);

2. 需求分析

在页面上呈现全部活动(Activity)信息。

在页面上添加活动信息到数据库。

在页面上修改活动信息,并且在修改界面呈现修改前的信息。

在页面上删除指定活动信息。

3. 综合实践

3.1 搭建项目初始环境

3.1.1 准备数据

创建数据库db_activity,创建表tb_activity,并导入相关数据。

drop database if exists db_activity;
create database db_activity default character set utf8;
use db_activity;
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');
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,'ACCESS','cuoxiao','2020-02-02 15:00:00','2020-02-03 15:00:00','...',1,now(),'xiaoli');
insert into tb_activity values (null,'SD_ALL','cuoxiao','2020-02-02 15:00:00','2020-02-03 15:00:00','...',1,now(),'xiaoli');
insert into tb_activity values (null,'DF','cuoxiao','2020-02-02 15:00:00','2020-02-03 15:00:00','...',1,now(),'xiaoli');
insert into tb_activity values (null,'FG','cuoxiao','2020-02-02 15:00:00','2020-02-03 15:00:00','...',1,now(),'xiaoli');
insert into tb_activity values (null,'ER','cuoxiao','2020-02-02 15:00:00','2020-02-03 15:00:00','...',1,now(),'xiaoli');
insert into tb_activity values (null,'EF','cuoxiao','2020-02-02 15:00:00','2020-02-03 15:00:00','...',1,now(),'xiaoli');
insert into tb_activity values (null,'FFF','cuoxiao','2020-02-02 15:00:00','2020-02-03 15:00:00','...',1,now(),'xiaoli');
insert into tb_activity values (null,'EEE','cuoxiao','2020-02-02 15:00:00','2020-02-03 15:00:00','...',1,now(),'xiaoli');
insert into tb_activity values (null,'WWW','cuoxiao','2020-02-02 15:00:00','2020-02-03 15:00:00','...',1,now(),'xiaoli');
insert into tb_activity values (null,'AAA','cuoxiao','2020-02-02 15:00:00','2020-02-03 15:00:00','...',1,now(),'xiaoli');
insert into tb_activity values (null,'CCC','cuoxiao','2020-02-02 15:00:00','2020-02-03 15:00:00','...',1,now(),'xiaoli');
insert into tb_activity values (null,'XXXX','cuoxiao','2020-02-02 15:00:00','2020-02-03 15:00:00','...',1,now(),'xiaoli');
insert into tb_activity values (null,'WWW','cuoxiao','2020-02-02 15:00:00','2020-02-03 15:00:00','...',1,now(),'xiaoli');
insert into tb_activity values (null,'QQQQ','cuoxiao','2020-02-02 15:00:00','2020-02-03 15:00:00','...',1,now(),'xiaoli');

3.1.2 创建SpringBoot项目

1)打开Spring Starter Project界面,如图所示。

image-20201203211451387

2)添加项目依赖(MySql,Jdbc API,MyBatis,Spring Web,Thymeleaf),如图所示

image-20201203211644421

3)修改application.properties文件(src/main/resources/),进行资源配置,如图所示

3.1)添加数据源配置(使用内置的HikariCP连接池)

# spring datasource
spring.datasource.url=jdbc:mysql:///dbactivity?serverTimezone=GMT%2B8&charac# terEncoding=utf8
spring.datasource.username=root
spring.datasource.password=root

3.2)添加mybatis配置

# spring mybatis
mybatis.mapper-locations=classpath:/mapper/*/*.xml

3.3)添加thymeleaf配置

# spring web
spring.thymeleaf.prefix=classpath:/templates/pages/

3.4)添加日志配置

# Spring log
logging.level.com.cy=debug

3.1.3 启动项目

image-20201203212309121

3.2 活动模块API设计

3.2.1 API对象类型及业务关系设计

image-20201203212500926

3.2.2 服务端实现

分别创建数据层 ActivityDao、业务层 ActivityService、ActivityServiceImpl、控制层 ActivityController、实体类 Activity

image-20201203213921600

3.2.3 客户端实现

image-20201203213943868

3.3 活动模块查询业务实现

3.3.1 业务时序分析

image-20201203214022110

3.3.2 服务端实现

1)定义pojo对象

package com.cy.pj.activity.pojo;

import java.util.Date;

import org.springframework.format.annotation.DateTimeFormat;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;

@Setter
@Getter
@ToString
@NoArgsConstructor  //无参构造
@AllArgsConstructor //所有参数的构造函数
public class Activity {
	private Long id;
	private String title;
	private String category;
	@DateTimeFormat(pattern = "yyyy/MM/dd HH:mm")
	private Date startTime;
	@DateTimeFormat(pattern = "yyyy/MM/dd HH:mm")
	private Date endTime;
	private String remark;
	private int state = 1;
	private Date createdTime;
	private String createdUser;
}

2)定义ActivityDao接口及方法

package com.cy.pj.activity.dao;

import java.util.List;

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

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

@Mapper
public interface ActivityDao {
    /**
	 * 查询所有活动信息
	 * @return
	 */
	@Select("select * from tb_activity order by createdTime desc")
	List<Activity> findActivitys();
}

3)定义ActivityService接口及实现类ActivityServiceImpl

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() {
		return activityDao.findActivitys();
	}

}

第四步:定义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";
	}
}

3.3.3 客户端实现

1)定义activity.html页面(src/main/resources/templates/pages/)

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<div class="container">
	    <h1>The Activity Page</h1>
		<div>
			<table class="table">
				<thead>
					<tr>
						<th>id</th>
						<th>title</th>
						<th>category</th>
						<th>startTime</th>
						<th>endTime</th>
						<th>state</th>
						<th>createdTime</th>
					</tr>
				</thead>
				<tbody>
					<tr th:each="a:${list}">
						<td th:text="${a.id}"></td>
						<td th:text="${a.title}"></td>
						<td th:text="${a.category}"></td>
						<td th:text="${#dates.format(a.startTime, 'yyyy/MM/dd HH:mm')}"></td>
						<td th:text="${#dates.format(a.endTime, 'yyyy/MM/dd HH:mm')}"></td>
						<td th:text="${a.state}"></td>
						<td th:text="${#dates.format(a.createdTime, 'yyyy/MM/dd HH:mm')}"></td>
					</tr>
				</tbody>
			</table>
		</div>
	</div>
</body>
</html>

3.3.4 运行效果

启动程序后,在浏览器输入http://localhost:8080/activity/doFindActivitys,效果如图

image-20201204001207373

3.4 活动模块添加业务实现

3.4.1 业务时序分析

image-20201206213558013

3.4.2 服务端实现

1)在ActivityDao中定义insertActivity(Activity entity)方法以及SQL映射

ActivityDao :

	/**
	 * 添加活动信息
	 * @return
	 */
	int insertActivity(Activity activity);

ActivityMapper.xml(src/main/resources/mapper/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="insertActivity">
      insert into tb_activity
      (title,category,startTime,endTime,state,remark,createdTime,createdUser)
      values
      (#{title},#{category},#{startTime},#{endTime},#{state},#{remark},now(),#{createdUser})
   </insert>
</mapper>

2)在ActivityService接口及实现类中添加saveActivity(Activity entity)

ActivityService:

	int saveActivity(Activity activity);

ActivityServiceImpl:

	@Override
	public int saveActivity(Activity activity) {
		return activityDao.insertActivity(activity);
	}

3)在ActivityController对象中添加doSaveActivity方法并定义url映射

	@RequestMapping("doSaveActivity")
	public String doSaveActivity(Activity activity) {
		activityService.saveActivity(activity);
		return "redirect:doFindActivitys";
	}

3.4.3 客户端实现

1)在页面中activity.html页面中引入两个js(jquery,bootstrap)

1.1)复制bootstrap和jquery到src/main/resources/static/目录下

image-20201206220036648

1.2)在 标签体中引入bootstrap.min.css

	<link rel="stylesheet" href="/bootstrap/css/bootstrap.min.css">

1.3)在 标签体最后引入jquery.min.js、bootstrap.min.js

	<!-- 当在页面中需要使用bootstrap插件时,需要添加如下两个js,但也要注意顺序 -->
	<script type="text/javascript" src="/jquery/jquery.min.js"></script>
	<script type="text/javascript" src="/bootstrap/js/bootstrap.min.js"></script>

2)基于bootcss.com官方模态框案例,在activity.html页面在 标签体中添加模态框。

	<!-- Modal -->
	<div class="modal fade" id="myModal" tabindex="-1" role="dialog"
		aria-labelledby="myModalLabel">
		<div class="modal-dialog" role="document">
			<div class="modal-content">
				<div class="modal-header">
					<button type="button" class="close" data-dismiss="modal"
						aria-label="Close">
						<span aria-hidden="true">&times;</span>
					</button>
					<h4 class="modal-title" id="myModalLabel">Modal title</h4>
				</div>
				<div class="modal-body">
					
				</div>
				<div class="modal-footer">
					<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
					<button type="button" class="btn btn-primary"
						onclick="doSaveActivity()">Save changes</button>
				</div>
			</div>
		</div>
	</div>

3)在

标签体中添加form表单(用户填写用户数据)

					<form id="atyFormId" class="form-horizontal"
						action="doSaveActivity" method="post">
						<input type="hidden" name="id" id="atyId">
						<div class="form-group">
							<label for="titleId" class="col-sm-2 control-label">title</label>
							<div class="col-sm-10">
								<input type="text" class="form-control" name="title"
									id="titleId" placeholder="title">
							</div>
						</div>
						<div class="form-group">
							<label for="categoryId" class="col-sm-2 control-label">category</label>
							<div class="col-sm-10">
								<input type="text" class="form-control" name="category"
									id="categoryId" placeholder="category">
							</div>
						</div>
						<div class="form-group">
							<label for="startTimeId" class="col-sm-2 control-label">startTime</label>
							<div class="col-sm-10">
								<input type="text" class="form-control" name="startTime"
									id="startTimeId" placeholder="yyyy/MM/dd">
							</div>
						</div>
						<div class="form-group">
							<label for="endTimeId" class="col-sm-2 control-label">endTime</label>
							<div class="col-sm-10">
								<input type="text" class="form-control" name="endTime"
									id="endTimeId" placeholder="yyyy/MM/dd">
							</div>
						</div>
						<div class="form-group">
							<label for="remarkId" class="col-sm-2 control-label">remark</label>
							<div class="col-sm-10">
								<textarea class="form-control" id="remarkId" name="remark"
									placeholder="remark"></textarea>
							</div>
						</div>
					</form>

在 标签体最后添加如下 标签体,提交form表单,关闭模态框

	<script>
		function doSaveActivity() {
			// alert("save activity");
			//对表单内容进行校验
			//执行表单提交操作(基于js方式提交表单)
			$("#atyFormId").submit();
			//关闭模态框
			$('#myModal').modal('hide');
		}
	</script>

4)在activity.html页面

标签体下方添加添加按钮,点击按钮时呈现模态框

		<div>
			<button type="button" class="btn btn-primary" data-toggle="modal"
				onclick="doShowAddDialog()">添加活动信息</button>
		</div>

在 标签体中添加如下代码

		// 呈现添加模态框
		function doShowAddDialog() {
			$("#atyId").val('');
			$("#titleId").val('');
			$("#categoryId").val('');
			$("#startTimeId").val('');
			$("#endTimeId").val('');
			$("#remarkId").text('');
			// 显示模态框
			$('#myModal').modal('show');
		}

5)在表单中输入数据, 然后点击保存按钮,将数据传递到服务端。

image-20201207000632569

image-20201207000650974

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

3.5.1 业务时序分析

image-20201207215411575

3.5.2 服务端实现

第一步:在ActivityDao中定义findById方法,基于活动id查询活动信息

	/**
	 * 基于id查询指定活动信息
	 * @param id
	 * @return
	 */
	@Select("select * from tb_activity where id=#{id}")
	Activity findById(Integer id);

第二步:在ActivityService及实现类中添加findById方法,基于活动id查询活动信息。

ActivityService:

	Activity findById(Integer id);

ActivityServiceImpl:

	@Override
	public Activity findById(Integer id) {
		return activityDao.findById(id);
	}

第三步:在ActivityController中定义doFindById方法,基于id获取活动信息将其存储在作用域对象中,并定义url映射。

    @RequestMapping("doFindById")
    public String doFindById(Integer id,Model model) {
        Activity aty=activityService.findById(id);
        model.addAttribute("aty", aty);
        return "forward:doFindActivitys";
    }

3.5.3 客户端实现

1)activity.html中 标签体最后注册修改按钮事件并定义事件处理函数

<td>
    <button class="btn btn-warning btn-sm" th:onclick="doLoadById([[${a.id}]])">更新</button>
</td>

2)在 标签体中修改按钮事件处理函数中向服务端发起请求基于id获取活动信息。

		function doLoadById(id){
			location.href="doFindById?id="+id;
		}

3)在activity.html页面中给 标签体添加 “th:inline” 属性,定义处理函数获取基于id查询到的活动信息

	<!-- 假如要在js中获取thymeaf表达式中的数据script标签内部需要th:inline="javascript" -->
	<script th:inline="javascript">
	     $(function(){//页面加载完成以后执行
	    	 var aty=[[${aty}]];//在js中获取thyemeaf表达式中的内容
	         //console.log("aty",aty); 在浏览器输出相关内容
	         if(aty){
	        	 doInitEditFormData(aty)
	         }
	     });
	    
		function doInitEditFormData(aty){
			$("#atyId").val(aty.id);
			$("#titleId").val(aty.title);
			$("#categoryId").val(aty.category);
			$("#startTimeId").val(aty.startTime);
			$("#endTimeId").val(aty.endTime);
			$("#remarkId").text(aty.remark);
		  	//显示模态框
		  	$('#myModal').modal('show'); 
		}
	</script>

4)将要修改的记录信息呈现在表单中并以模态框的信息进行呈现。

image-20201207221726828

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

3.6.1 业务时序分析

image-20201207232542804

3.6.2 服务端实现

1)ActivityDao中定义基于id更新活动信息的方法 updateObject(Activity entity)

	/**
	 * 基于id更新指定活动信息
	 * @param entity
	 * @return
	 */
	int updateActivity(Activity entity);

ActivityMapper.xml(src/main/resources/mapper/activity/)

	<update id="updateActivity">
		update tb_activity
		set title=#{title},
		category=#{category},
		startTime=#{startTime},
		endTime=#{endTime},
		remark=#{remark}
		where id=#{id}
	</update>

2)修改ActivityServiceImpl类中saveObject方法,基于的值进行添加或修改操作

	@Override
	public int saveActivity(Activity entity) {
		if(entity.getId()==null) {
		  return activityDao.insertActivity(entity);
		}else {
		  return activityDao.updateActivity(entity);
		}
	}

3.7 活动模块删除操作实现

3.7.1 业务时序分析

image-20201207233101006

3.7.2 服务端实现

1)ActivityDao中定义基于id删除记录的方法 deleteById(Integer id);

	/**
	 * 基于id删除活动信息
	 * @param id
	 * @return
	 */
	@Delete("delete from tb_activity where id=#{id}")
	int deleteById(Integer id);

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

ActivityService:

	int deleteById(Integer id);

ActivityServiceImpl:

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

3)ActivityController中定义doDeleteById(Integer id)方法用于处理删除请求

	@RequestMapping("doDeleteById")
	public String doDeleteById(Integer id) {
		activityService.deleteById(id);
		return "forward:doFindActivitys";
	}

3.7.3 客户端实现

1)Activity.html 标签中注册删除按钮事件以及事件处理函数定义

<button class="btn btn-danger btn-sm" th:onclick="doDeleteById([[${a.id}]])">删除</button>

2)在 标签中的删除事件处理函数内部向服务端发请求执行删除操作

		function doDeleteById(id) {
		    if (!confirm("确定删除吗")) return;
		    location.href = "doDeleteById?id=" + id;
		}

3)点击删除按钮删除指定活动信息

image-20201207233814475

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值