Machen Sie die Variable, in der die ID gespeichert ist, zu einem ID-Typ anstelle von int / long (Java).

Überblick

Wenn Sie eine ID mit sich führen, wird diese normalerweise in int, long, String usw. gespeichert. In diesem Fall kann sie jedoch verwirrt und in den folgenden Fällen schwer verständlich werden.

public someMethod(int hogeId, int fugaId) { ... }

Wenn Sie dies tun können, können Sie unachtsame Fehler vermeiden. (Wenn Sie es chiguhagu machen, wird die IDE Sie als Fehler anzeigen.)

public someMethod(HogeId hogeId, FugaId fugaId) { ... }

Aufmerksamkeitspunkt

Dies ist zwar leichter zu verstehen, es sind jedoch einige Punkte zu beachten.

  1. Jackson kann von / nach JSON konvertieren
  2. Was kann als Parameter / Ergebnis in MyBatis behandelt werden?
  3. Kann als URL-Parameter von Spring MVC oder als Rückgabewert von "@ RestController" behandelt werden
  4. Da viele ID-Klassen erstellt werden, ist keine problematische Beschreibung einzeln erforderlich (lassen Sie die übergeordnete Klasse sie implementieren).
  5. Die Leistung wird nicht beeinträchtigt

Fazit

Dies kann wie folgt realisiert werden.

PiyoId.java


package your.package;

import your.package.LongId;
import lombok.EqualsAndHashCode;

@EqualsAndHashCode(callSuper = true)
class PiyoId extends LongId {
    public PiyoId(String id) { super(id); }
    public PiyoId(long id) { super(id); }
}

LongId.java


package your.package;

import com.fasterxml.jackson.annotation.JsonValue;
import lombok.EqualsAndHashCode;

@EqualsAndHashCode
public abstract class LongId {
    private final long id;

    public LongId(String id) {
        this.id = Long.parseLong(id);
    }

    public LongIdBase(long id) {
        this.id = id;
    }

    @JsonValue
    public long getId() {
        return this.id;
    }

    public String toString() {
        return this.getClass().getSimpleName() + "(" + this.id + ")";
    }
}

LongIdTypeHandler.java


package your.package;

import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import your.package.HogeId;
import your.package.LongId;
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.MappedTypes;

//Listen Sie hier die ID-Klassen auf
@MappedTypes(value = {HogeId.class})
public class LongIdTypeHandler<E extends LongId> extends BaseTypeHandler<E> {
    private final Class<E> type;

    public LongIdTypeHandler(Class<E> type) {
        if (type == null) throw new IllegalArgumentException("Type argument cannot be null");
        this.type = type;
    }

    private E createInstance(boolean wasNull, long id) {
        if (wasNull) {
            return null;
        }
        try {
            return type.getDeclaredConstructor(long.class).newInstance(id);
        } catch (InstantiationException | IllegalAccessException | NoSuchMethodException | InvocationTargetException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public void setNonNullParameter(PreparedStatement ps, int num, E parameter, JdbcType jdbcType) throws SQLException {
        long id = rs.getLong(columnName);
        return createInstance(rs.wasNull(), id);
    }

    @Override
    public E getNullableResult(ResultSet rs, String columnName) throws SQLException {
        long id = rs.getLong(columnName);
        return createInstance(rs.wasNull(), id);
    }

    @Override
    public E getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
        long id = rs.getLong(columnIndex);
        return createInstance(rs.wasNull(), id);
    }

    @Override
    public E getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
        long id = cs.getLong(columnIndex);
        return createInstance(cs.wasNull(), id);
    }
}

Einzelheiten

Jackson kompatibel

Um nahtlos konvertieren zu können, muss es eine der folgenden sein:

Konvertierung in JSON-> Objekt

Einer der folgenden:

  1. Standardkonstruktor + Setter
  2. Konstruktor mit @ JsonCreator
  3. Konstruktor mit übereinstimmenden Argumenten

Objekt-> In JSON konvertieren

Einer der folgenden: 4. Urteil von Getter 5. Führen Sie die Methode mit @ JsonValue aus

Fazit

Entsprechen 3 und 5

Unterstützt MyBatis

Das Objekt kann jetzt als MyBatis-Parameter übergeben werden

Beide der folgenden Punkte müssen angesprochen werden:

1. Wenn die ID-Klasse ein Parameter ist
2. Beim Empfang einer Klasse, die die ID-Klasse als Argument kennzeichnet

Es funktioniert nicht mit selectKey


<insert id="insert" parameterType="your.package.Hoge">
  INSERT INTO hoges (value1, value2)
  VALUES (#{value1}, #{value2})
  <selectKey resultType="your.package.HogeId" keyProperty="id" order="AFTER">
    select @@IDENTITY
  </selectKey>
</insert>

UseGeneratedKeys funktioniert


<insert id="insert" parameterType="your.package.Hoge" useGeneratedKeys="true" keyProperty="id">
  INSERT INTO hoges (value1, value2)
  VALUES (#{value1}, #{value2})
</insert>

Federkompatibel

Feder MVC Controller Parameter

Spring MVC @ RestController Rückgabewert

Die Leistung wird nicht beeinträchtigt

Verifizierungs-Schlüssel


//Schreiben Sie später

Recommended Posts

Machen Sie die Variable, in der die ID gespeichert ist, zu einem ID-Typ anstelle von int / long (Java).
Vergleichen Sie Elemente eines Arrays (Java)
[Java] So konvertieren Sie ein Element eines Array vom Typ String in einen Int-Typ
[Java] Achten Sie auf den Schlüsseltyp der Karte
Bitte beachten Sie die Aufteilung (Aufteilung) von Java Kotlin Int und Int
Ein Programm (Java), das die Summe von ungeraden und geraden Zahlen in einem Array ausgibt
(Ruby on Rails6) Anzeige der Datenbank, die die ID der Datenbank erhalten hat
[Java] [Java EE] [Glassfish] (Fortsetzung) Stil, der den Cache von Glassfish bezweifelt
Initialisierung mit einer leeren Zeichenfolge für eine Instanz vom Typ Java-Zeichenfolge
[Java] Um die Typinformationen der Typparameter zur Laufzeit zu kennen
[Java] Unterschied zwischen der Zuweisung der Basistypvariablen und der Zuordnung der Referenztypvariablen