Pourquoi faut-il de l'interface et xml fichier mappeur être dans le même paquet et ont le même nom?
Aujourd'hui, j'ai préparé un exemple d'utilisation de Spring Boot, et à l'aide de MyBatis pour l'accès aux données de communication à côté de Printemps-MyBatis. Voici la configuration du projet (à l'aide de maven):
src/main/java
- edu.home.ltmj.controller
+ CategoryController.java
- edu.home.ltmj.dao
+ CategoryDao.java
- edu.home.ltmj.domain
+ Category.java
src/main/resources
- edu.home.ltmj.dao
+ CategoryMapper.xml
Contenu pertinent de fichiers:
CategoryDao.java:
package edu.home.ltmj.dao;
public interface CategoryDao {
List<Category> getAllCategories();
}
CategoryMapper.xml:
<mapper namespace="edu.home.ltmj.dao.CategoryDao">
<resultMap id="categoryMap"
type="edu.home.ltmj.domain.Category">
<id property="id" column="id" />
<result property="name" column="name" />
</resultMap>
<select id="getAllCategories" resultMap="categoryMap">
SELECT id, nombre
FROM category
</select>
</mapper>
Ensuite, j'ai injecter une instance de ce dao dans une demande de contrôleur (pour des fins de test), comme ceci:
package edu.home.ltmj.controller;
@RestController
public class CategoryController {
@Autowired
private CategoryDao dao;
@RequestMapping(value="/category/all",
method=RequestMethod.GET,
produces=MediaType.APPLICATION_JSON_VALUE)
public List<Categoria> getAllCategories() {
return dao.getAllCategories();
}
}
Je lance mon projet et de tester l'exécution à l'aide de curl localhost:8080/category/all
et ensuite s'attendre à voir les résultats au format JSON, mais j'ai eu cette exception au lieu:
org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): edu.home.ltmj.dao.CategoryDao.getAllCategories
at org.apache.ibatis.binding.MapperMethod$SqlCommand.<init>(MapperMethod.java:189)
at org.apache.ibatis.binding.MapperMethod.<init>(MapperMethod.java:43)
at org.apache.ibatis.binding.MapperProxy.cachedMapperMethod(MapperProxy.java:58)
at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:51)
at com.sun.proxy.$Proxy45.getAllCategories(Unknown Source)
at edu.home.ltmj.controller.CategoryRestController.getAllCategories(CategoryRestController.java:27)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
(...)
Je ne comprends pas la cause de cette. Il y a une interface CategoryDao
et il a la bonne méthode getAllCategories
qui correspond à <select id="getAllCategories">
. Après un certain temps de jouer avec cela, j'ai changé le nom de l'interface dao pour CategoryMapper
et mise à jour de l'espace de noms dans CategoryMapper.xml. Après je l'ai fait, tout a fonctionné normalement. Aussi, après avoir le même nom de la classe et le xml, j'ai déplacé la classe dao et le mapper de xml dans différents dossiers (stil en utilisant le même nom pour les deux: CategoryMapper.), mise à jour de l'espace de noms dans le fichier xml, et a obtenu la même exception, avec le message de mise à jour pour afficher le nom de l'ensemble de l'interface dao. Mais là encore, j'ai déplacé les deux fichiers dans le même package et tout a fonctionné à nouveau.
Donc, ma question est: pourquoi ne MyBatis besoin que l'interface et le mapper de xml fichier ayant le même nom et être dans le même paquet? Est-ce MyBatis de conception ou d'un problème au Printemps MyBatis?
OriginalL'auteur Luiggi Mendoza | 2015-05-15
Vous devez vous connecter pour publier un commentaire.
Avez-vous un MyBatis fichier de Config?
Si je me souviens bien le même nom même emplacement pour le fichier XML que l'interface est quand vous voulez avoir une installation qui fonctionne sans configuration supplémentaire.
Si vous avez le XML mappeurs de quelque part d'autre, vous pouvez spécifier manuellement le chemin des fichiers XML à l'aide d'un
<mappers>
élément à l'intérieur d' MyBatis de configuration.De la L'injection de Mappeurs de la documentation:
Donc, essayez ceci:
Créer un
mybatis-config.xml
fichier à l'intérieur desrc/main/resources
avec ça:Où
WhateverNameYouWant.xml
contient ce que votreCategoryMapper.xml
contenus.Définir l'emplacement du fichier de config (Java configuration comme ci-dessous ou haricot dans le
applicationContext
fichier):@MapperScan
et indiquer les paquets de base où MyBatis peut analyser tous les mappeurs par lui-même. Cette annotation fonctionne comme<mybatis:scan />
de scan automatique des fichiers et donc de ne pas utiliser<mappers/>
.regarde pour les interfaces. Voir mon edit pour la réponse.
Ce qui est intéressant. En fin de compte, c'est un MyBatis chose l'ensemble de la séparation des préoccupations entre l'interface et le mappeur, tandis que
@MapperScan
aide sur l'permettra à l'autowiring de haricots de la dao interfaces. Merci pour le lien vers la documentation et de l'exemple.OriginalL'auteur Bogdan
J'ai utilisé de la manière suivante sans @MapperScan comme suit :
1) le programme d'Installation mybatis-config.xml tout comme l'étape 2 ci-dessus
2) Le Programme D'Installation CategoryDao
3) le programme d'Installation à l'intérieur mybatis-config.xml
OriginalL'auteur Ian Lim