MyBatis vous permet de définir un Mapper avec des annotations au lieu de Mapper XML. Cette fois, je vais résumer comment utiliser l'annotation.
@Insert
, @Update
, @Select
, @Delete
Il peut être spécifié pour chaque méthode, et chacun correspond au SQL à exécuter.
Chaque annotation peut prendre une chaîne ou un tableau de chaînes comme argument et transmettre le SQL que vous souhaitez exécuter.
Si un tableau est spécifié, les chaînes de caractères seront combinées séparées par un espace demi-largeur.
Comme avec XML, vous pouvez incorporer des valeurs avec # {hoge}
, et si vous voulez profiter du SQL dynamique, vous devrez mettre le tout dans <script>
.
@Select("SELECT id, title FROM table WHERE id=#{id}")
Todo findById(Integer id);
@Select({
"<script>",
"SELECT id, title FROM table",
"<where>",
"<if test=\"id != null\">AND id=#{id}</if>",
"<if test=\"title != null\">AND title=#{title}</if>",
"</where>",
"</script>"
})
List<Hoge> find(@Param("id") Integer id, @Param("title") String title);
D'ailleurs, dans le cas de XML, l'attribut resultType
a été spécifié, mais il n'est pas nécessaire de le spécifier car le type de retour de la méthode est automatiquement appliqué.
@InsertProvider
, @UpdateProvider
, @SelectProvider
, @DeleteProvider
Il peut être spécifié pour une méthode, et chacun correspond au SQL à exécuter.
Pour chaque annotation, spécifiez l'objet de classe dans l'attribut type
et le nom de la méthode sous forme de chaîne de caractères dans l'attribut method
.
Exécute la chaîne retournée par les méthodes spécifiées par eux en tant que SQL.
La méthode de création de SQL peut être réalisée en construisant simplement une chaîne, mais elle peut également être construite à l'aide du générateur SQL fourni par MyBatis. Vous pouvez également utiliser la syntaxe de contrôle Java pour créer du SQL dynamique. http://www.mybatis.org/mybatis-3/ja/statement-builders.html
Vous pouvez définir la valeur directement dans SQL, mais il y a un risque d'injection, il est donc préférable d'utiliser le format # {hoge}
.
@SelectProvider(type = TodoSQLProvider.class, method = "select")
List<Todo> find2(@Param("id") Integer id, @Param("title") String title);
public class TodoSQLProvider {
public String select(@Param("id") Integer id, @Param("title") String title) {
return new SQL() {
{
SELECT("*");
FROM("todo");
if (id != null) {
WHERE("id = #{id}");
// WHERE("id = " + id);C'est un risque d'injection
}
if (title != null) {
WHERE("title = #{title}");
}
}
}.toString();
}
}
@Option
Vous pouvez définir les options suivantes qui peuvent être spécifiées pour la méthode, telles que «
useCache
flushCache
resultSetType
statementType
fetchSize
timeout
useGeneratedKeys
keyProperty
keyColumn
resultSets
@Results
, @Result
«@ Reuslts» correspond au XML «@ Results
peut être spécifié pour la méthode, et l'attribut ʻid spécifie une chaîne de caractères et l'attribut
value spécifie un tableau de
@ Result`.
@ Result
peut spécifier ʻid,
column,
property,
javaType,
jdbcType,
typeHandler, ʻone
, many
comme attributs.
Comme c'est presque le même que l'attribut qui peut être spécifié avec la balise `
attribut | La description |
---|---|
id |
Spécifiez comme valeur booléenne. Pour XML<result> Quand<id> J'avais l'habitude de spécifier correctement la clé primaire,@Result Utilisons cet attribut. |
one |
@One Spécifier.@One Est de XML<association> Correspond à. |
many |
@Many Est spécifié.@Many Est de XML<collection> Correspond à. |
@Select("SELECT id, title FROM todo")
@Results(id = "hoge", value = {
@Result(id = true, column = "id", property = "i"),
@Result(id = true, column = "title", property = "t"),
})
List<Hoge> findAll();
@Data
public class Hoge {
private Integer i;
private String t;
}
@One
, @Many
Comme mentionné ci-dessus, cela correspond à «
Pour fetchType
, spécifiez l'un des éléments FetchType.DEFAULT
, FetchType.EAGER
ou FetchType.LAZY
. Si spécifié, l'opération est la même que XML fetchType, elle est donc omise.
Pour select
, spécifiez le nom complet de la méthode Mapper. (Méthodes avec @ Select
et @ SelectProvider
)
Si vous spécifiez uniquement le nom de la méthode au lieu du nom complet comprenant le package, etc., vous spécifiez la méthode dans la même interface Mapper.
Le comportement est le même que lorsque l'attribut select est spécifié dans XML.
public interface TodoMapper {
@Select("SELECT * FROM todo WHERE id=#{id}")
@Results(id = "todo", value = {
@Result(column = "author", property = "author", one = @One(select = "com.example.mybatis.UsersMapper.findById", fetchType = FetchType.EAGER)) })
Todo findById(Integer id);
}
public interface UsersMapper {
@Select("SELECT * FROM users WHERE id=#{id}")
User findById(Integer id);
}
En XML, au lieu d'utiliser select, il était possible de joindre et d'obtenir les tables comme indiqué ci-dessous et d'utiliser le résultat pour le mappage.
<resultMap id="TodoMap" type="Todo">
<id column="todoId" property="id" />
<result column="title" property="title" />
<association property="author" javaType="User">
<id column="userId" property="id" />
<result column="name" property="name" />
</association>
</resultMap>
<select id="findById" resultMap="TodoMap">
SELECT t.id as todoId, t.title, u.id as userId, u.name FROM todo t, users u WHERE t.author = u.id
</select>
Cependant, @ One
et @ Many
ne peuvent pas réaliser la même chose que ci-dessus, et vous devez toujours exécuter une autre sélection.
Je n'aime pas le problème N + 1 avec la méthode de sélection, et je ne l'ai pas beaucoup utilisé personnellement, alors j'ai pensé que c'était un peu un inconvénient.
@ConstructorArgs
, @Arg
«@ ConstructorArgs» correspond au XML «
@ ConstructorArgs
peut spécifier un tableau de @ Arg
dans l'attribut value
.
@ Arg
peut spécifier ʻid,
column,
javaType,
jdbcType,
typeHandler,
select,
resultMap comme attributs. ʻId
est similaire à @ Result
, et vous devez spécifier true
pour la clé primaire.
En dehors de cela, c'est le même que les attributs qui peuvent être spécifiés dans la balise «
@Select("SELECT id, title FROM todo")
@ConstructorArgs({
@Arg(id = true, column = "id", name = "id"),
@Arg(id = true, column = "title", name = "title")
})
List<Todo> constructor();
@ResultMap
En spécifiant le «@ Results» «id» que vous voulez utiliser pour l'attribut «value», vous pouvez utiliser le «@ Results» défini ailleurs.
@Select("SELECT id, title FROM todo")
@Results(id = "hoge", value = {
@Result(id = true, column = "id", property = "i"),
@Result(id = true, column = "title", property = "t")
})
List<Hoge> findAll();
@Select("SELECT id, title FROM todo WHERE id=#{id}")
@ResultMap("hoge")
Hoge findBy(Integer id);
Si vous spécifiez au format «nom du package + nom de l'interface + valeur d'attribut id», vous pouvez également utiliser «@ Results» défini dans d'autres interfaces.
@MapKey
Ne peut être spécifié que pour les méthodes qui renvoient Map
.
Dans l'attribut value
, spécifiez la propriété clé de Map
.
@Select("SELECT id, title FROM todo")
@MapKey("id")
Map<Integer, Todo> map();
Par exemple, si les données avec id 1 et titre 1 et id 2 et titre 2 peuvent être obtenues, la carte sera comme suit.
{1=Todo(id=1, title=test1), 2=Todo(id=2, title=test2)}
@ResultType
La classe à mapper est obtenue à partir du type de retour.
Cependant, dans le cas d'une méthode qui utilise ResultHandler, la valeur de retour sera void
, spécifiez donc la classe à mapper par @ ResultType
.
@Select("SELECT id, title FROM todo")
@ResultType(Todo.class)
void handle(ResultHandler<Todo> handler);
Lorsque vous utilisez ResultHandler, vous pouvez également utiliser @ ResultMap
.
@SelectKey
Il est possible de réaliser la fonction équivalente à <selectKey> 'de XML. Vous pouvez spécifier
statement,
keyProperty,
keyColumn,
before,
resultType,
statementType` comme attributs.
Spécifiez une instruction SQL dans l'attribut «statement», où «before» correspond à «order» en XML. A part cela, c'est la même chose que pour XML.
Vous pouvez faire presque la même chose que XML, mais je pense que c'est le goulot d'étranglement car il existe des différences fonctionnelles entre «@ One» et «@ Many». Si vous souhaitez simplement exécuter rapidement du SQL simple, vous pouvez facilement le définir directement dans l'interface.
Certaines annotations n'ont pas encore été résumées, je voudrais donc les ajouter prochainement.
Recommended Posts