小组成员分工
lzh:主要完成系统的需求分析,系统完成后整体的测试。
jl:主要完成数据库的数据修改和导入,sql语句,数据库的测试,持久层的xml文件。
zxc:主要完成酒店管理模块的代码实现与测试,定义持久层接口。
st:主要完成景点管理模块的代码实现与测试,控制层的设计。
cmx:主要完成用户登录模块的代码实现与测试,实体层的设计。
zjt:主要完成订单管理模块和用户收藏模块的代码实现与测试,过滤器以及常量的设置。
项目介绍
主要功能
本系统主要依据MVC(Model-View-Controller)架构,分别包括用户管理模块,订单管理模块,景点管理模块,酒店管理模块以及用户收藏管理模块。
- 用户管理模块:用户登录,用户信息修改(前台显示有误但后台数据库无误)。
- 订单管理模块:新建订单
- 景点管理模块:分页查询全部景点,查询一个景点的详细信息
- 酒店管理模块:分页查询全部酒店,查询一个酒店的详细信息
- 用户收藏模块:添加收藏,删除收藏
核心代码
UserController部分
@Controller
@RequestMapping("user")
public class UserController {
@Autowired
UserService userService;
@GetMapping("getUser")
String getUser(int id){
User user = userService.queryUser(id);
System.out.println(user);
return "front/user";
}
@PostMapping("/login")
String getUser(User user, HttpServletRequest httpServletRequest,
HttpSession httpSession){
User u = userService.getUserByUsernameAndPassword(user);
System.out.println(u);
if (u != null){
System.out.println("登录成功!");
httpSession.setAttribute("user",u);
String path = "redirect:/attraction/list";
return path;
}else {
System.out.println("登录失败");
return "front/login";
}
}
@GetMapping("/person_center")
String personCenter(){
return "front/person_center";
}
@PostMapping("/edit")
String updateUser(User user,HttpSession httpSession){
userService.updateUserInfo(user);
System.out.println(user);
httpSession.setAttribute("user",user);
return "front/person_center";
}
}
OrderController部分
@Controller
@RequestMapping("/order")
public class OrderController {
@Autowired
private OrderService orderService;
@Autowired
private AttractionService attractionService;
@Transactional
@PostMapping("buy")
public String buy(Order order, @RequestParam(name = "from", required = true) String from, HttpSession session) {
System.out.println(order);
//type:订单类型:1:景点订单;2:酒店订单;3:攻略订单
if (order.getType() == Type.attraction) {
Attraction attraction = attractionService.getAttractionById(order.getOid());
if (orderService.saveOrder(order)) {
session.setAttribute("message", "购买成功");
} else {
session.setAttribute("message", "购买失败,你今天已经购买过景点门票了哦!");
}
}
return "redirect:" + from;
}
}
AttractionController部分
@Controller
@RequestMapping("/attraction")
public class AttractionController {
@Autowired
private AttractionService attractionService;
@Autowired
private CollectService collectService;
@Autowired
private OrderService orderService;
@RequestMapping("/list")
public String getAttractions(HttpServletRequest request, @RequestParam(required = true, name = "page", defaultValue = "1") Integer page) {
//page:表示查询第几页;8:表示每页显示的数量
PageHelper.startPage(page, 8);
List<Attraction> attractions = attractionService.getAttractions();
//将attractions封装至PageInfo;5表示分页导航的最大页码数。
PageInfo<Attraction> pageInfo = new PageInfo<Attraction>(attractions, 5);
request.setAttribute("pageInfo", pageInfo);
//------------------以下为验证打印信息------------------
System.out.println("当前页: " + pageInfo.getPageNum());
System.out.println("总页码: " + pageInfo.getPages());
System.out.println("总条数: " + pageInfo.getTotal());
System.out.println("每页显示的条数: " + pageInfo.getPageSize());
List<Attraction> list = pageInfo.getList();
for(int i=0;i<list.size();i++){
Attraction attraction = list.get(i);
System.out.println(attraction);
}
//------------------以上为验证打印信息------------------
return "front/attraction";
}
@RequestMapping("/{id}")
public String getAttractionById(@PathVariable(name = "id") int id, HttpServletRequest request) {
// 获取景点
Attraction attraction = attractionService.getAttractionById(id);
request.setAttribute("attraction", attraction);
// 获取用户
User user = (User) request.getSession().getAttribute("user");
if (user != null) {
int userID = user.getId();
// 判断该用户是否已收藏此景点
boolean isCollect = collectService.isCollect(userID, Type.attraction, id);
request.setAttribute("isCollect", isCollect);
// 判断该用户是否已购买此景点
Order order = orderService.getOrderByTypeAndIDs(userID, Type.attraction, id);
if(order!=null){
// 比较购买时间(年月日)与今天(年月日)是否相等
String pattern = "yyyy-MM-dd";
SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
Date createTimeDate = order.getOrderTime();
String createTimeString = simpleDateFormat.format(createTimeDate);
Date todayTimeDate = new Date();
String todayTimeString = simpleDateFormat.format(todayTimeDate);
if (createTimeString.equals(todayTimeString)) {
request.setAttribute("isOrder", true);
} else {
request.setAttribute("isOrder", false);
}
}else{
request.setAttribute("isOrder", false);
}
} else {
request.setAttribute("isOrder", false);
}
return "front/attraction_detail";
}
}
HotelController部分
@Controller
@RequestMapping("hotel")
public class HotelController {
@Autowired
HotelService hotelService;
@Autowired
CollectService collectService;
@Autowired
OrderService orderService;
@RequestMapping("/list")
public String getHotels(HttpServletRequest request, @RequestParam(required = true, name = "page", defaultValue = "1") Integer page){
//page:表示查询第几页;8:表示每页显示的数量
PageHelper.startPage(page, 8);
List<Hotel> hotels = hotelService.getHotels();
//将attractions封装至PageInfo;5表示分页导航的最大页码数。
PageInfo<Hotel> pageInfo = new PageInfo<Hotel>(hotels, 5);
request.setAttribute("pageInfo", pageInfo);
//------------------以下为验证打印信息------------------
System.out.println("当前页: " + pageInfo.getPageNum());
System.out.println("总页码: " + pageInfo.getPages());
System.out.println("总条数: " + pageInfo.getTotal());
System.out.println("每页显示的条数: " + pageInfo.getPageSize());
List<Hotel> list = pageInfo.getList();
for(int i=0;i<list.size();i++){
Hotel hotel = list.get(i);
System.out.println(hotel);
}
//------------------以上为验证打印信息------------------
return "front/hotel";
}
@RequestMapping("/{id}")
public String getHotelById(@PathVariable(name = "id") int id, HttpServletRequest request) {
// 获取景点
Hotel hotel = hotelService.getHotelById(id);
request.setAttribute("hotel", hotel);
// 获取用户
User user = (User) request.getSession().getAttribute("user");
if (user != null) {
int userID = user.getId();
// 判断该用户是否已收藏此景点
boolean isCollect = collectService.isCollect(userID, Type.attraction, id);
request.setAttribute("isCollect", isCollect);
// 判断该用户是否已购买此景点
Order order = orderService.getOrderByTypeAndIDs(userID, Type.attraction, id);
if(order!=null){
// 比较购买时间(年月日)与今天(年月日)是否相等
String pattern = "yyyy-MM-dd";
SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
Date createTimeDate = order.getOrderTime();
String createTimeString = simpleDateFormat.format(createTimeDate);
Date todayTimeDate = new Date();
String todayTimeString = simpleDateFormat.format(todayTimeDate);
if (createTimeString.equals(todayTimeString)) {
request.setAttribute("isOrder", true);
} else {
request.setAttribute("isOrder", false);
}
}else{
request.setAttribute("isOrder", false);
}
} else {
request.setAttribute("isOrder", false);
}
return "front/hotel_detail";
}
}
CollectController部分
@Controller
@RequestMapping("collect")
public class CollectController {
@Autowired
CollectService collectService;
@PostMapping("/on")
public String on(Collect collect, @RequestParam(name = "from", required = true) String from, HttpSession session) {
System.out.println("------------");
boolean on = collectService.saveCollect(collect);
if (on) {
session.setAttribute("message", "收藏成功");
} else {
session.setAttribute("message", "收藏失败");
}
return "redirect:" + from;
}
@PostMapping("/off")
public String off(Collect collect, @RequestParam(name = "from", required = true) String from, HttpSession session) {
boolean off = collectService.deleteCollect(collect);
if (off) {
session.setAttribute("message", "取消收藏成功");
} else {
session.setAttribute("message", "取消收藏失败");
}
return "redirect:" + from;
}
}
代码截图
运行效果截图
用户登录
用户输入用户名:admin 密码:admin后点击登录按钮进入景点页面,如果用户名或密码错误就会重新返回登录页面。
景点管理
- 分页查询景点
- 景点详细信息查询
酒店管理
- 分页查询酒店
- 查询酒店详细信息
订单管理
收藏管理
-
添加收藏
-
取消收藏
学习总结
因为本组的成员均为计科专业,所以对SSM的框架都有着基本的了解以及在Eclipse上相关项目的学习经验。通过了解和总结本次实训中各小组成员的学习情况,对本次的实训中所学的知识进行了总结以及之前所学的知识进行了巩固学习,对部分实训过程中所提到的相关专业知识进行了解。
知识汇总
该部分总结了各个小组成员在课上老师所提到的相关知识以及部分提到的名词回去搜索之后了解到的新的知识,或是一部分对于课上的自己不了解或是不熟悉的知识。
IDEA
IDEA为现在社会上主流的JAVA编译软件,对比Eclipse需要收费,idea的使用下来更加智能,也支持更多项目等,能创建更多更丰富的项目,比如在本次项目中创建的SSM的Javaweb项目,还有JavaFX等GUI项目,也可以用spring initializer来快速的创建SpringBoot项目。
环境配置
学习了Maven的本地配置,Java与数据库的配置在之前的学习中已经配置完成,在进行pom文件的配置的时候需要镜像来加速。pom文件是Maven项目运行时必不可少的一部分,通过pom文件可以为Maven项目提供依赖,pom文件如果没有搭建好依赖的话需要对项目进行重建。同时在SSM中的各项目要通过右键给项目指定多个不同的文件夹。
JavaFX
在上课中提到了JavaFX和GUI,JavaFX可以用于GUI的开发,GUI是图形用户界面,GUI在计算机专业中有着广泛的应用,使人与机器的交互更加便利,如果进行JavaFX进行学习将可以提高自己的UI的制作能力,有利于自己学习Java的页面的开发,掌握更多的技术可以为自己提供更多的机会。
mysql 中 utf8和utf8mb4
在Navicat中创建数据库时选择字符集时出现了utf8和utf8mb4,utf8mb4中的mb4为most bytes 4,可以兼容四个字节,而utf8最多只能支持三个字节,在一般情况下选择utf8mb4,有着更好的兼容性。
war和war exploded
在进行服务器的配置的时候,可以看到下图的两种部署方式,通过课后的学习知道两种部署方式的差别。
- war包是将整个项目进行打包之后部署到服务器,整个项目都被打包成了war包的形式。
- war exploded如字面意思上是将项目分解后放上去,也就是将整个项目的文件夹都直接部署到服务器上。
ORM
ORM是Object Relational Mapping 的缩写,译为“对象关系映射”,它解决了对象和关系型数据库之间的数据交互问题。ORM在SSM中体现为,在SSM的entity的文件夹中创建的类的属性要和数据库中的数据表的各个字段对应,然后在resource文件中的mapper要和数据库中的以及entity中的字段名一一对应,这样才可以在service调用mapper的功能时可以正常使用,如果字段不统一会使整个项目的开发不方便,更加复杂,所以通过ORM的思想进行软件的开发可以有效地增加开发效率。
resouce文件中的命名
在resource中创建文件夹要使用/而不能直接使用,虽然两种的显示效果一样但是在实际应用中使用.来进行创建的话会出错,使用/能够成功的创建多级目录,虽然在项目中的显示效果一样,但是查看路径时会发现两种方法创建出来的路径并不一样。例如如图路径:
创建文件夹时使用的其实是在使用
config常量
通过在项目中java文件夹中创建一个config文件,在里面可以存储常量,在其他类中可以直接进行调用来节省高频率出现的语句的写的时间,使得代码整体更加简洁,在config中定义的常量应该使用大写。
@data
在项目中使用@data项目可以节省在写实体类时的时间,可以有效地提高代码的简洁性。通过@data注释的引入可以自动完成基本的例如get和set,tostring以及构造器等方法。需要在pom中引入lombok。
get和post
get和post通过表单的method可以进行相关设置,在controller的后台也可以设置相关的getmapping和postmapping进行接受,get和post的传输有以下的差距:
- get的传输所包含的值会直接显示在路径中,会直接显示在url之后,安全性较差,传输的格式是形如
?key=value&key2=value
的形式,而在post传输的信息会在form中,在后台所以安全性较高,传输的是键值对,可以在响应头中查看。 - get传输的信息的长度有限,post可以传输更多的长度,而且post支持传输其他形式的数据,比如multipart-file类型的文件传输必须使用post进行传输,不能使用get。
@autowired 构造注入
如果直接进行注解语句@autowired进行自动注入的话,不会报错但是在autowired下面会出现波浪线的提醒。
@Autowired
private UserService userService;
通过将鼠标移动到autowired上查看信息可以看到上面提示不建议使用字段注入,为了解决该问题可以进行字段注入。将以上的代码换为以下的代码:
private UserService userService;
@Autowired
UserController(UserService userService){
this.userService=userService;
}`
请求重定向,请求转发的区别;
- 请求转发是浏览器将消息发给服务器,服务器直接定向到目标服务器的地址,进行访问,收到响应后返回给浏览器目标服务器的反应。而请求重定向是浏览器将访问消息发给服务器,服务器返回给浏览器一个访问的新的地址,浏览器再访问新的地址,从目的地直接获得响应。
- 请求转发因为是收到来自服务器的相应,所以地址不发生改变,请求重定向因为收到目标的相应,所以地址会改变。两种不同方式访问获得的域名不相同,url地址不同。
- 请求转发因为只需要发一次请求,所以request和response在访问的过程中不会变,但是请求重定向因为两次要发送不同的请求,所以两次中的数据会不同。
- 请求转发在controller中通过
request.getRequestDispatcher("user.html").forward(request, response);
来实现,也可以通过在jsp页面中使用<jsp:forward page="WEB-INF/jsp/front/login.jsp"></jsp:forward>
来实现,而请求重定向需要使用response.sendRedirect("user.html");
来实现,或者return一个redirect:/front/user
来实现。
pojo,entity,vo区别
在本项目中使用的是entity来存放实体类,但是在之前的项目的开发有的时候使用的是pojo文件夹,老师提到pojo和entity虽然看起来作用相同但是pojo和entity实际上存在着一定的差别,以及提到了vo,对于这个问题进行了网上的学习和总结。
- entity(实体):其中的属性必须要和数据表中的字段一一对应,数据表到对应实体类的映射。
- pojo(简单Java对象):原词为Plain Old Java Object,没有要求要和数据表中的对象一一对应,没有规则,可以转换为po(持久化对象),vo,dto(数据传输对象)。
- vo(值对象/表现层对象):原词为View Object,对应页面中显示的对象。
@Repository
在代码的编写中,使不使用@Repository实际使用中没有差别,功能的使用上一样,但是通过注解来进行标识可以更好的作出区分。通过注解的方法可以更好的区分功能,@Repository作用于持久层。
postman
通过使用Postman这个软件可以在自己编写软件时更好的看到软件中的post请求,也可以通过postman来发送post请求,使用postman可以更加直观的看到post的效果,在代码的测试中使用postman可以帮助我们更高效的和直观的进行post表单的测试。
mybatisplus
mybatisplus是一款可以简化整个开发流程的软件,可以大大的提升开发效率,在Mybatis的基础上进行了开发,可以为软件的开发做一个锦上添花的功能,在熟练掌握mybatis以及相关框架后可以为后台的开发提高效率。
springcloud
分布式架构其中的一种就是微服务,可以通过使用springcloud来进行微服务项目的搭建。微服务架构是一种由多个微型服务组成的一种架构方式,服务之间互相互相协调、互相配合,其中spring cloud基于spring boot提供了一整套服务的解决方案,简化了分布式系统基础设施的开发。因为微服务在目前IT行业有着较好的前景,所以如果能够学好掌握springcloud的运用对于自己在IT行业的就业提供优势。
pagehelper
pagehelper需要先在pom文件中引入pagehelper的依赖,是一种分页插件,通过pagehelper的使用可以自动分页来使得整个页面的效果更加美观。相关代码如下:
@RequestMapping("/list")
public String getAttractions(HttpServletRequest request, @RequestParam(required = true, name = "page", defaultValue = "1") Integer page) {
//page:表示查询第几页;8:表示每页显示的数量
PageHelper.startPage(page, 8);
List<Attraction> attractions = attractionService.getAttractions();
//将attractions封装至PageInfo;5表示分页导航的最大页码数。
PageInfo<Attraction> pageInfo = new PageInfo<>(attractions, 5);
request.setAttribute("pageInfo", pageInfo);
//------------------以下为验证打印信息------------------
System.out.println("当前页: " + pageInfo.getPageNum());
System.out.println("总页码: " + pageInfo.getPages());
System.out.println("总条数: " + pageInfo.getTotal());
System.out.println("每页显示的条数: " + pageInfo.getPageSize());
List<Attraction> list = pageInfo.getList();
for(int i=0;i<list.size();i++){
Attraction attraction = list.get(i);
System.out.println(attraction);
}
//------------------以上为验证打印信息------------------
return "front/attraction";
}
其中核心的PageHelper.startPage(page, 8);
,通过这句代码设置了PageHelper查询的页数和每页显示的数量,然后进行查询列表的结果进行信息的获取PageInfo<Attraction> pageInfo = new PageInfo<>(attractions, 5);
,第一个值为传入列表的参数,第二个值为分页导航的最大页码数,虽然也可以在SQL的查询语句中直接使用limit,但是使用pagehelper的话可以直接获得页码,页数,当前页等信息,直接获得更加详细的信息。
学习心得
通过本次的实训,对于之前所学的SSM进行了一遍复习,也学到了在IDEA环境中进行相关环境的配置以及SSM框架的代码编写,同时也学习了不少的新概念,了解了自己的知识仍然欠缺需要不断地进行学习和巩固,计算机行业的工作需要知识以及良好的态度。在往后的计算机相关的学习和工作中需要学会勤用csdn和搜索引擎来进行搜索来解决各种问题。