SpringBoot整合SpringData(Thymeleaf,NotNUll数据校验,自定义异常,Ehcache缓存)项目

一:酒店,房间项目(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>

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值