前言

注:本篇为纯实践篇,主要用于技术整合,介绍如何搭建一个完整全面的Web项目。如果对于技术原理还不了解的童鞋可点击下方链接,学习后在来~

H2数据库教程:H2数据库入门

缓存使用教程:在Spring中使用缓存

Spring Data JPA使用教程:Spring Data JPA学习导引

使用Redis缓存(与本章内容基本相同,唯一的差别是使用Redis缓存):在SpringBoot中使用Redis缓存

1、环境配置

pom.xml需要引入的包如下:

<?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>com.scb</groupId><artifactId>h2demo</artifactId><version>0.0.1-SNAPSHOT</version><packaging>jar</packaging><name>h2demo</name><description>Demo project for Spring Boot</description><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.1.0.RELEASE</version><relativePath/> <!-- lookup parent from repository --></parent><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding><java.version>1.8</java.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</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-thymeleaf</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>com.h2database</groupId><artifactId>h2</artifactId><scope>runtime</scope></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><!-- 阿里系的Druid依赖包 --><dependency><groupId>com.alibaba</groupId><artifactId>druid-spring-boot-starter</artifactId><version>1.1.9</version></dependency><!-- Druid 依赖 log4j包 --><dependency><groupId>log4j</groupId><artifactId>log4j</artifactId><version>1.2.17</version></dependency><!-- Ehcache依赖包 --><dependency><groupId>net.sf.ehcache</groupId><artifactId>ehcache</artifactId><version>2.7.2</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-context-support</artifactId></dependency><dependency><groupId>org.hibernate</groupId><artifactId>hibernate-ehcache</artifactId><version>4.1.0.Final</version></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>

然后在application.yml中进行配置

spring:jpa:generate-ddl: falseshow-sql: true    //输出sql语句hibernate:ddl-auto: noneh2:console:path: /h2-consoleenabled: truesettings:web-allow-others: truedatasource:platform: h2url: jdbc:h2:~/test    //test是我创建的数据库名username: sapassword:schema: classpath:schema.sql //程序运行时,使用schema.sql来创建数据库中的表data: classpath:data.sql  //程序运行时,使用data.sql来创建初始数据name: testtype: com.alibaba.druid.pool.DruidDataSource    //使用阿里druid连接池druid:min-idle: 2initial-size: 5max-active: 10max-wait: 5000validation-query: select 1
server:port: 8080

schema.sql代码如下:

drop table if exists staff;
CREATE TABLE staff(
id INTEGER not null primary key,
name char(20),
age INTEGER
);

data.sql代码如下:

insert into staff
values (1, '张三', 26);insert into staff
values (2, '李四', 23);insert into staff
values (3,'张某', 26);insert into staff
values (4,'王五', 26);insert into staff
values (5,'甲六', 26);insert into staff
values (6,'已七', 26);insert into staff
values (7,'丙八', 26);insert into staff
values (8,'丁九', 26)

2、代码详解

要使用Ehcache进行缓存的话,需要对其进行配置。首先创建一个ehcache.xml,代码如下:

<?xml version="1.0" encoding="UTF-8"?>
<ehcache updateCheck="false"><!-- 指定一个文件目录,当EhCache把数据写到硬盘上时,将把数据写到这个文件目录下 --><diskStore path="java.io.tmpdir"/><!-- 设定缓存的默认数据过期策略 --><defaultCachemaxElementsInMemory="10000"eternal="false"timeToIdleSeconds="120"timeToLiveSeconds="120"overflowToDisk="true"diskPersistent="false"diskExpiryThreadIntervalSeconds="120"memoryStoreEvictionPolicy="LRU"/><cachename="myCache"maxElementsInMemory="10000"eternal="false"overflowToDisk="true"timeToIdleSeconds="30"timeToLiveSeconds="60"memoryStoreEvictionPolicy="LFU"/>
</ehcache>

在创建一个CachingConfig类进行配置

package com.scb.h2demo.config;import net.sf.ehcache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.ehcache.EhCacheCacheManager;
import org.springframework.cache.ehcache.EhCacheManagerFactoryBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;@Configuration
@EnableCaching
public class CachingConfig {/** 配置EhCacheCacheManager*/@Beanpublic EhCacheCacheManager cacheManager(CacheManager cacheManager){EhCacheCacheManager ehCacheCacheManager = new EhCacheCacheManager(cacheManager);return ehCacheCacheManager;}/** 配置EhCacheManagerFactoryBean*/@Beanpublic EhCacheManagerFactoryBean ehCacheManagerFactoryBean(){EhCacheManagerFactoryBean cacheManagerFactoryBean = new EhCacheManagerFactoryBean ();cacheManagerFactoryBean.setConfigLocation (new ClassPathResource("ehcache.xml"));cacheManagerFactoryBean.setShared (true);return cacheManagerFactoryBean;}
}

接下来创建实体层对象Staff

