这边文章主要实战如何使用Mybatis以及整合Redis缓存,数据第一次读取从数据库,后续的访问则从缓存中读取数据。

1.0 Mybatis

MyBatis 是支持定制化 SQL、存储过程以及高级映射的优秀的持久层框架。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以对配置和原生Map使用简单的 XML 或注解,将接口和 Java 的 POJOs(Plain Old Java Objects,普通的 Java对象)映射成数据库中的记录。

MyBatis并不是一套完整的ORM数据库连接框架,目前大多数互联网公司首选的数据库连接方式,不会对应用程序或者数据库的现有设计强加任何影响。 SQL写在xml里,便于统一管理和优化。解除SQL与程序代码的耦合:通过提供DAL层,将业务逻辑和数据访问逻辑分离,使系统的设计更清晰,更易维护,更易单元测试。SQL和代码的分离,提高了可维护性。

它的优点也正是缺点,编写SQL语句时工作量很大,尤其是字段多、关联表多时,更是如此。 SQL语句依赖于数据库,导致数据库移植性差,不能更换数据库。

1.1使用 MyBatis 官方提供的 Spring Boot 整合包实现。

1.1.1. pom.xml里面添加mybatis jar包。

<!-- springboot,mybatis 整合包 -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.0</version>
</dependency>

1.1.2 配置数据库连接

在 application.properties 中添加:

