2017-06-29 128 views
0

我想用的MyBatis 3 我写了这个映射inperface来检索PotgreSQL数据库中的数据:MyBatis的返回一个列表,并且不希望返回一个对象

package datamodel.gis.building; 
public interface BuildingMapperBatis 
{ 
    // List of objects within rectangular box 
    public List<BuildingDbDto> getByBBox(@Param("lat1") BigDecimal lat1, 
              @Param("lon1") BigDecimal lon1, 
              @Param("lat2") BigDecimal lat2, 
              @Param("lon2") BigDecimal lon2); 

    // Retrieve the object by id 
    public BuildingDbDto getById(@Param("id") Long id); 
    /// public List<BuildingDbDto> getById(@Param("id") Long id); 
} 

类BuildingDbDto是一个平凡的DTO对象与私人领域,公共getter,没有setter和一个构造函数初始化所有的领域。

一块MyBatis的XML配置的是:

<configuration> 
    <typeAliases> 
     <typeAlias alias="Building" type="datamodel.gis.building.BuildingDbDto" /> 
    </typeAliases> 
    <environments default="default">...here is the connection specified...</environments> 
    <mappers> 
     <mapper resource="datamodel/gis/building/BuildingMapperBatis.xml" /> 
    </mappers> 
</configuration> 

文件 “/src/main/resources/datamodel/gis/building/BuildingMapperBatis.xml” 在映射器的XML配置是:

<?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="datamodel.gis.building.BuildingMapperBatis"> 
    <resultMap id="BuildingMap" type="Building" > 
     <id column="bld_id" property="id" /> 
     <result column="bld_geo_latitude" property="latitude" /> 
     <result column="bld_geo_longitude" property="longitude" /> 
     <result column="bld_addr_settlement_name" property="addrSettlementName" /> 
    </resultMap> 

    <select id="getByBBox" resultMap="BuildingMap"> 
     SELECT bld_id, bld_geo_latitude, bld_geo_longitude, bld_addr_settlement_name 
     FROM get_buildings_in_bbox(#{lat1}, #{lon1}, #{lat2}, #{lon2}) 
    </select> 

    <!-- <select id="getById" resultMap="Building"> --> 
    <select id="getById" resultType="Building"> 
     SELECT bld_id, bld_geo_latitude, bld_geo_longitude, bld_addr_settlement_name 
     FROM get_buildings_in_bbox(0,0,90,90) 
     WHERE bld_id = #{id} 
    </select> 
</mapper> 

然后我执行查询:

BuildingMapperBatis mapper = sessionFactory.openSession().getMapper(BuildingMapperBatis.class); 
List<BuildingDbDto> found = mapper.getByBBox(lat1, lon1, lat2, lon2); 
BuildingDbDto dto = mapper.getById(id); 
/*/// 
BuildingDbDto dto = mapper.getById(id).get(0); 
*/ 

的方法getByBBox确实工作。

getById抛出该异常在生产线的方法, “.getById(ID);”: “java.lang.IllegalAccessError:试图从类com.sun.proxy访问类datamodel.gis.building.BuildingDbDto $ Proxy0 at com.sun.proxy。$ Proxy0.getById(Unknown Source)“ 我试过了resultType =”Building“和resultMap =”Building“,结果是一样的。

我试图用代码行代替注释掉的代码。我将getById的结果类型更改为一个列表,并将列表的第0个元素。 在此变体中,代码正常工作。但我不喜欢这种转换,因为按id搜索总是只返回一个(或没有)对象。

如何让该方法返回单个对象而不是列表?

+0

您是否试图在您的'getById'查询中指定'LIMIT 1'? – esin88

+0

是的,但这并没有帮助。查询是正确的,它总是返回一个记录,因为它通过主键搜索数据。 – Pokvalitov

+0

尝试将'getById'设置为'resultMap =“BuildingMap”'..找不到其他看起来不寻常的东西 – esin88

回答

0

我找到了我的问题的解决方案,所以我回答我的问题。

异常的原因是我没有将BuildingDbDto声明为公共类。我想将DTO从业务层隐藏起来并使其受到封装保护。我的意图是将DTO转换为同一包中的buisness实体(包含数据获取器和业务逻辑方法),并使buisness实体公开。

不幸的是,MyBatis里面的魔法必须有一个对返回值类的访问,所以DTO必须是公共的。

相关问题