package com.scb.h2demo.entity;import lombok.Data;import javax.persistence.*;
import java.io.Serializable;@Data
@Entity
@Table(name="staff")
public class Staff implements Serializable {private static final long serialVersionUID = 1L;@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private Integer id;@Column(name="name")private String name;@Column(name="age")private Integer age;
}

在创建DAO层

package com.scb.h2demo.dao;import com.scb.h2demo.entity.Staff;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;import java.util.List;@Repository
public interface StaffRepository extends JpaRepository<Staff,Integer> {@Query("from Staff where name like %:name%")List<Staff> getByNameIsLike(@Param("name")String name);Staff getById(Integer id);void deleteById(Integer id);
}

接着创建Service层(在Service层接口上,应用缓存,此时其所有实现类都将继承缓存。)

package com.scb.h2demo.service;import com.scb.h2demo.entity.Staff;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.domain.Page;import java.util.List;public interface IStaffService {List<Staff> getAllList();Page<Staff> queryAllStaffList(int pageNum,int pageSize);List<Staff> getByNameIsLike(String name);@Cacheable("myCache")Staff findOne(Integer id);@CachePut(value="myCache", key = "#result.id")Staff insert(Staff staff);@CacheEvict("myCache")void remove(Integer id);@CacheEvict("myCache")void deleteAll();
}
package com.scb.h2demo.service;import com.scb.h2demo.dao.StaffRepository;
import com.scb.h2demo.entity.Staff;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;import javax.transaction.Transactional;
import java.util.List;@Service
@Transactional
public class StaffServiceImpl implements IStaffService {@Autowiredprivate StaffRepository staffRepository;@Overridepublic List<Staff> getAllList() {return staffRepository.findAll();}@Overridepublic Page<Staff> queryAllStaffList(int pageNum,int pageSize) {Sort sort=new Sort(Sort.Direction.DESC,"id");Pageable pageable=new PageRequest(pageNum,pageSize,sort);return staffRepository.findAll(pageable);}@Overridepublic List<Staff> getByNameIsLike(String name) {return staffRepository.getByNameIsLike(name);}@Overridepublic Staff findOne(Integer id) {return staffRepository.getById(id);}@Overridepublic Staff insert(Staff staff) {return staffRepository.save(staff);}@Overridepublic void remove(Integer id) {staffRepository.deleteById(id);}@Overridepublic void deleteAll() {staffRepository.deleteAll();}
}

最后是Controller层(RESTful风格)

package com.scb.h2demo.controller;import com.scb.h2demo.entity.Staff;
import com.scb.h2demo.exception.Error;
import com.scb.h2demo.exception.StaffNotFoundException;
import com.scb.h2demo.service.IStaffService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;import java.util.List;@RestController
@RequestMapping(path="/staffRest",produces="application/json;charset=utf-8")
public class RestServiceController {@Autowiredprivate IStaffService staffService;@ExceptionHandler(StaffNotFoundException.class)@ResponseStatus(HttpStatus.NOT_FOUND)public Error staffNotFound(StaffNotFoundException e){Integer id=e.getStaffId();return new Error(4,"Staff ["+id+"] not found");}@GetMapping("/{id}")public Staff staffById(@PathVariable Integer id){Staff staff=staffService.findOne(id);if(staff==null){throw new StaffNotFoundException(id);}return staff;}@GetMappingpublic List<Staff> getAllStaffs(){return staffService.getAllList();}@PostMappingpublic Staff createStaff(Staff staff){return staffService.insert(staff);}@PutMappingpublic Staff updateStaff(Staff staff){return staffService.insert(staff);}@DeleteMapping("/{id}")public Staff deleteStaffById(@PathVariable Integer id){Staff staff=staffService.findOne(id);if(staff==null){throw new StaffNotFoundException(id);}staffService.remove(id);return staff;}@DeleteMappingpublic List<Staff> deleteAllStaffs(){List<Staff> staffList=staffService.getAllList();staffService.deleteAll();return staffList;}
}

其中Error是自定义的POJO类,用来记录异常。

package com.scb.h2demo.exception;import lombok.AllArgsConstructor;
import lombok.Getter;@AllArgsConstructor
@Getter
public class Error {private int code;private String message;
}

而StaffNotFoundException是自定义的异常类

package com.scb.h2demo.exception;public class StaffNotFoundException extends RuntimeException {private Integer staffId;public StaffNotFoundException(Integer staffId){this.staffId=staffId;}public Integer getStaffId(){return staffId;}
}

现在,整个项目已经开发完毕,接下来,让我们使用Postman来进行测试。

3、使用Postman进行测试

当我们以GET请求访问 http://localhost:8080/staffRest/1 时,将返回 id 为1的员工。

如果以GET请求访问 http://localhost:8080/staffRest/9 时,即访问不存在的员工时,将返回Error对象:

而以GET请求访问 http://localhost:8080/staffRest 时,返回的是所有员工列表。

以POST请求访问 http://localhost:8080/staffRest 并加上staff参数时,将create一个staff

