Spring Boot进阶系列四
这边文章主要实战如何使用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进阶系列四的更多相关文章
- Spring Boot进阶系列一
笔者最近在总结一个 Spring Boot实战系列,以方便将来查找和公司内部培训用途. 1.Springboot从哪里来 SpringBoot是由Pivotal团队在2013年开始研发.2014年4月 ...
- Spring Boot进阶系列三
Thymeleaf是官方推荐的显示引擎,这篇文章主要介绍怎么让spring boot整合Thymeleaf. 它是一个适用于Web和独立环境的现代服务器端Java模板引擎. Thymeleaf的主要 ...
- Spring Boot进阶系列二
上一篇文章,主要分析了怎么建立一个Restful web service,系列二主要创建一个H5静态页面使用ajax请求数据,功能主要有添加一本书,请求所有书并且按照Id降序排列,以及查看,删除一本书 ...
- Spring Boot干货系列:(四)Thymeleaf篇
Spring Boot干货系列:(四)Thymeleaf篇 原创 2017-04-05 嘟嘟MD 嘟爷java超神学堂 前言 Web开发是我们平时开发中至关重要的,这里就来介绍一下Spring Boo ...
- (转)Spring Boot干货系列:(四)开发Web应用之Thymeleaf篇
转:http://tengj.top/2017/03/13/springboot4/ 前言 Web开发是我们平时开发中至关重要的,这里就来介绍一下Spring Boot对Web开发的支持. 正文 Sp ...
- spring boot / cloud (十四) 微服务间远程服务调用的认证和鉴权的思考和设计,以及restFul风格的url匹配拦截方法
spring boot / cloud (十四) 微服务间远程服务调用的认证和鉴权的思考和设计,以及restFul风格的url匹配拦截方法 前言 本篇接着<spring boot / cloud ...
- Spring Boot 启动(四) EnvironmentPostProcessor
Spring Boot 启动(四) EnvironmentPostProcessor Spring 系列目录(https://www.cnblogs.com/binarylei/p/10198698. ...
- 【转】Spring Boot干货系列:(一)优雅的入门篇
转自Spring Boot干货系列:(一)优雅的入门篇 前言 Spring一直是很火的一个开源框架,在过去的一段时间里,Spring Boot在社区中热度一直很高,所以决定花时间来了解和学习,为自己做 ...
- 【转】Spring Boot干货系列:(二)配置文件解析
转自:Spring Boot干货系列:(二)配置文件解析 前言 上一篇介绍了Spring Boot的入门,知道了Spring Boot使用"习惯优于配置"(项目中存在大量的配置,此 ...
随机推荐
- 浅析libuv源码-node事件轮询解析(4)
这篇应该能结,简图如下. 上一篇讲到了uv__work_submit方法,接着写了. void uv__work_submit(uv_loop_t* loop, struct uv__work* w, ...
- IEEE浮点表示 (原发布 csdn 2018-10-14 10:29:33)
目录 观察IEEE浮点表示 工作中遇到过整型转浮点型(union那种转换),碰到就看下书,过后就遗忘了.等过段时间又出现此现象,又重新拿起书本,这次记录了过程.然而一直等到今天才写出来,以防以后还用到 ...
- c# winform devexpress TreeList过滤和绑定
/// <summary> /// 模糊查询 /// </summary> /// <param name="str"></param&g ...
- Linux纯小白操作(以安装JDK为例)
[本文只针对纯小白,有基础的请略过] 最近公司给分配工作使用的虚拟机都是Linux系统的,以前完全没接触过,今天按照网上一些教程操作,好多地方感觉对小白不够友好(有些问题非常小白那些教程没有写出来.我 ...
- localdb启动
前提:vs自带localdb,不用另外装.其次,vs里的的“sql server 对象资源管理器”(在视图里)可以常规管理它.相比之下,SSMS更专业(推荐),按情况选用. 正文: 安装完毕后…… C ...
- 3-awk
1.输出双引号:awk '{print "\""}' #放大:awk '{print " \" "}'使用“”双引号把一个 ...
- MSSQL记录表字段数据变化的相关SQl
在软件实施过程中,也许会有这样的问题: 表中数据出现非预期的结果,此时不确定是程序问题,哪个程序,存储过程,触发器.. 或还是人为修改的结果,此时可以用触发器对特定的表字段做跟踪监视,记录每次新增,修 ...
- windows10删除多出的oem分区
某次windows升级后,磁盘管理里新出现一个500多M的OEM分区 其实系统里本来就有一个OEM分区是第一个分区,大小499M,可能因为这个分区太小,系统就又新建一个 因为在windows10分区后 ...
- cephfs测试中出现的问题
最近重新对cephfs进行性能测试. 测试步骤: (1) 选取一个特地版本的操作系统内核,挂载20000个客户端; (2) 用iozone中的fileop工具,在每隔挂载点上都跑一个fileop进程; ...
- Django框架(十五)-- cookie和session组件
一.cookie 1.cookie的由来 HTTP协议是无状态的.无状态的意思是每次请求都是独立的,它的执行情况和结果与前面的请求和之后的请求都无直接关系,它不会受前面的请求响应情况直接影响,也不会直 ...