Отобразить перечисление в JPA с фиксированными значениями?

Вы можете изменить свой дочерний компонент следующим образом, поскольку text является массивом, поэтому вам необходимо получить доступ к его значениям по индексу.

const Child = ({ text, title }) => {
  return (
    <div>
      {text.map((text,index) => {
        return (
          <div>
            <h3>{title[index]}</h3>
            <p>{text}</p>
          </div>
        );
      })}
    </div>
  );
};

Вы даже можете изменить свой родительский компонент на что-то вроде этого

import Child from "../components/child";

const ComponentA = () => {
  <Layout>
    <h1>Home Page</h1>
    {info.text.map((text,index)=> <Child title={info.title[index]} text={text} />}
  </Layout>
}

const info = {
  title: ["Title1", "Title2"],
  text: ["Paragraph1", "Paragraph2"]
};

И тогда ваш ребенок должен быть

const Child = ({ text, title }) => {
  return (
    <div>
          <h3>{title}</h3>
          <p>{text}</p>
    </div>
  );
};
180
задан Arjan Tijms 24 June 2013 в 19:56
поделиться

2 ответа

Для версий, более ранних, чем JPA 2.1, JPA предоставляет только два способа борьбы с перечислениями: по их name или по их ordinal. А стандартный JPA не поддерживает пользовательские типы. Итак:

  • Если вы хотите выполнять пользовательские преобразования типов, вам придется использовать расширение поставщика (с Hibernate UserType, EclipseLink Converter и т. Д.). (второе решение). ~or~
  • Вам придется использовать @PrePersist и @PostLoad трюк (первое решение). ~or~
  • Annotate getter и setter, принимающие и возвращающие значение int ~or~
  • Используйте целочисленный атрибут на уровне сущности и выполняйте перевод в getters и setters.

Я проиллюстрирую последний вариант (это базовая реализация, настройте ее по мере необходимости):

@Entity
@Table(name = "AUTHORITY_")
public class Authority implements Serializable {

    public enum Right {
        READ(100), WRITE(200), EDITOR (300);

        private int value;

        Right(int value) { this.value = value; }    

        public int getValue() { return value; }

        public static Right parse(int id) {
            Right right = null; // Default
            for (Right item : Right.values()) {
                if (item.getValue()==id) {
                    right = item;
                    break;
                }
            }
            return right;
        }

    };

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "AUTHORITY_ID")
    private Long id;

    @Column(name = "RIGHT_ID")
    private int rightId;

    public Right getRight () {
        return Right.parse(this.rightId);
    }

    public void setRight(Right right) {
        this.rightId = right.getValue();
    }

}
163
ответ дан 23 November 2019 в 06:14
поделиться

Мое собственное решение решить этот вид Перечислимого отображения JPA следующее.

Шаг 1 - Запись следующий интерфейс, который мы будем использовать для всех перечислений, которые мы хотим отобразить на столбец дб:

public interface IDbValue<T extends java.io.Serializable> {

    T getDbVal();

}

Шаг 2 - Реализация пользовательский универсальный преобразователь JPA следующим образом:

import javax.persistence.AttributeConverter;

public abstract class EnumDbValueConverter<T extends java.io.Serializable, E extends Enum<E> & IDbValue<T>>
        implements AttributeConverter<E, T> {

    private final Class<E> clazz;

    public EnumDbValueConverter(Class<E> clazz){
        this.clazz = clazz;
    }

    @Override
    public T convertToDatabaseColumn(E attribute) {
        if (attribute == null) {
            return null;
        }
        return attribute.getDbVal();
    }

    @Override
    public E convertToEntityAttribute(T dbData) {
        if (dbData == null) {
            return null;
        }
        for (E e : clazz.getEnumConstants()) {
            if (dbData.equals(e.getDbVal())) {
                return e;
            }
        }
        // handle error as you prefer, for example, using slf4j:
        // log.error("Unable to convert {} to enum {}.", dbData, clazz.getCanonicalName());
        return null;
    }

}

Этот класс преобразует перечисление значений E в поле базы данных типа T (например, String) при помощи getDbVal() на перечислении E, и наоборот.

Шаг 3 - Позволил исходному перечислению реализовать интерфейс, который мы определили на шаге 1:

public enum Right implements IDbValue<Integer> {
    READ(100), WRITE(200), EDITOR (300);

    private final Integer dbVal;

    private Right(Integer dbVal) {
        this.dbVal = dbVal;
    }

    @Override
    public Integer getDbVal() {
        return dbVal;
    }
}

Шаг 4 - Расширяют преобразователь шага 2 для Right перечисление шага 3:

public class RightConverter extends EnumDbValueConverter<Integer, Right> {
    public RightConverter() {
        super(Right.class);
    }
}

Шаг 5 - заключительный шаг должен аннотировать поле в объекте следующим образом:

@Column(name = "RIGHT")
@Convert(converter = RightConverter.class)
private Right right;

Заключение

, по моему скромному мнению, это - самое чистое и самое изящное решение, если у Вас есть много перечислений для отображения, и Вы хотите использовать конкретное поле самого перечисления как отображающий значение.

Для всех перечислений других в Вашем проекте, которым нужна подобная логика отображения, только необходимо повторить шаги 3 - 5, который является:

  • реализуют интерфейс IDbValue на Вашем перечислении;
  • расширяются EnumDbValueConverter только с 3 строками кода (можно также сделать это в объекте, чтобы не создавать разделенный класс);
  • аннотируют перечислимый атрибут [1 113] от [1 114] пакет.

Hope это помогает.

0
ответ дан 23 November 2019 в 06:14
поделиться
Другие вопросы по тегам:

Похожие вопросы: