这边文章主要实战如何使用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. MySQL数据库 : 高级查询

    根据某个字段删除重复的数据, 只保留一条: 比如uuid字段有重复的, 需要只保留一条数据, 让uuid字段不能重复, 则首先 group by uuid 查出所有数据的id最小的那条数据,作为dt表 ...

  2. Jaeger接入Python应用:jaeger-client-python【非完全教程】

    目录 Jaeger接入Python应用 1. 安装 jaeger-client 2. (示例)创建 Tracer 对象,并通过 Tracer 对象创建 Span 来追踪业务流程. 3. 初始化和配置 ...

  3. 使用Redis实现中英文自动补全功能详解

    1.Redis自动补全功能介绍: ​ Redis可以帮我们实现很多种功能,今天这里着重介绍的是Redis的自动补全功能的实现.我们使用有序集合,并score都为0,这样就按元素值的字典序排序.然后我们 ...

  4. Logstash跟es加密通信

    前提条件,es集群内部各节点已开启https访问,集群也已开启x-pack安全功能,并设置了系统默认的用户密码等,具体操作详见:https://www.cnblogs.com/sanduzxcvbnm ...

  5. 【java】java反射获取属性和属性值,java反射设置属性和属性值

    今日份代码如下: /** * * @Author: SXD * @Description: * @Date: create in 2019/9/20 15:39 */ public class Pro ...

  6. 【ELK】elasticsearch中使用脚本报错:scripts of type [inline], operation [update] and lang [groovy] are disabled

    查看ID为2的这条数据: 使用更新命令: 使用脚本对年龄+5 curl -XPOST http://192.168.6.16:9200/my_new_index/user/2/_update?pret ...

  7. 使用Ueditor上传图片到图片服务器(一)

    网站的文章,通过运营平台来发布文章(图文消息),上传图片等.百度Ueditor比较成熟就采用了该技术,另外上传的图片是网站系统以及运营平台系统共享的,所以考虑搭建独立的图片服务器,以后也可以提供给公司 ...

  8. Vue.js最佳实践--VueRouter的beforeEnter与beforeRouteLeave冲突解决

    用Vue做应用管理系统,通常会在离开某个页面的时候,需要检测用户是否有修改,询问用户需要不需要保存之类的需求 这时候,在读VueRouter文档:组件内的守卫 的时候,发现beforeRouteLea ...

  9. Qt QVector简单用法

    添加元素 QVector<QString> strArray; strArray.append("Hello"); 遍历 QVector<QString>: ...

  10. Spark源码执行逻辑分析【基于案例SparkPi】

    一.案例SparkPi代码 package scala import org.apache.spark.sql.SparkSession import scala.math.random /** Co ...