2017-06-29 81 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必須是公共的。