[JAVA] Verwenden Sie MyBatis, um eine Karte mit einem Schlüssel als Kennung und einem Wert als Entität abzurufen

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

Verwenden Sie MyBatis, um eine Karte mit einem Schlüssel als Kennung und einem Wert als Entität abzurufen
Verwendung von MyBatis2 (iBatis) mit Spring Boot 1.4 (Spring 4)
Versuchen Sie, den API-Schlüssel von Redmine mit Ruby zu erhalten
Verwendung von Map
Verwendung von Map
So fügen Sie mit CircleCI ein weiteres Projekt als Maven-Bibliothek hinzu und verwenden es zum Erstellen
Mit Podman im Docker möchte jeder miteinander auskommen und Docker mit einem gemeinsam genutzten Computer verwenden
So führen Sie JUnit im Batch aus und erhalten Abdeckung
[Spring Boot] Ich möchte meine eigene Eigenschaftendatei hinzufügen und den Wert mit env.getProperty () abrufen.
Verwendung des Zertifikats und des privaten Schlüssels, die durch die BASIC-Authentifizierung von Docker mit AWS ALB erstellt wurden
[Java] Verwendung von Map
Verwenden Sie den schnellen Filter und die Karte
Verwendung von Java Map
So erhalten Sie die ID des automatisch inkrementierten PRIMAY-Schlüssels in MyBatis
So erhalten Sie den Wert von Boolean mit jQuery in einfacher Rails-Form