以PUT请求访问 http://localhost:8080/staffRest 并加上staff参数时,将update一个staff(其实update和create操作都一样,通过调用JpaRepository的insert方法实现,而insert方法,他首先会查找是否存在相同主键,如果存在则update,否则create)

最后,以DELETE请求访问 http://localhost:8080/staffRest/1 时,是删除id为1的员工。

以DELETE请求访问 http://localhost:8080/staffRest 时,是删除所有的员工。

使用H2Database+Druid连接池+Spring Data JPA+Ehcache实现CRUD操作相关推荐

  1. Spring Data JPA(官方文档翻译)

    关于本书 介绍 关于这本指南 第一章 前言 第二章 新增及注意点 第三章 项目依赖 第四章 使用Spring Data Repositories 4.1 核心概念 4.2 查询方法 4.3 定义rep ...

  2. Spring Security+Spring Data Jpa 强强联手,安全管理只有更简单!

    Spring Security+Spring Data Jpa 强强联手,安全管理没有简单,只有更简单! 这周忙着更新 OAuth2,Spring Security 也抽空来一篇. Spring Se ...

  3. Spring Boot 应用系列 1 -- Spring Boot 2 整合Spring Data JPA和Druid,双数据源

    最近Team开始尝试使用Spring Boot + Spring Data JPA作为数据层的解决方案,在网上逛了几圈之后发现大家并不待见JPA,理由是(1)MyBatis简单直观够用,(2)以Hib ...

  4. Java回顾(十二) File类、Druid连接池、JDBCTemplate(Spring JDBC)、HTML和CSS

    1.File类 1.1.File类概述和构造方法 File:是文件和目录路径名的抽象表示 文件和路径是可以通过File封装为对象的 以下是三种实现的方法,一般来说,用第一种就可以 public cla ...

  5. spring配置druid连接池和监控数据库访问性能

    Druid连接池及监控在spring配置如下: [html] view plaincopy <bean id="dataSource" class="com.ali ...

  6. java spring druid_Spring配置Druid连接池

    最近项目用c3p0数据连接池有问题,因此换成了druid连接池,它的优点是可以很好的监控DB池连接和SQL的执行情况.在此做个记录便于下次使用. 1.首先导入Spring(网上很多这里我就不列举了)和 ...

  7. Spring Boot文档阅读笔记-使用Spring Data JPA连接多源数据库(MySQL和Oracle)

    下面这个小项目展示了如何连接2个数据库,一个是Oracle,一个是MySQL. 关键的Maven依赖: <dependency><groupId>org.springframe ...

  8. Spring学习总结(12)——Druid连接池及监控在spring配置

    Druid连接池及监控在 spring 配置如下: <bean  id="dataSource" class="com.alibaba.druid.pool.Dru ...

  9. Spring Boot 使用 Druid 连接池详解

    Spring Boot 使用 Druid 连接池详解 Alibaba Druid 是一个 JDBC 组件库,包含数据库连接池.SQL Parser 等组件,被大量业务和技术产品使用或集成,经历过严苛的 ...

最新文章

  1. 邓俊辉数据结构学习-3-栈
  2. Linux内核--网络栈实现分析(三)--驱动程序层+链路层(上)
  3. spring boot 邮件端口_1 分钟教会你用 Spring Boot 发邮件
  4. 获得TADIR-OBJECT全部的entry list
  5. head first python(第三章)–学习笔记
  6. [CQOI2014]通配符匹配
  7. 基于SpringCloud的微服务架构演变史?
  8. PCL之求点云的BoundingBox
  9. 啦啦外卖独立版41.4+全插件+可运营版本+开源(亲测100%可用)
  10. 3.6-WizNote 常用快捷键
  11. #pragma comment (lib, ws2_32.lib) 调用报错
  12. 复活唐音,是一味怎样的菜?
  13. java安卓分屏是如何实现的_安卓原生分屏有了,谷歌说:Android Q要实现分屏应用多开...
  14. python制作手机游戏脚本能使用到的相关方法
  15. windows 完成端口
  16. JavaScript_函数
  17. JAVA课程设计(小游戏贪吃蛇)完整源码附素材(二)
  18. 说说我在机场碰上的那些大家喜闻乐见的事
  19. Hadoop自动化安装脚本
  20. 常见的售后管理难点汇总

热门文章

  1. 以太坊控制台源码分析
  2. iOS8.1完美越狱
  3. 【技术手册】Java 开发者必备手册《Spring Cloud Alibaba 从入门到实战》
  4. “质量革命”背后:瓜子二手车的底层逻辑与战略选择
  5. 2018年云计算关键词:马太效应、价格竞赛与数字化转型
  6. TS-MPEG2视频数字水印演示程序
  7. 系统安全知识之系统安全的最小特权原则
  8. Serv-U------一款安全的、优秀FTP服务器
  9. 大厂 vs 小厂,我的亲身体验
  10. 赚钱的底层模式和破局思路