SSHフレームワークとRedisを連携したCRUD処理の具体的実装

新規データ登録機能の構築

まず、Redisへコース情報を登録し、同時にMySQLデータベースへ同期処理を行うActionクラスを作成します。以下の`CourseAddAction`クラスは、新しいエンティティの追加を担当します。

package com.example.edu.action;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.HashMap;

import org.springframework.beans.factory.annotation.Autowired;
import com.opensymphony.xwork2.ActionSupport;
import com.example.edu.entity.Course;
import com.example.edu.redis.RedisConnectionManager;
import com.example.edu.service.CourseService;

@SuppressWarnings("serial")
public class CourseAddAction extends ActionSupport {

    @Autowired
    private CourseService courseService;

    private RedisConnectionManager redisManager = RedisConnectionManager.getInstance();
    private List<Course> courseList = new ArrayList<>();

    private Course course;

    public Course getCourse() {
        return course;
    }

    public void setCourse(Course course) {
        this.course = course;
    }

    public String execute() {
        persistCourseData(course);
        return SUCCESS;
    }

    @SuppressWarnings({ "unchecked", "rawtypes" })
    private void persistCourseData(Course entity) {
        // 1. IDリストの取得と新しいIDの生成
        List<String> idList = redisManager.getList("course:id:list");
        int lastIndex = idList.size() - 1;
        int newId = Integer.parseInt(idList.get(lastIndex)) + 1;
        
        // 新しいIDをリストに追加
        redisManager.pushRight("course:id:list", String.valueOf(newId));

        // 2. トータルカウントの更新
        String currentCountStr = redisManager.get("course:total:count");
        int currentCount = Integer.parseInt(currentCountStr);
        redisManager.set("course:total:count", String.valueOf(currentCount + 1), -1);

        // 3. ハッシュデータの保存
        Map<String, String> dataMap = new HashMap<>();
        dataMap.put("ID", String.valueOf(newId));
        dataMap.put("NAME", entity.getName());
        dataMap.put("COMMENT", entity.getComment());
        
        String hashKey = "course:detail:" + newId;
        redisManager.storeHash(hashKey, dataMap);

        // 4. データベースへの同期
        courseService.addCourse(entity);
    }
}

この処理では、`course:id:list`というリストキーを利用して既存のIDを管理し、最後の要素を取得してインクリメントすることで新規IDを生成しています。その後、`storeHash`メソッドを用いてRedisのハッシュ構造にデータを保存し、`courseService`経由でMySQLにも永続化しています。

        @SuppressWarnings({ "unchecked", "rawtypes" })
        public synchronized void storeHash(K key, Map map) {
            redisTemplate.opsForHash().putAll(key, map);
        }

データ削除機能の構築

次に、RedisおよびMySQLから特定のコースデータを削除する機能を実装します。`CourseDeleteAction`クラスは、IDを指定してデータを削除し、一貫性を保ちます。

package com.example.edu.action;

import org.springframework.beans.factory.annotation.Autowired;
import com.opensymphony.xwork2.ActionSupport;
import com.example.edu.redis.RedisConnectionManager;
import com.example.edu.service.CourseService;

@SuppressWarnings("serial")
public class CourseDeleteAction extends ActionSupport {

    @Autowired
    private CourseService courseService;

    private RedisConnectionManager redisManager = RedisConnectionManager.getInstance();

    private int courseId;
    
    public int getCourseId() {
        return courseId;
    }
    
    public void setCourseId(int courseId) {
        this.courseId = courseId;
    }

    public String execute() {
        removeCourseData(courseId);
        // データベース同期
        courseService.removeCourse(courseId);
        return SUCCESS;
    }

    private void removeCourseData(int id) {
        // 対象ハッシュキーの削除
        redisManager.deleteKey("course:detail:" + id);

        // カウントのデクリメント
        String countStr = redisManager.get("course:total:count");
        int count = Integer.parseInt(countStr);
        redisManager.set("course:total:count", String.valueOf(count - 1), -1);

        // ID管理リストからの要素削除
        redisManager.removeItemFromList("course:id:list", String.valueOf(id));
    }
}

削除処理では、該当するハッシュキーを削除した後、総数カウントを減らします。最も複雑なのはリストからの削除ですが、`removeItemFromList`メソッドを用いて実装します。このメソッドはRedisの`LREM`コマンドに相当する機能を提供します。

        @Override
        public synchronized void removeItemFromList(K key, V value) {
            redisTemplate.opsForList().remove(key, 1, value);
        }

データ更新機能の構築

最後に、既存のコース情報を更新する処理を作成します。`CourseUpdateAction`クラスは、Redis上のハッシュデータを上書きし、変更をMySQLに反映させます。

package com.example.edu.action;

import java.util.HashMap;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import com.opensymphony.xwork2.ActionSupport;
import com.example.edu.entity.Course;
import com.example.edu.redis.RedisConnectionManager;
import com.example.edu.service.CourseService;

@SuppressWarnings("serial")
public class CourseUpdateAction extends ActionSupport {

    @Autowired
    private CourseService courseService;

    private RedisConnectionManager redisManager = RedisConnectionManager.getInstance();

    private Course course;

    public Course getCourse() {
        return course;
    }

    public void setCourse(Course course) {
        this.course = course;
    }

    @SuppressWarnings({ "rawtypes", "unchecked" })
    public String execute() {
        Map<String, String> updateMap = new HashMap<>();
        updateMap.put("ID", String.valueOf(course.getId()));
        updateMap.put("NAME", course.getName());
        updateMap.put("COMMENT", course.getComment());
        
        redisManager.updateHash("course:detail:" + course.getId(), updateMap);
        
        // データベース同期
        courseService.modifyCourse(course);
        return SUCCESS;
    }
}

更新処理には`updateHash`メソッドを使用します。このメソッドは、指定されたキーのハッシュ全体を新しいマップデータで置き換えます。

        @SuppressWarnings({ "rawtypes", "unchecked" })
        @Override
        public synchronized void updateHash(K key, Map map) {
            redisTemplate.boundHashOps(key).putAll(map);
        }

7月19日 00:04 投稿