How do you map a List<string> in iBatis?
Asked Answered
Q

8

5

I have a class like this

public SomeClass
{
   private List<string> _strings = new List<string>();

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

How would I do the mapping for _strings?

I tried this, but it complains about the List typehandler not being found, which it doesn't complain about if I mapped it as an object.

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

So I searched Google and found this workaround (originally for a Java issue, no idea if it's suppose to work in C#)

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

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

This at least lets the test run, and it returns the rest of my object fine, and my list has the right number of entries, except they're all blank.

I think the problem is that the property attribute is blank, but I'm not sure whats suppose to go there. (I also tried using 'value', but that didn't work either). This seems like it should be a lot simpler and I'm just overlooking something obvious.

Thanks.

Quadrangle answered 14/7, 2009 at 20:56 Comment(2)
Is the list the only member of your class, or are there more members? What does the data in the database look like? I believe I've run into something similar, but I'd like to get more history first.Rudolfrudolfo
There are more members in the class, but they all function as I expect them to. It seems to be just the List<string> variables that I can't map.Quadrangle
Q
0

Since no solution was found I just went with a method I'm not particularly proud of.

I mapped a class that had no other property other than a string value.

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

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

iBatis seems to have no problem with that, just with mapping to a collection of strings.

Quadrangle answered 21/7, 2009 at 21:59 Comment(0)
F
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:

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

And then you can call it like this:

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

So you don't have to create a custom type with one property to do that.

Florrie answered 20/8, 2010 at 9:34 Comment(0)
P
4

My experience is the with Java version of iBATIS, but the solution should still work for the C# peeps out there.

Given a class

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

You can populate the list of strings or other simple types (classes without attributes, such as Integer, String, etc.) with the following two resultMaps

<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>

Hope this helps.

Plover answered 2/2, 2010 at 21:30 Comment(5)
This throws an exception when iBatis tries loading the <sqlMap> with the message There is no Set member named '' in class 'MyClass'. I guess in the .NET version every <result> needs the property attribute.Bosk
Hm... and adding property="someStrings" to your <result> didn't work, I assume? :(Plover
I confirm that this works in Java, thanks! Adding property="putSomethingHere" was the trick.Florey
Glad it finally helped someone!Plover
And--5 1/2 years later--it even helped me.Plover
M
1

At least in iBATIS3 for Java your above could just use a resultMap like:

<resultMap id="someClassMap" type="SomeClass"> 
    <collection property="Strings" ofType="String"/> 
</resultMap>
Mooring answered 3/9, 2009 at 17:47 Comment(0)
P
1

The following is my experience with Java version of IBatis (version 2.3.4). My scenario was I wanted Ibatis to return me a map of keys and values for a given list of parameters. Done using Ibatis queryForMap method to return a map where the key is an Object and the values are a collection of Objects (this example Key is a Wrapper while the values are a list of Wrapper Longs).

Create a placeholder (with the getters/setters) to hold the data when the query executes.

class PlaceHolder {
  private long elementId;;
  private List<Long> valueIds;
}

Ibatis resultmap definitions

<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>

My initial troubles was getting the alias' right and the groupBy syntax on the parent map. Having the groupBy will get Ibatis to get the same object for the elementId to populate the children. One instance without the groupBy I found that for each key the previous child added to the list was replaced by the latest child as a new list was initialized (note I have not had a peep at the internals of Ibatis yet as I write this example). The placeholders alias must match the parent and child's resultMap. Ibatis 3 seems to have better syntax to define and handle a scenario as above.

Phenyl answered 21/3, 2011 at 12:17 Comment(0)
D
1

if IBatis-3, just use below

<select id="getFilteredList" resultType="String"> your sql here</select>
Disputation answered 13/5, 2014 at 8:39 Comment(0)
Q
0

Since no solution was found I just went with a method I'm not particularly proud of.

I mapped a class that had no other property other than a string value.

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

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

iBatis seems to have no problem with that, just with mapping to a collection of strings.

Quadrangle answered 21/7, 2009 at 21:59 Comment(0)
B
0

you can just use 'System.String' or 'java.lang.String' as the property

Bootle answered 5/2, 2010 at 17:8 Comment(0)
C
0

This worked for me , got a list of strings from procedure output cursor

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>
Cabstand answered 6/2, 2017 at 22:29 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.