# Data source configuration
spring.datasource.url=jdbc:mysql://localhost:3306/demo?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC
spring.datasource.username=user-name
spring.datasource.password=******
# mybatis 配置
mybatis.config-location=classpath:mybatis/mybatis-config.xml
mybatis.mapper-locations=classpath:mybatis/mapper/*.xml

1.1.3 在 src/main/resources 下创建 mybatis 文件夹,并在 mybatis 文件夹中创建 "mybatis-config.xml" 配置文件

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<settings>
<!-- 获取数据库自增主键值 -->
<setting name="useGeneratedKeys" value="true"/>
<!-- 使用列别名替换列名,默认为 true -->
<setting name="useColumnLabel" value="true"/>
<!-- 开启驼峰命名转换:Table(create_time) => Entity(createTime) -->
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
</configuration>

1.1.4 示例表依然使用系列一中的book表

CREATE TABLE `book` (

  `Id` int(11) NOT NULL AUTO_INCREMENT,
`Name` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`Category` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`Price` decimal(18,2) NOT NULL,
`Publish_Date` date NOT NULL,
`Poster` varchar(45) NOT NULL,
PRIMARY KEY (`Id`)
) ENGINE=InnoDB AUTO_INCREMENT=61 DEFAULT CHARSET=utf8

1.1.5 实体模型如下

public class Book implements Serializable {

       private static final long serialVersionUID = -8471725336062010735L;
private Integer id;
private String name;
private String category;
private Double price;
private Date publish_date;
private String poster; } // 省略getter,setter方法

1.1.6 Mapper接口

@Mapper
public interface BookMapper { public void insert(Book book);
public Book getById(Integer id);
public void deleteById(Integer id);
public void update(Book book);
}

1.1.7添加bookMapper.xml

mybatis 文件夹下创建一个 mapper文件夹,里边存放 Mpper 接口对应的 mapper 映射文件。

<?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.example.demo.store.BookMapper">
<insert id="insert" parameterType="com.example.demo.model.Book">
insert into demo.book(Name,Category,Price,Publish_Date,Poster) values(#{name},#{category},#{price},curdate(),'NA')
</insert>
<select id="getById" parameterType="java.lang.Integer" resultType="com.example.demo.model.Book">
SELECT * FROM demo.book where Id = #{id}
</select> <update id="update" parameterType="com.example.demo.model.Book">
update demo.book set Name = #{name},Price = #{price}, Category = #{category} where Id = #{id}
</update> <delete id="deleteById" parameterType="java.lang.Integer">
delete from demo.book where Id = #{id}
</delete>
</mapper>

2.0 使用Redis做缓存

redis是一个高性能的key-value存储系统。和Memcached类似,它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)、zset(sorted set --有序集合)和hash(哈希类型)。 可以对这些类型运行原子操作,例如附加到字符串 ; 递增哈希值 ; 将元素推送到列表中 ; 计算集合交集, 并集和差异 ; 或者在排序集中获得排名最高的成员。

为了实现其出色的性能,Redis使用 内存数据集。根据使用情况,可以通过每隔一段时间将数据集转储到磁盘或通过将每个命令附加到日志来保留它。如果仅仅需要功能丰富的网络内存缓存,则可以选择禁用持久性。

Redis还支持简单的设置,就可以实现主从异步复制,具有非常快速的非阻塞第一次同步,自动重新连接以及在网络分割上的部分重新同步。

2.1 集成Redis到Springboot应用程序

磁盘读写速度远低于内存读写速度,那么当数据量增大时,如果一直去连接数据库增删改查,那么压力之大可想而知。适时地引入缓存,直接从缓存中读取无疑是改善性能的很重要的手段。

2.1.1 pom.xml中添加redis jar包

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

2.1.2 在 application.properties 中添加配置信息

#Cache type is redis
spring.cache.type=redis
spring.redis.host=127.0.0.1
spring.redis.port=6379
spring.redis.password=
# 连接池最大连接数(使用负值表示没有限制)
spring.redis.pool.max-active=8
# 连接池最大阻塞等待时间(使用负值表示没有限制)
spring.redis.pool.max-wait=-1
# 连接池中的最大空闲连接
spring.redis.pool.max-idle=8
# 连接池中的最小空闲连接
spring.redis.pool.min-idle=0
# 连接超时时间(毫秒)
spring.redis.timeout=0
# Cache expire time
spring.cache.redis.time-to-live=120000

2.1.3 加入一层服务,在com.example.demo.service package中,新建BookService.java

@CacheConfig(cacheNames="book")
@Service
public class BookService {
@Autowired
private BookMapper bookMapper; @CachePut(key = "#book.id")
public void save(Book book) {
System.out.println("Save name =" + book.getName() + " data...");
this.bookMapper.insert(book);
} @CachePut(key = "#book.id")
public void update(Book book) {
System.out.println("Update id = " + book.getId() + " data...");
this.bookMapper.update(book);
} @Cacheable(key = "#id")
public Book getBookById(Integer id) {
System.out.println("No data in cache, fetch data from db server. Id is : " + id);
Book book = bookMapper.getById(id);
return book;
} @CacheEvict(key = "#id")
public void delete(Integer id) {
System.out.println("Delete id=" + id + " data from db server...");
bookMapper.deleteById(id);
}
}

2.1.4 添加Controller

@Controller
@RequestMapping("book")
@ResponseBody
public class BookController { @Autowired
private BookService bookServie;     @RequestMapping("save")
public void save(Book book) {
this.bookServie.save(book);
} @RequestMapping("update")
public void update(Book book) {
this.bookServie.update(book);
} @RequestMapping("get/{id}")
  public Book get(@PathVariable("id") Integer id) {
    Book book = this.bookServie.getBookById(id);
    return book;
} @RequestMapping("delete/{id}")
public void delete(@PathVariable("id") Integer id) {
this.bookServie.delete(id);
}
}

2.1.5 开启缓存注解

@EnableCaching
@SpringBootApplication
public class ProductApp1Application {
public static void main(String[] args) {
SpringApplication.run(ProductApp1Application.class, args);
}
}

2.1.6 测试,

浏览器上输入,http://localhost:8080/book/get/58

只有第一次会访问数据库,

No data in cache, fetch data from db server. Id is : 58

2019-09-01 17:36:36.559 DEBUG 21364 --- [nio-8080-exec-7] c.example.demo.store.BookMapper.getById  : ==>  Preparing: SELECT * FROM demo.book where Id = ?

2019-09-01 17:36:36.847 DEBUG 21364 --- [nio-8080-exec-7] c.example.demo.store.BookMapper.getById  : ==> Parameters: 58(Integer)

2019-09-01 17:36:36.874 DEBUG 21364 --- [nio-8080-exec-7] c.example.demo.store.BookMapper.getById  : <==      Total: 1

后续发送请求则直接从缓存中读取数据,此时已经没有任何日志输出了。

Spring Boot进阶系列四的更多相关文章

  1. Spring Boot进阶系列一

    笔者最近在总结一个 Spring Boot实战系列,以方便将来查找和公司内部培训用途. 1.Springboot从哪里来 SpringBoot是由Pivotal团队在2013年开始研发.2014年4月 ...

  2. Spring Boot进阶系列三

    Thymeleaf是官方推荐的显示引擎,这篇文章主要介绍怎么让spring boot整合Thymeleaf.  它是一个适用于Web和独立环境的现代服务器端Java模板引擎. Thymeleaf的主要 ...

  3. Spring Boot进阶系列二

    上一篇文章,主要分析了怎么建立一个Restful web service,系列二主要创建一个H5静态页面使用ajax请求数据,功能主要有添加一本书,请求所有书并且按照Id降序排列,以及查看,删除一本书 ...

  4. Spring Boot干货系列:(四)Thymeleaf篇

    Spring Boot干货系列:(四)Thymeleaf篇 原创 2017-04-05 嘟嘟MD 嘟爷java超神学堂 前言 Web开发是我们平时开发中至关重要的,这里就来介绍一下Spring Boo ...

  5. (转)Spring Boot干货系列:(四)开发Web应用之Thymeleaf篇

    转:http://tengj.top/2017/03/13/springboot4/ 前言 Web开发是我们平时开发中至关重要的,这里就来介绍一下Spring Boot对Web开发的支持. 正文 Sp ...

  6. spring boot / cloud (十四) 微服务间远程服务调用的认证和鉴权的思考和设计,以及restFul风格的url匹配拦截方法

    spring boot / cloud (十四) 微服务间远程服务调用的认证和鉴权的思考和设计,以及restFul风格的url匹配拦截方法 前言 本篇接着<spring boot / cloud ...

  7. Spring Boot 启动(四) EnvironmentPostProcessor

    Spring Boot 启动(四) EnvironmentPostProcessor Spring 系列目录(https://www.cnblogs.com/binarylei/p/10198698. ...

  8. 【转】Spring Boot干货系列:(一)优雅的入门篇

    转自Spring Boot干货系列:(一)优雅的入门篇 前言 Spring一直是很火的一个开源框架,在过去的一段时间里,Spring Boot在社区中热度一直很高,所以决定花时间来了解和学习,为自己做 ...

  9. 【转】Spring Boot干货系列:(二)配置文件解析

    转自:Spring Boot干货系列:(二)配置文件解析 前言 上一篇介绍了Spring Boot的入门,知道了Spring Boot使用"习惯优于配置"(项目中存在大量的配置,此 ...

随机推荐

  1. Java : Hibernate 动态+分页+自定义字段+自定义实体类查询

    // 组合查询public List<ListBookDTO> listSetDSL(PublishingHouse publishingHouse,Integer minDiscount ...

  2. tornado6与python3.7,异步新姿势

    废话不多说,直接上代码 __auth__ = "aleimu" __doc__ = "学习tornado6.0+ 版本与python3.7+" import t ...

  3. pod的yaml说明

    apiVersion: v1 #指定api版本,此值必须在kubectl apiversion中 kind: Pod #指定创建资源的角色/类型 metadata: #资源的元数据/属性 name: ...

  4. window.postMessage()实现跨域消息传递

    window.postMessage() 方法可以安全地实现跨源通信.通常,对于两个不同页面的脚本,只有当执行它们的页面位于具有相同的协议(通常为https), 端口号(443为https的默认值), ...

  5. python 排序 选择排序

    算法思想: 首先从序列中选择一个最值,将这个元素和序列的首地址上的元素交换,这样就完成了一个元素的排序,接下来,重复上述过程,不断的从剩下的序列中选取最值,然后添加到有序部分的末尾(注意,这种添加是通 ...

  6. 线程安全---Day23

    最近忙着备考大学四年最后的两科,昨天刚考完大学所有的考试,但是大学专业是机械,但是自己热衷于IT行业,想往IT行业走,希望毕业后能成功进入到IT行业,只希望毕业能找到一份Java开发工程师的工作,这样 ...

  7. HighChat动态绑定数据 数据后台绑定(三)

    今天看了几位大佬的博客,学到了一些,现在分享一下,也作为以后的参考 不多说看代码 1.后台代码 public ActionResult Ajax2() { ReportData reportData ...

  8. 面试官:你知道Spring中有哪些可以让我们扩展的地方么

    大家都知道我这段时间陆续更新了Spring系列源码分析以及各种扩展点的文章,到了今天可以总算可以更新这篇文章了 首先列举一下一个经典的面试题:Spring中Bean的生命周期: 开始初始化容器 加载B ...

  9. 5.css三角的做法

    如上图所示,类似这样的小三角都可以通过以下代码写出: .box1 { width: ; height: ; /* border: 10px solid pink; */ border-top: 10p ...

  10. FCC-学习笔记 Pig Latin

    FCC-学习笔记  Pig Latin 1>最近在学习和练习FCC的题目.这个真的比较的好,推荐给大家. 2>中文版的地址:https://www.freecodecamp.cn/;英文版 ...