MyBatis 3 - Spring MVC. Type interface is not know

2019-09-07 16:36发布

问题:

I don't know the problem here. The other mappers works, but this don't. The excepcion is thrown when I try get the Mapper: session.getMapper(ModeloDAO.class). Maybe is an error with byte[] field or with . I've try without association and byte[] field, but the problem persist.

Model:

@Alias("Modelo")
public class Modelo {

    private int id;
    private String nombre;
    private String estado;
    private Date fechaCreacion;
    private Date creadoPor;
    private byte[] foto;
    private Marca marca;

    public Modelo() {

    }

    public Modelo(String nombre, String estado, Date fechaCreacion, Date creadoPor,
                    byte[] foto, Marca marca) {
        super();
        this.nombre = nombre;
        this.estado = estado;
        this.fechaCreacion = fechaCreacion;
        this.creadoPor = creadoPor;
        this.foto = foto;
        this.marca = marca;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getNombre() {
        return nombre;
    }

    public void setNombre(String nombre) {
        this.nombre = nombre;
    }

    public String getEstado() {
        return estado;
    }

    public void setEstado(String estado) {
        this.estado = estado;
    }

    public Date getFechaCreacion() {
        return fechaCreacion;
    }

    public void setFechaCreacion(Date fechaCreacion) {
        this.fechaCreacion = fechaCreacion;
    }

    public Date getCreadoPor() {
        return creadoPor;
    }

    public void setCreadoPor(Date creadoPor) {
        this.creadoPor = creadoPor;
    }

    public byte[] getFoto() {
        return foto;
    }

    public void setFoto(byte[] foto) {
        this.foto = foto;
    }

    public Marca getMarca() {
        return marca;
    }

    public void setMarca(Marca marca) {
        this.marca = marca;
    }

}

Mapper:

<?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.acme.repository.ModeloDAO">
    <resultMap id="modeloResult" type="Modelo">
        <id property="id" column="modelo_id" />
        <result property="nombre" column="nombre" />
        <result property="estado" column="estado" />
        <result property="foto" column="foto" javaType="_byte[]" jdbcType="BLOB" />
        <result property="fechaCreacion" column="fecha_creacion" />
        <result property="creadoPor" column="creado_por" />
        <association property="marca" column="marca_id" javaType="Marca">
            <id property="id" column="marca_id" />
            <result property="nombre" column="nombre" />
            <result property="estado" column="estado" />
            <result property="fechaCreacion" column="fecha_creacion" />
            <result property="creadoPor" column="creado_por" />
        </association>
    </resultMap>

    <select id="list" resultMap="modeloResult">
        select
                    modelos.modelo_id,
                    modelos.nombre,
                    modelos.estado,
                    modelos.foto,
                    modelos.fecha_creacion,
                    marcas.marca_id,
                    marcas.nombre as nombreM,
                    marcas.estado,
                    marcas.fecha_creacion

            from 
                modelos,marcas
            where
                modelos.marca_id=marcas.marca_id;
    </select>

    <select id="searchById" resultMap="modeloResult" parameterType="int">
        select * from modelos where modelo_id = #{id}
    </select>

    <select id="searchByMarca" resultMap="modeloResult" parameterType="int">
        select * from modelos where marca_id = #{marcaId}
    </select>

    <insert id="save" parameterType="Modelo">
        insert into modelos(nombre, creado_por, foto) values(#{nombre}, #{creadoPor}, #{foto})
    </insert>

    <update id="update" parameterType="Modelo">
        update modelos set nombre = #{nombre}, foto = #{foto} where modelo_id = #{id}
    </update>

    <update id="delete" parameterType="int">
        update modelos set estado = 'INACTIVO' where modelo_id = #{id}
    </update>
</mapper>

DAO:

public interface ModeloDAO {

    List<Modelo> list();
    Modelo searchById(int id);
    List<Modelo> searchByMarca(int marcaId);
    void save(Modelo m);
    void update(Modelo m);
    void delete(int id);
}

Configuration:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <settings>
        <setting name="logImpl" value="LOG4J"/>
    </settings>
    <typeAliases>
        <package name="com.acme.model"/>
    </typeAliases>
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/test"/>
                <property name="username" value="root"/>
                <property name="password" value="12345"/>
            </dataSource>
        </environment>
    </environments>

    <mappers>
        <mapper resource="mybatis/mapper/MarcaMapper.xml" />
        <mapper resource="mybatis/mapper/ModeloMapper.xml" />
    </mappers>
</configuration>

Stack trace:

org.apache.ibatis.binding.BindingException: Type interface com.acme.repository.ModeloDAO is not known to the MapperRegistry.
    org.apache.ibatis.binding.MapperRegistry.getMapper(MapperRegistry.java:47)
    org.apache.ibatis.session.Configuration.getMapper(Configuration.java:675)
    org.apache.ibatis.session.defaults.DefaultSqlSession.getMapper(DefaultSqlSession.java:250)
    com.acme.repository.ModeloDAOImpl.list(ModeloDAOImpl.java:22)
    com.acme.service.ModeloService.list(ModeloService.java:20)
    com.acme.controller.ModeloController.list(ModeloController.java:22)
    sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    java.lang.reflect.Method.invoke(Unknown Source)
    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:111)
    org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:806)
    org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:729)
    org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
    org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:959)
    org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:893)
    org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)
    org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:861)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:622)
    org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
    org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)

回答1:

from the MapperRegistry source code:

public <T> T getMapper(Class<T> type, SqlSession sqlSession) {
        MapperProxyFactory mapperProxyFactory = (MapperProxyFactory)this.knownMappers.get(type);
        if(mapperProxyFactory == null) {
            throw new BindingException("Type " + type + " is not known to the MapperRegistry.");
        } else {
            try {
                return mapperProxyFactory.newInstance(sqlSession);
            } catch (Exception var5) {
                throw new BindingException("Error getting mapper instance. Cause: " + var5, var5);
            }
        }
    }

it seems that your mapper class wasn't registered by mybatis. please check your ModeloDAO 's package is com.acme.repository or you should add mapper manually:

session.getConfiguration().addMapper(ModeloDAO.class)

it seems that the ModeloDAOImpl cause the problem,if you choose to use mapper class, then you don't need to write the implementation of the mapper, mybatis will generate it for you.



回答2:

In your mapper.xml file mapper's namespace should be the path to the mapper interface.

for example:

<mapper namespace="com.app.mapper.LineMapper">
<select id="selectLine" resultType="com.jiaotong114.jiaotong.beans.Line">
select * from bus_line where id = #{id}
</select>
</mapper>

Your mapper interface should be in com.app.mapper package and the name of it is LineMapper.