Requête JPQL pour l'élément dans la liste stockée avec AttributeConverter
comme Tobias Liefke a suggéré ici , j'ai implémenté un AttributeConverter
pour stocker les valeurs list dans une colonne de chaîne simple séparée par des virgules.
Classe Convertisseur:
public class ListNumbersConverter implements AttributeConverter<List<Long>, String>
champ dans la classe D'entité:
@Column(name = "user_ids", nullable = false)
@Convert(converter = ListNumbersConverter.class)
private List<Long> userIds;
cela fonctionne bien mais je ne peux pas interroger les enregistrements pour des éléments de liste spécifiques. J'ai essayé d'utiliser l'opérateur IN
dans la requête JPQL comme ci-dessous:
? in userIds
avec ceci, je n'obtiens qu'un résultat si le paramètre input param est le premier élément de la valeur DB. e.g: valeur en DB est "1,2,3". Je suis capable de récupérer cet enregistrement si la valeur param d'entrée est 1 pour la requête mentionnée ci-dessus, mais pas capable de récupérer si la valeur est 2 ou 3. Comment dois-je écrire ma requête pour récupérer tous les enregistrements qui contiennent un élément spécifique?
ma base de données est MySQL.
1 réponses
Hibernate ne sais pas comment le convertisseur de cartes de la liste de la colonne. Il ne peut pas construire de mapping à partir du JPQL ? in userIds
vers le fragment SQL correspondant, car il aurait besoin de savoir comment votre convertisseur est implémenté.
mais vous pouvez toujours construire ce fragment SQL vous-même, par exemple:
WHERE concat(',', entity.userIds, ',') LIKE concat('%,', ?, ',%')
la première concat
est de s'assurer que l'expression correspond même à la première et à la dernière valeur de la liste (qui ne commencerait ou ne se terminerait pas avec le séparateur).
il y a d'autres fonctions spécifiques à la base de données qui pourraient être utilisées, mais cet exemple fonctionne sur tous les types de bases de données que je connais.
une autre remarque: vous ne devez pas essayer de joindre userIds
dans la requête - comme il est d'un de base type, même si c'est une liste. Voir le JavaDoc de @Convert
:
l'annotation convertie est utilisé pour spécifier la conversion d'un champ de Base ou propriété.
néanmoins Hibernate se plaindra si vous comparez directement votre attribut avec un littéral ( entity.userIds = '1'
) parce que le type de l'attribut ne correspond pas au type du littéral. Mais aussi longtemps que vous utilisez une fonction comme ci-dessus pour chaque côté de la comparaison, il ne me plaindrai pas.