Project Structure
├── src
| ├── main
| | ├── java
| | | └── com.example.demo
| | | ├── config
| | | | └── RedisConfiguration.java
| | | ├── controller
| | | | └── UserController.java
| | | ├── entity
| | | | └── User.java
| | | ├── repository
| | | | └── UserMapper.java
| | | ├── service
| | | | ├── UserService.java
| | | | └── impl
| | | | └── UserServiceImpl.java
| | | ├── util
| | | | └── RedisHelper.java
| | | └── DemoApplication.java
| | └── resources
| | ├── mapper
| | | └── UserMapper.xml
| | ├── application.yml
| | └── data.sql
└── pom.xml
Environment Setup with Docker
MySQL Container
To pull and run MySQL:
docker pull mysql:8.0
docker run -d --name mysql-db \
-e MYSQL_ROOT_PASSWORD=rootpass \
-e MYSQL_DATABASE=testdb \
-p 3306:3306 mysql:8.0
Redis Container
To pull and run Redis:
docker pull redis:alpine
docker run -d --name redis-cache -p 6379:6379 redis:alpine
Database Initialization
Create the required table and sample data:
CREATE TABLE user (
id INT PRIMARY KEY,
name VARCHAR(255),
age INT
);
INSERT INTO user VALUES (1, 'Alice', 25), (2, 'Bob', 30);
Spring Boot Configuration
Application Properties
server:
port: 8080
spring:
datasource:
url: jdbc:mysql://localhost:3306/testdb
username: root
password: rootpass
driver-class-name: com.mysql.cj.jdbc.Driver
redis:
host: localhost
port: 6379
mybatis:
mapper-locations: classpath:mapper/*.xml
type-aliases-package: com.example.demo.entity
Main Applicationn Class
@SpringBootApplication
@MapperScan("com.example.demo.repository")
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
Data Layer Implementation
User Entity
public class User {
private Integer id;
private String name;
private Integer age;
// Getters and setters omitted for brevity
}
Mapper Interface
public interface UserMapper {
List<User> findAll();
void incrementAge(Integer id);
}
Mapper XML
<mapper namespace="com.example.demo.repository.UserMapper">
<select id="findAll" resultType="User">
SELECT * FROM user
</select>
<update id="incrementAge">
UPDATE user SET age = age + 1 WHERE id = #{id}
</update>
</mapper>
Redis Integration
Redis Configuraton
@Configuration
public class RedisConfiguration {
@Bean
public LettuceConnectionFactory redisConnectionFactory() {
return new LettuceConnectionFactory(
new RedisStandaloneConfiguration("localhost", 6379)
);
}
}
Redis Utility Class
@Component
public class RedisHelper {
private final StringRedisTemplate template;
public RedisHelper(StringRedisTemplate template) {
this.template = template;
}
public void save(String key, Object value) {
template.opsForValue().set(key, value.toString());
}
public String retrieve(String key) {
return template.opsForValue().get(key);
}
public void delete(String key) {
template.delete(key);
}
}
Service and Controller Layers
User Service
@Service
@Transactional
public class UserServiceImpl implements UserService {
private static final String USER_CACHE_KEY = "users";
private final UserMapper userMapper;
private final RedisHelper redisHelper;
public UserServiceImpl(UserMapper userMapper, RedisHelper redisHelper) {
this.userMapper = userMapper;
this.redisHelper = redisHelper;
}
@Override
public List<User> getAllUsers() {
String cached = redisHelper.retrieve(USER_CACHE_KEY);
if (cached != null) {
// Deserialize from cache
return deserialize(cached);
}
List<User> users = userMapper.findAll();
redisHelper.save(USER_CACHE_KEY, serialize(users));
return users;
}
@Override
public void updateAges() {
redisHelper.delete(USER_CACHE_KEY);
userMapper.incrementAge(1);
userMapper.incrementAge(2);
}
private String serialize(List<User> users) {
return users.stream()
.map(Object::toString)
.collect(Collectors.joining(","));
}
private List<User> deserialize(String data) {
// Simplified deserialization logic
return Arrays.asList();
}
}
REST Controller
@RestController
@RequestMapping("/api/users")
public class UserController {
private final UserService userService;
public UserController(UserService userService) {
this.userService = userService;
}
@GetMapping
public List<User> getUsers() {
return userService.getAllUsers();
}
@PostMapping("/update-ages")
public ResponseEntity<String> updateAges() {
userService.updateAges();
return ResponseEntity.ok("Ages updated successfully");
}
}
Maven Dependencies
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.2.0</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
</dependencies>
Testing the Application
Start the application and verify functionality:
- Retrieev all users:
GET /api/users - Update ages:
POST /api/users/update-ages - Check Redis cache using CLI:
redis-cli GET users