Voici la trace de la pile lorsque j'essaie d'exécuter une requête simple à l'aide de MyBatis:
org.Apache.ibatis.binding.BindingException: Invalid bound statement (not found): com.my.package.persistence.BrandMapper.getBrand
org.Apache.ibatis.binding.MapperMethod$SqlCommand.<init>(MapperMethod.Java:189)
org.Apache.ibatis.binding.MapperMethod.<init>(MapperMethod.Java:43)
org.Apache.ibatis.binding.MapperProxy.cachedMapperMethod(MapperProxy.Java:58)
org.Apache.ibatis.binding.MapperProxy.invoke(MapperProxy.Java:51)
com.Sun.proxy.$Proxy25.getBrand(Unknown Source)
com.my.package.service.BrandService.getBrand(BrandService.Java:18)
com.my.package.service.BrandService$$FastClassBySpringCGLIB$$1140c60a.invoke(<generated>)
org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.Java:204)
org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.Java:649)
com.my.package.service.BrandService$$EnhancerBySpringCGLIB$$ea6f89cd.getBrand(<generated>)
com.my.package.controller.HomeController.getBrands(HomeController.Java:28)
Sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
Sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.Java:62)
Sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.Java:43)
Java.lang.reflect.Method.invoke(Method.Java:483)
org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.Java:221)
org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.Java:137)
org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.Java:110)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.Java:777)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.Java:706)
org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.Java:85)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.Java:943)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.Java:877)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.Java:966)
org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.Java:857)
javax.servlet.http.HttpServlet.service(HttpServlet.Java:622)
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.Java:842)
javax.servlet.http.HttpServlet.service(HttpServlet.Java:729)
org.Apache.Tomcat.websocket.server.WsFilter.doFilter(WsFilter.Java:52)
J'utilise la syntaxe Javaconfig au lieu de la configuration XML. Voici mon PersistenceConfig:
@Configuration
@EnableTransactionManagement
@MapperScan("com.my.package.persistence")
public class PersistenceConfig {
@Bean
public DataSource dataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
try {
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl("jdbc:mysql//localhost:3306/db");
dataSource.setUsername("dbuser");
dataSource.setPassword("dbpassword");
} catch (Exception e) {
System.out.print(e);
}
return dataSource;
}
@Bean
public DataSourceTransactionManager transactionManager() {
return new DataSourceTransactionManager(dataSource());
}
@Bean
public SqlSessionFactoryBean sqlSessionFactory() throws Exception {
SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
sessionFactory.setDataSource(dataSource());
sessionFactory.setTypeAliasesPackage("com.my.package.domain");
return sessionFactory;
}
}
Voici mon contrôleur:
@Controller
public class HomeController {
private static Logger logger = LoggerFactory.getLogger(HomeController.class);
@Autowired
private BrandService brandService;
@RequestMapping(value = "/", method = RequestMethod.GET)
public String index() {
return "index";
}
@RequestMapping(value = "/brands", method = RequestMethod.GET)
public String getBrands(Model model) {
model.addAttribute("brands",brandService.getBrand(1));
return "brands";
}
}
Voici mon interface Brand Mapper:
public interface BrandMapper {
Brand getBrand(int id);
Brand getBrandByName(String name);
List<Brand> getBrandList();
void addBrand(Brand brand);
void updateBrand(Brand brand);
void deleteBrand(int id);
}
Voici mon XML BrandMapper:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.my.package.persistence.BrandMapper">
<select id="getBrand" resultType="Brand" parameterType="int">
SELECT id, name
FROM brand
WHERE id = #{id};
</select>
<select id="getBrandByName" resultType="Brand" parameterType="String">
SELECT id, name
FROM brand
WHERE name = #{name};
</select>
<select id="getBrandList" resultType="Brand">
SELECT id, name
FROM brand;
</select>
<insert id="addBrand" parameterType="Brand">
INSERT INTO brand (id, name)
VALUE (#{id}, #{name})
</insert>
<update id="updateBrand" parameterType="Brand">
UPDATE brand
SET
name = #{name}
where id = #{id}
</update>
<delete id="deleteBrand" parameterType="int">
DELETE FROM brand
WHERE id = #{id}
</delete>
</mapper>
J'ai fait des recherches, mais aucune des solutions n'a fonctionné pour moi. Les fichiers My XML Mapper sont situés sous les ressources dans un package nommé "com.my.package.persistence".
Est-ce que quelqu'un a une idée de ce qui ne va pas ici?
Merci d'avance
Essayez de vérifier le fichier mybatis-conf.xml (quel que soit le nom de votre fichier appelé) et voyez si vous avez votre mappeur xml comme ceci:
<mappers>
<mapper resource="BrandMapper.xml">
<mappers>
Si vous aviez exécuté le JUNIT du code de service de base de données, cela aurait fonctionné. Par conséquent, je crois que c’est le probmlem lorsqu’un fichier WAR est généré. À partir de votre configuration, Mapper.Java et * Mapper.xml indiquent le même emplacement. Ainsi, lorsque war est géréné, le chemin du dossier pour les fichiers Java et xml serait WEB-INF/classes/com/my/package/persistence
. Cependant, le fichier * .xml n'est pas copié à l'emplacement. Une solution consiste à configurer votre script de construction de manière à copier les fichiers xml également ou autrement (ce que je préférerais) pour créer un répertoire sqlmap dans le répertoire resources et copier tous les fichiers mappeur xml dans le répertoire et pointer vers l'emplacement du fichier mapper à l'aide de sessionFactory.setMapperLocations
et une fois war le fichier est généré, assurez-vous que le répertoire sqlmap est présent dans le répertoire WEB-INF/classes
Message d'erreur :
org.Apache.ibatis.binding.BindingException: Invalid bound statement (not found):
Très probablement en raison d'un mauvais mappeur Syntaxe de requête . J'ai eu ce problème plusieurs fois et chaque fois que l'erreur est causée par une syntaxe incorrecte de la requête écrite dans le fichier mapper xml et les fichiers d'interface. Je vous suggère de
J'ai eu ce message d'erreur exact, s'est avéré être le chemin de l'espace de noms dans le fichier mappeur xml, j'avais changé le nom du paquet dans le fichier d'interface Java mais j'ai oublié de mettre à jour le nom du paquet dans le mappeur xml, un peu étrange. Mis à jour l'espace de noms du paquet et hop!
Vous devez indiquer les emplacements du mappeur lors de l’initialisation de sqlSessionFactory:
@Autowired
private ResourceLoader resourceLoader;
@Bean
public SqlSessionFactoryBean sqlSessionFactory() throws Exception {
SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
sessionFactory.setDataSource(dataSource());
//sessionFactory.setTypeAliasesPackage("com.my.package.domain");
sessionFactory.setMapperLocations(ResourcePatternUtils.getResourcePatternResolver(resourceLoader).
getResources("classpath:path/to/mappers/*.xml"));
return sessionFactory;
}
Dans votre cas, remplacez "classpath: chemin/vers/mappers/*. Xml" avec classpath: com/mon/package/persistence/*. Xml
J'espère que ceci vous aidera.
Votre fichier de mappeur doit figurer dans le même package que le fichier * Repo.Java. Vérifiez également l'espace de noms du mappeur.
Supprimez le ;
de la requête:
<select id="getBrand" resultType="Brand" parameterType="int">
SELECT id, name
FROM brand
WHERE id = #{id}
</select>
Je suppose que vous avez peut-être besoin d'un @Alias annotation:
@Alias ("Marque") Classe Brand { ... }
c'est la première chose qui me vient à l'esprit, espérons que cela aide!