Refactoring Scene Data Model to Separate Session ID Using MyBatis in Java
This article explains how to redesign a Java data model so that a single sessionId is stored at the outer level while multiple sceneId/sceneName pairs are nested inside a sceneList, and shows the required MyBatis mapper, XML mapping, service, and controller implementations.
Background: In a business scenario a single session_id may correspond to multiple scene_id and scene_name, and the original data structure repeats sessionId in each object.
Original VO class (redundant):
public class SceneVO {
private String sessionId;
private String sceneId;
private String sceneName;
// getters and setters omitted
}Sample JSON returned by the original design:
{
"data":[
{"sessionId":"jksadhjksd","sceneId":"NDJWKSDSJKDKED","sceneName":"场景1"},
{"sessionId":"jksadhjksd","sceneId":"KLJSDJKLSDFALK","sceneName":"场景2"},
{"sessionId":"jksadhjksd","sceneId":"KERFJKOVDJKDSS","sceneName":"场景3"}
]
}Desired JSON format moves sessionId to the outer level and nests scenes inside a sceneList array:
{
"data": {
"sessionId": "jksadhjksd",
"sceneList": [
{"sceneId":"NDJWKSDSJKDKED","sceneName":"场景1"},
{"sceneId":"KLJSDJKLSDFALK","sceneName":"场景2"},
{"sceneId":"KERFJKOVDJKDSS","sceneName":"场景3"}
]
}
}Entity classes to achieve the new structure:
public class SceneVO {
private String sessionId;
private List<SubSceneVO> sceneList;
// getters and setters omitted
}
public class SubSceneVO {
private String sceneId;
private String sceneName;
// getters and setters omitted
}Custom MyBatis mapper interface and XML mapping:
public interface BusinessScenesCustomMapper {
SceneVO selectBySessionId(String sessionId);
} <?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="your.package.mapper.BusinessScenesCustomMapper">
<resultMap id="BaseResultMap" type="your.package.vo.SceneVO">
<result column="session_id" jdbcType="VARCHAR" property="sessionId"/>
<!-- collection maps the repeated rows to a list of SubSceneVO -->
<collection property="sceneList" ofType="your.package.vo.SubSceneVO">
<result column="scene_id" jdbcType="VARCHAR" property="sceneId"/>
<result column="scene_name" jdbcType="VARCHAR" property="sceneName"/>
</collection>
</resultMap>
<select id="selectBySessionId" parameterType="string" resultMap="BaseResultMap">
SELECT session_id, scene_id, scene_name
FROM your_table
WHERE session_id = #{sessionId,jdbcType=VARCHAR}
</select>
</mapper>Service layer that delegates to the mapper:
public interface SceneService {
/** Get scene information for a given session */
SceneVO getScenesInfo(String sessionId);
}
@Service
public class SceneServiceImpl implements SceneService {
@Resource
private BusinessScenesCustomMapper businessScenesCustomMapper;
@Override
public SceneVO getScenesInfo(String sessionId) {
return businessScenesCustomMapper.selectBySessionId(sessionId);
}
}Controller exposing a REST endpoint:
@RestController
public class SceneController {
@Resource
private SceneService sceneService;
@GetMapping("/getScenesInfo")
public ResModel getScenesInfo(@RequestParam String sessionId) {
SceneVO sceneVO = sceneService.getScenesInfo(sessionId);
return ResModel.ok(sceneVO);
}
}With this refactoring, the API returns a compact JSON where the session identifier appears only once, and each scene is represented as an element of sceneList, simplifying front‑end consumption.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Architecture Digest
Focusing on Java backend development, covering application architecture from top-tier internet companies (high availability, high performance, high stability), big data, machine learning, Java architecture, and other popular fields.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
