一:酒店,房间项目(Hotel,Room)
1.pom文件
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>an.cxy</groupId>
<artifactId>Spring-Boot-Data-Work</artifactId>
<version>1.0-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.9.RELEASE</version>
</parent>
<dependencies>
<!-- Spring Boot 缓存支持启动器 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<!-- Ehcache 坐标 -->
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.1.10.RELEASE</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
2.配置文件:application.properties,ehcache.xml
#项目端口配置
server.port=8080
server.address=0.0.0.0
#Mysql数据源配置
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/test?characterEncoding=UTF8&useSSL=false
spring.datasource.username=root
spring.datasource.password=root
#JPA相关配置
#项目启动生成数据库
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
#josn数据格式
spring.jackson.serialization.indent-output=true
spring.redis.host=192.168.92.136
spring.redis.port=6379
spring.cache.type=redis
#spring.mvc.view.prefix=/WEB-INF/jsp/
#spring.mvc.view.suffix=.jsp
spring.cache.ehcache.config=classpath:ehcache.xml
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../config/ehcache.xsd">
<diskStore path="java.io.tmpdir"/>
<!--defaultCache:echcache的默认缓存策略 -->
<defaultCache
maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
maxElementsOnDisk="10000000"
diskExpiryThreadIntervalSeconds="120"
memoryStoreEvictionPolicy="LRU">
<persistence strategy="localTempSwap"/>
</defaultCache>
<!-- 自定义缓存策略 -->
<cache name="users"
maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
maxElementsOnDisk="10000000"
diskExpiryThreadIntervalSeconds="120"
memoryStoreEvictionPolicy="LRU">
<persistence strategy="localTempSwap"/>
</cache>
</ehcache>
3.实体类:正向工程,自动生产SQL表
package an.cxy.pojo;
import javax.persistence.*;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
@Entity
@Table(name = "t_room")
public class Room implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "rid")
private Integer rid;
@Column(name = "type")
private Integer type;
@Column(name = "price")
@NotNull//非空校验
private Integer price;
@Column(name = "info")
private String info;
@ManyToOne(cascade = CascadeType.PERSIST)
@JoinColumn(name = "hotelid")
private Hotel hotel;
public Hotel getHotel() {
return hotel;
}
public void setHotel(Hotel hotel) {
this.hotel = hotel;
}
public Integer getRid() {
return rid;
}
public void setRid(Integer rid) {
this.rid = rid;
}
public Integer getType() {
return type;
}
public void setType(Integer type) {
this.type = type;
}
public Integer getPrice() {
return price;
}
public void setPrice(Integer price) {
this.price = price;
}
public String getInfo() {
return info;
}
public void setInfo(String info) {
this.info = info;
}
@Override
public String toString() {
return "Room{" +
"rid=" + rid +
", type=" + type +
", price=" + price +
", info='" + info + '\'' +
'}';
}
public Room(Integer type, @NotBlank Integer price, String info, Integer hotelid) {
this.type = type;
this.price = price;
this.info = info;
}
public Room(){}
}
package an.cxy.pojo;
import javax.persistence.*;
import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;
@Entity
@Table(name = "t_hotel")
public class Hotel implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "hotelid")
private Integer hotelid;
@Column(name = "name")
private String name;
@Column(name = "address")
private String address;
@Column(name = "mobile")
private String mobile;
@OneToMany(mappedBy = "hotel",cascade = CascadeType.PERSIST)
private Set<Room> room=new HashSet<>();
public Set<Room> getRoom() {
return room;
}
public void setRoom(Set<Room> room) {
this.room = room;
}
public Integer getHotelid() {
return hotelid;
}
public void setHotelid(Integer hotelid) {
this.hotelid = hotelid;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getMobile() {
return mobile;
}
public void setMobile(String mobile) {
this.mobile = mobile;
}
@Override
public String toString() {
return "Hotel{" +
"hotelid=" + hotelid +
", name='" + name + '\'' +
", address='" + address + '\'' +
", mobile='" + mobile + '\'' +
'}';
}
public Hotel(String name, String address, String mobile) {
this.name = name;
this.address = address;
this.mobile = mobile;
}
public Hotel(){}
}
4.dao层:hoteldao,roomdao
package an.cxy.dao;
import an.cxy.pojo.Hotel;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
public interface HotelDao extends JpaRepository<Hotel,Integer>, JpaSpecificationExecutor<Hotel> {
}
package an.cxy.dao;
import an.cxy.pojo.Room;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Query;
import java.util.List;
public interface RoomDao extends JpaRepository<Room,Integer> , JpaSpecificationExecutor<Room> {
@Query(value = "select tr.rid,tr.info,tr.price,tr.type,th.address,th.mobile,th.name,th.hotelid from t_room tr,t_hotel th where tr.hotelid=th.hotelid and th.name like ?",nativeQuery = true)
List<Room> findByname(String pname);
}
5.service层:hotelService,roomService
package an.cxy.service;
import an.cxy.pojo.Hotel;
import java.util.List;
public interface HotelService {
List<Hotel> findHotel();
}
package an.cxy.service;
import an.cxy.pojo.Room;
import java.util.List;
public interface RoomService {
void addRoom(Room room);
List<Room> findAllRoom();
List<Room> findByName(String name);
void delete(Integer rid);
}
6.service实现类:
package an.cxy.service.impl;
import an.cxy.dao.HotelDao;
import an.cxy.pojo.Hotel;
import an.cxy.service.HotelService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class HotelServiceImpl implements HotelService {
@Autowired
HotelDao hotelDao;
@Override
public List<Hotel> findHotel() {
return hotelDao.findAll();
}
}
package an.cxy.service.impl;
import an.cxy.dao.RoomDao;
import an.cxy.pojo.Room;
import an.cxy.service.RoomService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class RoomServiceImpl implements RoomService {
@Autowired
RoomDao roomDao;
@Autowired
RedisTemplate<String,Object> template;
@Override
@CacheEvict(value = "users",allEntries = true)
public void addRoom(Room room) {
this.roomDao.save(room);
}
@Override
@Cacheable(value = "users")
public List<Room> findAllRoom() {
return roomDao.findAll();
}
@Override
@Cacheable(value = "users")
public List<Room> findByName(String name) {
return roomDao.findByname(name);
}
@Override
@CacheEvict(value = "users",allEntries = true)
public void delete(Integer rid) {
roomDao.deleteById(rid);
}
}
7.Controller层:hotelController,roomController
package an.cxy.controller;
import an.cxy.pojo.Hotel;
import an.cxy.pojo.Room;
import an.cxy.service.HotelService;
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 java.util.List;
@Controller
public class HotelController {
@Autowired
HotelService hotelService;
@RequestMapping("/findHotel")
public String findHotel(Model model, Room room){
List<Hotel> hotel = hotelService.findHotel();
model.addAttribute("hotel",hotel);
return "add";
}
}
package an.cxy.controller;
import an.cxy.pojo.Room;
import an.cxy.service.RoomService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.validation.Valid;
import java.util.List;
@Controller
public class RoomController {
@Autowired
RoomService roomService;
@RequestMapping("/adds")
public String add(Room room){
return "/add";
}
@RequestMapping("/addRoom")
public String addRoom(@Valid Room room,BindingResult result){
if(result.hasErrors()){
return "/add";
}
roomService.addRoom(room);
return "redirect:/findAllRoom";
}
@RequestMapping("/findAllRoom")
public String findAllRoom(Model model){
List<Room> list = roomService.findAllRoom();
model.addAttribute("list",list);
System.out.println(list);
return "all";
}
@RequestMapping("/findByName")
public String findByName(Model model,String name){
name="%"+name+"%";
List<Room> list = roomService.findByName(name);
model.addAttribute("list",list);
return "all";
}
@RequestMapping("/delete")
public String delete( Integer rid){
roomService.delete(rid);
return "redirect:/findAllRoom";
}
}
8.自定义异常
package an.cxy.exception;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
//SpringBoot 处理异常方式五:@Configuration: 通过实现HandlerExceptionResolver完成全局异常
// 结合方式三四:既能跳转到指定页面又能携带参数
@Configuration
public class GlobalException implements HandlerExceptionResolver {
@Override
public ModelAndView resolveException(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) {
ModelAndView mv=new ModelAndView();
if(e instanceof Exception){
mv.setViewName("error1");//指定视图
}
mv.addObject("error",e.toString());
return mv;
}
}
9.页面:使用thymeleaf渲染html
add.html:
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<form method="post" th:action="@{/addRoom}">
房型:<input type="radio" name="type" value="1">标准间
<input type="radio" name="type" value="2">豪华间
<input type="radio" name="type" value="3">总统套房<br>
价格:<input type="text" name="price" ><font color="red" th:errors="${room.price}"></font></font><br/>
<!--所属酒店:<select name="hotel">
<option value="1">七天</option>
<option value="2">如家</option>
<option value="3">汉庭</option>e">
</select><br>-->
所属酒店:<select name="hotel">
<option value="0">请选择</option>
<span th:each="h:${hotel}">
<option th:value="${h.hotelid}"><span th:text="${h.name}"></span></option>
</span>
</select><br>
描述:<textarea rows="3" cols="20" name="info"></textarea>
<input type="submit" value="发布" >
<input type="reset" value="重置">
</form>
</body>
</html>
all.html:
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>显示所有信息</title>
</head>
<body>
<form th:action="@{/findByName}" method="post">
名称:<input type="text" name="name"> <input type="submit" value="查询">
<hr>
<a th:href="@{/findHotel}">添加</a>
</form>
<hr>
<table border="1px" align="center" width="50%">
<tr>
<th>ID</th>
<th>酒店名称</th>
<th>房型</th>
<th>价格</th>
<th>地址</th>
<th>电话</th>
<th>操作</th>
</tr>
<tr th:each="room : ${list}">
<td th:text="${room.rid}"></td>
<td th:text="${room.hotel.name}"></td>
<td th:text="${room.type}"></td>
<td th:text="${room.price}"></td>
<td th:text="${room.hotel.address}"></td>
<td th:text="${room.hotel.mobile}"></td>
<th><a th:href="@{/delete(rid=${room.rid})}" >操作</a></th>
</tr>
</table>
</body>
</html>
error1.html
<html lang="en">
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>异常</title>
</head>
<body>
<span th:text="${error}"></span>
</body>
</html>