如何在 iBatis 中映射一个 List<string>?

5
我有一个类似这样的类
public SomeClass
{
   private List<string> _strings = new List<string>();

   public IEnumerable<string> Strings
   {
      {  get return _strings; }
   }
}

我该如何为_strings做映射?

我尝试了这个方法,但它会抱怨找不到List类型处理程序,如果我将其映射为对象,则不会出现此问题。

<result property="_strings" column="value" />

所以我在谷歌上搜索并找到了这个解决方法(原本是针对Java问题的,不确定它是否适用于C#)

<result property="_strings" resultMapping="someMapping.StringList"/>

<resultMap id="StringList" class="System.String">
  <result property="" column="Value"/>
</resultMap>

至少这样可以让测试运行,并且它可以正常返回我的对象的其余部分,而我的列表中有正确数量的条目,只是它们全部都是空白的。

我认为问题在于属性属性为空,但我不确定应该放什么。 (我也尝试使用'value',但那也不起作用)。 这似乎应该简单得多,我只是忽视了一些明显的东西。

谢谢。


列表是你的类唯一的成员,还是还有其他成员?数据库中的数据是什么样子的?我相信我遇到过类似的问题,但我想先了解更多历史记录。 - Spencer Kormos
班级中有更多的成员,但他们都按照我的预期发挥作用。似乎只是无法映射 List<string> 类型的变量。 - Brandon
8个回答

5

Use auto result-mapping of IBatis. This is the solution in Java which you can easily map to C#. This is your sql map:

<code><sqlMap namespace="Users"></code>
<code><select id="names" resultClass="java.lang.String"></code>
        select first_name as firstName from user
<code></select></code>
<code><sqlMap></code>

And then you can call it like this:

List<code><String></code> userNames = (List<code><String></code>)sqlMap.queryForList("Users.names");

因此,您不必创建一个只有一个属性的自定义类型来实现这一点。

4

我有Java版本的iBATIS的经验,但是这个解决方案对于使用C#的人也适用。

假设有一个类

class MyClass {
  int id;
  List<String> firstName;
}

您可以使用以下两个resultMaps来填充字符串或其他简单类型(没有属性的类,如Integer、String等)的列表

<sqlMap namespace="ns">
  <resultMap id="ListMap" class="string">
    <result property="firstName" column="firstName" 
            javaType="java.util.List" jdbcType="VARCHAR"/>
  </resultMap>

  <resultMap id="PrimaryMap" class="MyClass" groupBy="id">
    <result property="id" columnName="id"/>
    <result property="firstname" resultMap="ns.ListMap" javaType="java.util.List"/>
  </resultMap>

  <select id="MySuperQuery" resultMap="PrimaryMap">
    select id, firstName from user
  </select>
</sqlMap>

希望这能帮到你。

当iBatis尝试加载<sqlMap>时,会抛出一个异常,其中包含消息“在'MyClass'类中没有名为''的Set成员”。我猜在.NET版本中,每个<result>都需要属性属性。 - Tinister
嗯...将property="someStrings"添加到您的<result>中没有起作用,我猜想是吗?:( - inanutshellus
我确认这在Java中可行,谢谢!添加 property="putSomethingHere" 是关键。 - Chris
很高兴它终于帮助到了某个人! - inanutshellus
1
五年半后,它甚至帮助了我。 - inanutshellus

1
以下是我使用Java版本的IBatis(版本2.3.4)的经验。我的场景是我想让Ibatis为给定的参数列表返回一个键值对映射的Map。使用Ibatis queryForMap方法返回一个Map,其中键是一个Object,值是一个对象集合(此示例中Key是一个Wrapper,而值是一个Wrapper Longs列表)。
创建一个占位符(带有getter/setter)来保存查询执行时的数据。
class PlaceHolder {
  private long elementId;;
  private List<Long> valueIds;
}

Ibatis结果映射定义

<resultMap id="valueIdsMap" class="java.lang.Long">
    <result property="valueIds" column="otherId" javaType="java.util.List" jdbcType="NUMERIC"/>
</resultMap>

<resultMap id="testKeysAndValuesMap" groupBy="elementId" class="PlaceHolder">
    <result property="elementId" column="elementId" jdbcType="NUMERIC" javaType="java.lang.Long"/>
  <result property="valueIds" resultMap="MapName.valueIdsMap" javaType="java.util.List" />
</resultMap>

<select id="retrieveTestKeysAndValuesMap" resultMap="testKeysAndValuesMap" 
        parameterClass="java.util.List">
    SELECT
    table_name_1.column_fk as elementId,
    table_name_1.id as otherId
    FROM table_name_1
    WHERE table_name_1.column_fk IN
        <iterate open="(" close=")" conjunction=", ">
            #[]#
        </iterate>

我的初始问题是正确设置别名和父映射中的groupBy语法。使用groupBy将使Ibatis获取相同的对象以填充子元素的elementId。如果没有groupBy,我发现对于每个键,列表中添加的前一个子项将被最新的子项替换,因为新列表被初始化(请注意,我在编写此示例时还没有查看Ibatis的内部)。占位符别名必须与父级和子级的resultMap匹配。Ibatis 3似乎有更好的语法来定义和处理上述情况。


1

至少在Java的iBATIS3中,您可以使用resultMap来实现上述功能:

<resultMap id="someClassMap" type="SomeClass"> 
    <collection property="Strings" ofType="String"/> 
</resultMap>

1
如果使用的是IBatis-3,只需使用以下内容。
<select id="getFilteredList" resultType="String"> your sql here</select>

0

由于没有找到解决方案,我只能采用一种我并不特别自豪的方法。

我映射了一个除字符串值之外没有其他属性的类。

public class StringValue
{
    public String Name { get; set; }
}

<resultMap id="StringList" class="StringValue" >
  <result property="Name" column="Value"/>
</resultMap>

iBatis似乎对此没有问题,只是在映射到字符串集合时出现了问题。


0

你可以直接使用 'System.String' 或者 'java.lang.String' 作为属性


0

这对我有用,从过程输出光标中获取了一个字符串列表

List ss = sqlmap.queryList(..

<resultMap id="emailsMap" class="java.lang.String">
        <result  column="E_MAIL" property="" /> 
</resultMap>

<parameterMap id="xp" class="java.util.Map">
    <parameter property="dd" jdbcType="VARCHAR" mode="IN" />
    <parameter property="outPutCursor" javaType="java.sql.ResultSet" jdbcType="ORACLECURSOR"  mode="OUT" />
    </parameterMap>
    enter code here

<procedure id="xx" parameterMap="xp" resultMap="emailsMap">
        { call aaa.bbb(?, ?) }
</procedure>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接