Wie der Titel schon sagt.
Mögliche Verwendungsszenarien sind beispielsweise wie folgt.
Betrachten Sie die folgende Tabelle als Beispiel.
Employee | Department | SubDepartment |
---|---|---|
id PK | id PK | employee_id FK |
name | name | department_id FK |
mail_address | ||
department_id FK | ||
department_name |
Entity(Paket weglassen und importieren)
//Mitarbeitereinheit
@Data
@AllArgsConstructor
@NoArgsConstructor
public class EmployeeEntity {
private int id;
private String name;
private String mailAddress;
private int departmentId;
private String departmentName;
//Gleichzeitige Organisation
private List<DepartmentEntity> subDepartments;
}
//Mitgliedsorganisation Entity
@Data
@AllArgsConstructor
@NoArgsConstructor
public class DepartmentEntity {
private int id;
private String name;
}
Wenn Sie die folgende Struktur erhalten möchten, ist es anscheinend nicht möglich, sie nur mit der Funktion von MyBatis auf einmal zu erhalten.
Erforderliche Struktur
{
"1" : {
"id" : 1,
"name" : "John",
"mailAddress" : "[email protected]",
"departmentId" : 1,
"departmentName" : "Planning",
"subDepartments" : [ ]
},
"2" : {
"id" : 2,
"name" : "Ken",
"mailAddress" : "[email protected]",
"departmentId" : 1,
"departmentName" : "Planning",
"subDepartments" : [ {
"id" : 2,
"name" : "Legal"
}, {
"id" : 3,
"name" : "Investor Relations"
} ]
}
}
Vermitteln Sie daher die MappingHelper-Klasse, damit die obige Struktur erhalten werden kann. Informationen werden aus der Datenbank als Liste von MappingHelper abgerufen und mit MappingHelper # toMap in Map konvertiert. Halten Sie die Schlüssel- und Wertdatentypen generisch, damit Sie sie beim Definieren der Schnittstelle für die von Ihnen ausgegebene Abfrage angeben können.
MappingHelper.java
package com.example.domain.model;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class MappingHelper<K, V> {
private K key;
private V value;
public static <K, V> Map<K, V> toMap(List<MappingHelper<K, V>> list) {
if (list == null) {
return Collections.emptyMap();
}
return list.parallelStream().collect(Collectors.toMap(MappingHelper::getKey, MappingHelper::getValue));
}
}
Verwenden Sie diese MappingHelper-Klasse, um den folgenden MyBatis-Mapper zu erstellen.
EmployeeRepository.java
package com.example.domain.repository;
import com.example.domain.model.EmployeeEntity;
import com.example.domain.model.MappingHelper;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
@Mapper
public interface EmployeeRepository {
List<MappingHelper<Integer, EmployeeEntity>> findAllByIds(@Param("ids") List<Integer> ids);
}
EmployeeRepository.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.example.domain.repository.EmployeeRepository">
<select id="findAllByIds" resultMap="employeeMapHelper">
SELECT
e.id employeeId,
e.name employeeName,
e.mail_address mailAddress,
d.id departmentId,
d.name departmentName,
sd.id subDepartmentId,
sd.name subDepartmentName
FROM
employee e
LEFT JOIN
department d
ON
e.department_id = d.id
LEFT JOIN (
SELECT
d2.id,
d2.name,
sd2.employee_id
FROM
sub_department sd2
INNER JOIN
department d2
ON
d2.id = sd2.department_id
WHERE
sd2.employee_id IN
<foreach collection="ids" item="id" open="(" close=")" separator=",">
#{id}
</foreach>
) sd
ON
e.id = sd.employee_id
WHERE
e.id IN
<foreach collection="ids" item="id" open="(" close=")" separator=",">
#{id}
</foreach>
</select>
<resultMap id="employeeMapHelper" type="MappingHelper">
<id property="key" column="employeeId" javaType="String"/>
<association property="value" resultMap="employeeMap"/>
</resultMap>
<resultMap id="employeeMap" type="EmployeeEntity">
<id property="id" column="employeeId"/>
<result property="name" column="employeeName"/>
<result property="mailAddress" column="mailAddress"/>
<result property="departmentId" column="departmentId"/>
<result property="departmentName" column="departmentName"/>
<collection property="subDepartments" ofType="DepartmentEntity">
<id property="id" column="subDepartmentId"/>
<result property="name" column="subDepartmentName"/>
</collection>
</resultMap>
</mapper>
Sie können die Zielstruktur erhalten, indem Sie die folgende Verarbeitung wie oben beschrieben ausführen.
SandboxRestController.java
package com.example.web;
import com.example.domain.model.EmployeeEntity;
import com.example.domain.model.MappingHelper;
import com.example.domain.repository.EmployeeRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@RestController
@RequiredArgsConstructor
public class SandboxRestController {
private final EmployeeRepository employeeRepository;
@RequestMapping("/mybatisToMap")
public ResponseEntity<Map> mybatisToMap() {
List<MappingHelper<Integer, EmployeeEntity>> mapperList = employeeRepository.findAllByIds(Arrays.asList(1, 2));
Map<Integer, EmployeeEntity> employeeMap = MappingHelper.toMap(mapperList);
return ResponseEntity.ok().body(employeeMap);
}
}
Mit den oben genannten Informationen können Sie mithilfe von MyBatis eine Karte mit dem Schlüssel als Kennung und dem Wert als Entität abrufen. Dies kann bei der Implementierung mit Java hilfreich sein, wenn eine Tabellenverknüpfung nicht möglich ist.
Beispielcode: https://github.com/tnemotox/sandbox Referenz: https://stackoverflow.com/questions/36400538/mybatis-resultmap-is-hashmapstring-object
Nachtrag: 18.6.14
Mit Java können Sie eine Liste erstellen und mit Stream Ihr Bestes geben, auch wenn Sie sich nicht die Mühe machen, mit MyBatis Ihr Bestes zu geben ... Es gibt Zeiten, in denen Sie eine Liste möchten, sodass Sie sie aus den Ergebnissen dieser Abfrage auf einmal erstellen können.
Von der Liste zur Karte mit Stream
Map<Integer, EmployeeEntity> employeeMap = employees.stream().collect(toMap(EmployeeEntity::getEmployeeId, e -> e, (e1, e2) -> e1);
Nun, es könnte nützlich sein ...
Recommended Posts