项目结构
![]()
一、准备数据
创建数据库并创建表
![]()
二、在domain下新建City类
package com.uos.springboot.domain;
import java.io.Serializable;
/**
* 城市实体类
*/
public class City implements Serializable {
private static final long serialVersionUID = -1L;
/**
* 城市编号
*/
private Long id;
/**
* 省份编号
*/
private Long provinceId;
/**
* 城市名称
*/
private String cityName;
/**
* 描述
*/
private String description;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Long getProvinceId() {
return provinceId;
}
public void setProvinceId(Long provinceId) {
this.provinceId = provinceId;
}
public String getCityName() {
return cityName;
}
public void setCityName(String cityName) {
this.cityName = cityName;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
@Override
public String toString() {
return "City{" +
"id=" + id +
", provinceId=" + provinceId +
", cityName='" + cityName + '\'' +
", description='" + description + '\'' +
'}';
}
}
三、在dao层下新建
CityDao接口
package com.uos.springboot.dao;
import com.uos.springboot.domain.City;
import io.lettuce.core.dynamic.annotation.Param;
import java.util.List;
/**
* 城市 DAO 接口类
*/
public interface CityDao {
/**
* 获取城市信息列表
*/
List<City> findAllCity();
/**
* 根据城市 ID,获取城市信息
*/
City findById(@Param("id") Long id);
Long saveCity(City city);
Long updateCity(City city);
Long deleteCity(Long id);
}
在resource下创建mapper-->CityMapper.xml
<?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.uos.springboot.dao.CityDao">
<resultMap id="BaseResultMap" type="com.uos.springboot.domain.City">
<result column="id" property="id" />
<result column="province_id" property="provinceId" />
<result column="city_name" property="cityName" />
<result column="description" property="description" />
</resultMap>
<sql id="Base_Column_List">
id, province_id, city_name, description
</sql>
<select id="findById" resultMap="BaseResultMap" parameterType="java.lang.Long">
select
<include refid="Base_Column_List" />
from city
where id = #{id}
</select>
<select id="findAllCity" resultMap="BaseResultMap" >
select
<include refid="Base_Column_List" />
from city
</select>
<insert id="saveCity" parameterType="City" useGeneratedKeys="true" keyProperty="id">
insert into
city(id,province_id,city_name,description)
values
(#{id},#{provinceId},#{cityName},#{description})
</insert>
<update id="updateCity" parameterType="City">
update
city
set
<if test="provinceId!=null">
province_id = #{provinceId},
</if>
<if test="cityName!=null">
city_name = #{cityName},
</if>
<if test="description!=null">
description = #{description}
</if>
where
id = #{id}
</update>
<delete id="deleteCity" parameterType="java.lang.Long">
delete from
city
where
id = #{id}
</delete>
</mapper>
四、在Service层下
新建CityService接口
package com.uos.springboot.service;
import com.uos.springboot.domain.City;
/**
* 城市业务逻辑接口类
*/
public interface CityService {
/**
* 根据城市 ID,查询城市信息
*/
City findCityById(Long id);
/**
* 新增城市信息
*/
Long saveCity(City city);
/**
* 更新城市信息
*/
Long updateCity(City city);
/**
* 根据城市 ID,删除城市信息
*/
Long deleteCity(Long id);
}
CityServiceImpl实现类
package com.uos.springboot.service.impl;
import com.uos.springboot.dao.CityDao;
import com.uos.springboot.domain.City;
import com.uos.springboot.service.CityService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;
import java.util.concurrent.TimeUnit;
/**
* 城市业务逻辑实现类
*/
@Service
public class CityServiceImpl implements CityService {
private static final Logger LOGGER = LoggerFactory.getLogger(CityServiceImpl.class);
@Autowired
private CityDao cityDao;
@Autowired
private RedisTemplate redisTemplate;
/**
* 获取城市逻辑:
* 如果缓存存在,从缓存中获取城市信息
* 如果缓存不存在,从 DB 中获取城市信息,然后插入缓存
*/
public City findCityById(Long id) {
// 从缓存中获取城市信息
String key = "city_" + id;
ValueOperations<String, City> operations = redisTemplate.opsForValue();
// 缓存存在
boolean hasKey = redisTemplate.hasKey(key);
if (hasKey) {
City city = operations.get(key);
LOGGER.info("CityServiceImpl.findCityById() : 从缓存中获取了城市 >> " + city.toString());
return city;
}
// 从 DB 中获取城市信息
City city = cityDao.findById(id);
// 插入缓存
operations.set(key, city, 10, TimeUnit.SECONDS);
LOGGER.info("CityServiceImpl.findCityById() : 城市插入缓存 >> " + city.toString());
return city;
}
@Override
public Long saveCity(City city) {
return cityDao.saveCity(city);
}
/**
* 更新城市逻辑:
* 如果缓存存在,删除
* 如果缓存不存在,不操作
*/
@Override
public Long updateCity(City city) {
Long ret = cityDao.updateCity(city);
// 缓存存在,删除缓存
String key = "city_" + city.getId();
boolean hasKey = redisTemplate.hasKey(key);
if (hasKey) {
redisTemplate.delete(key);
LOGGER.info("CityServiceImpl.updateCity() : 从缓存中删除城市 >> " + city.toString());
}
return ret;
}
@Override
public Long deleteCity(Long id) {
Long ret = cityDao.deleteCity(id);
// 缓存存在,删除缓存
String key = "city_" + id;
boolean hasKey = redisTemplate.hasKey(key);
if (hasKey) {
redisTemplate.delete(key);
LOGGER.info("CityServiceImpl.deleteCity() : 从缓存中删除城市 ID >> " + id);
}
return ret;
}
}
五、全局配置文件
## 数据源配置
spring.datasource.url=jdbc:mysql://localhost:3306/springbootdb?serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
## Mybatis 配置
mybatis.typeAliasesPackage=com.uos.springboot.domain
mybatis.mapperLocations=classpath:mapper/*.xml
## Redis 配置
## Redis数据库索引(默认为0)
spring.redis.database=0
## Redis服务器地址
spring.redis.host=192.168.152.120
## Redis服务器连接端口
spring.redis.port=6379
## Redis服务器连接密码(默认为空)
spring.redis.password=1
# 连接池最大连接数(使用负值表示没有限制)
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=5000
六、启动类
![]()
七、结果测试
![]()