You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user-java@ibatis.apache.org by Ingmar Lötzsch <il...@asci-systemhaus.de> on 2009/02/04 09:59:27 UTC

Re: Insert help

Hello Rahul,

here an example for Date[]/date[]

> Can any one tell me how to use  typehandlercallback  implementation with 
>  sqlmap  while doing insert

public void insert(Planschichteinheit record)
{
	getSqlMapClientTemplate().insert("planschichteinheit.insert", record);
}

> and one more thing how would I map my array data type in my sqlmap

<insert id="insert" 
parameterClass="com.asci.nef.types.disposition.Planschichteinheit">
	INSERT INTO planschichteinheit
	(
		id,
		planschichtid,
		auftragstage
	)
	VALUES
	(
		#id:INTEGER#,
		#planschicht.id:INTEGER#,
		#auftragstage,handler=DateArrayTypeHandler#,
	)
</insert>

The same as with the <select>.

> I know I can map my class for int  but how I would do it for short array 
> which holds the different account numbers which a person holds
> 
> At my Backend AccountNumbers field map to varchar , so to overcome this 
> I can use custom TypeHandlerCallback implementation  but how would
> 
> Declare this in my sqlmap and I am not allowed to change my data type in DB.

<typeAlias alias="DateArrayTypeHandler" 
type="com.asci.common.ibatis.DateArrayTypeHandler" />
<typeAlias alias="BitNTypeHandler" 
type="com.asci.common.ibatis.BitNTypeHandler" />
<typeAlias alias="IntArrayTypeHandler" 
type="com.asci.common.ibatis.IntArrayTypeHandler" />
...

> Say I have following class
> 
> public class Person
> {
>       int age;
> 
>       short [] Accountnumbers;
> 
>       public short[] getAccountnumbers()
>       {
>             return Accountnumbers;
>       }
> 
>       public void setAccountnumbers(short[] accountnumbers)
>       {
>             Accountnumbers = accountnumbers;
>       }
> 
>       public int getAge()
>       {
>             return age;
>       }
> 
>       public void setAge(int age)
>       {
>             this.age = age;
>       }
> }

OK.

> import java.sql.SQLException;
> 
> import java.sql.Types;
> 
> import com.ibatis.sqlmap.client.extensions.ParameterSetter;
> import com.ibatis.sqlmap.client.extensions.ResultGetter;
> import com.ibatis.sqlmap.client.extensions.TypeHandlerCallback;
> 
> public class ArraysToStringTypeHandler implements TypeHandlerCallback
> {
>       public Object getResult(ResultGetter arg0) throws SQLException
>       {
>             return null;
>       }
> 
>       public void setParameter(ParameterSetter setter, Object 
> parameter) throws SQLException
>       {
>             if (parameter == null) {
>                   setter.setNull(Types./CHAR/);
>         } else {
>             setter.setString(ArraysToString( parameter));
>         }
>       }
> 
>       public Object valueOf(String arg0)
>       {
>             return null;
>       }
> 
>       private String ArraysToString(Object obj)
>       {
>             if (obj == null)
>             {
>                   throw new IllegalArgumentException ("Could not 
> convert null to a String value. " +
>                   "Valid argument is an array of type short Only ");
>             }
>             else if (obj instanceof short[])
>             {
>                   short[] ourData = (short []) obj;
>                   int length = ourData.length;
> 
>                   StringBuffer dataHolderSb = new StringBuffer();
>                   for (int i = 0; i < length; i++)
>                   {
>                         dataHolderSb.append(ourData[i]);
>                   }
> 
>                   return dataHolderSb.toString();
>             }
>             else {
>                   return null;     
>             }
>       }
> }

Dependend on your type of DBMS and its configuration you need to use an 
java.sql.Array implementation.

Here is an working example for int[] and PostgreSQL 8.1:

package com.asci.common.ibatis;

import java.sql.Array;
import java.sql.SQLException;
import java.util.Collection;

import com.asci.common.jdbc.IntArray;
import com.ibatis.sqlmap.client.extensions.ParameterSetter;
import com.ibatis.sqlmap.client.extensions.ResultGetter;
import com.ibatis.sqlmap.client.extensions.TypeHandlerCallback;

public class IntArrayTypeHandler
implements TypeHandlerCallback
{
	public void setParameter(ParameterSetter setter, Object parameter)
	throws SQLException
	{
		Collection<Integer> keys = (Collection<Integer>) parameter;
		IntArray intArray = new IntArray(keys);
		setter.setArray(intArray);
	}
	
	public Object getResult(ResultGetter getter)
	throws SQLException
	{
		Array array = getter.getArray();
		return array;
	}
	
	public Object valueOf(String string)
	{
		return string;
	}
}

package com.asci.common.jdbc;

import java.sql.SQLException;
import java.sql.Types;
import java.util.Collection;

public class IntArray
extends SqlArrayAdapter
{
	private static final Integer[] emptyArray = new Integer[0];
	
	private int[] array;
	
	public IntArray(int[] array)
	{
		if (array == null)
		{
			throw new IllegalArgumentException("parameter array should not be null");
		}
		this.array = array;
	}
	
	public IntArray(Collection<Integer> set)
	{
		if (set == null)
		{
			throw new IllegalArgumentException("parameter set should not be null");
		}
		Integer[] keys = set.toArray(emptyArray);

		this.array = new int[keys.length];
		for (int i = 0; i < keys.length; ++i)
		{
			Integer key = keys[i];
			this.array[i] = key.intValue();
		}
	}
	
	@Override
	public int getBaseType()
	throws SQLException
	{
		return Types.INTEGER;
	}

	/**
	 * This method is called by driver ver. 8 but not by ver. 7.
	 */
	@Override
	public String getBaseTypeName()
	throws SQLException
	{
		return "int4";
	}
	
	/**
	 * This method is called by both drivers ver. 8 and 7.
	 */
	@Override
	public String toString()
	{
		String result = "{";
		for (int i = 0; i < this.array.length; ++i)
		{
			if (i > 0)
			{
				result += ",";
			}
			result += this.array[i];
		}
		result += "}";
		return result;
	}
}

package com.asci.common.jdbc;

import java.sql.Array;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Map;

/**
  * Die Klasse implementiert java.sql.Array, so dass man in davon 
abgeleiteten Klassen nur die
  * benötigten Methoden überschreiben muss.
  *
  * @author IngmarL
  */
public abstract class SqlArrayAdapter
implements Array
{
	public Object getArray() throws SQLException
	{
		return null;
	}
	
	public Object getArray(long index, int count) throws SQLException
	{
		return null;
	}
	
	public Object getArray(long index, int count, Map<String, Class< ? >> 
map) throws SQLException
	{
		return null;
	}
	
	public Object getArray(Map<String, Class< ? >> map) throws SQLException
	{
		return null;
	}
	
	public int getBaseType() throws SQLException
	{
		return 0;
	}
	
	public String getBaseTypeName() throws SQLException
	{
		return null;
	}
	
	public ResultSet getResultSet() throws SQLException
	{
		return null;
	}
	
	public ResultSet getResultSet(long index, int count) throws SQLException
	{
		return null;
	}
	
	public ResultSet getResultSet(long index, int count, Map<String, Class< 
? >> map) throws SQLException
	{
		return null;
	}
	
	public ResultSet getResultSet(Map<String, Class< ? >> map) throws 
SQLException
	{
		return null;
	}
}

> <insert id="Person" parameterClass="com.foo.Contact">
>            insert into personTable (age,Accountnumbers)
>            values (#age #,#what to declare for short array here for 
> Accountnumber field, handler=ArraysToStringTypeHandler #)
> </insert>

You didn't show us the class Contact. If there is the same method 
getAccountnumbers() as in Person, write

values (#age#, #accountnumbers,handler=ArraysToStringTypeHandler#)

I didn't try, if the spaces are correct in

#age #

and

#accountnumbers, handler=ArraysToStringTypeHandler #

Ingmar

RE: Insert help

Posted by Rahul Saluja <ra...@vnl.in>.
Hello Ingmar,

Thanks for your timely help, finally it worked.

Regards
Rahul Saluja


-----Original Message-----
From: Ingmar Lötzsch [mailto:iloetzsch@asci-systemhaus.de]
Sent: Wednesday, February 04, 2009 3:05 PM
To: user-java@ibatis.apache.org
Subject: Re: Insert help

Hello Rahul,

> Really appreciate your response, Well I do need to bother you for one more thing if you could tell me where exactly do I need to insert the following statement (In my sqlmap-config.xml file or under my resource file).
>
> <typeAlias alias="DateArrayTypeHandler"
> type="com.asci.common.ibatis.DateArrayTypeHandler" /> <typeAlias alias="BitNTypeHandler"
> type="com.asci.common.ibatis.BitNTypeHandler" /> <typeAlias alias="IntArrayTypeHandler"
> type="com.asci.common.ibatis.IntArrayTypeHandler" />

I don't know, if it is possible to place this elements in the resource
files containing the SQL statements. I placed them in sqlmap-config.xml.

Ingmar
The information contained in this e-mail is private & confidential and may also be legally privileged. If you are not the intended recipient, please notify us, preferably by e-mail, and do not read, copy or disclose the contents of this message to anyone.

Re: Insert help

Posted by Ingmar Lötzsch <il...@asci-systemhaus.de>.
Hello Rahul,

> Really appreciate your response, Well I do need to bother you for one more thing if you could tell me where exactly do I need to insert the following statement (In my sqlmap-config.xml file or under my resource file).
> 
> <typeAlias alias="DateArrayTypeHandler"
> type="com.asci.common.ibatis.DateArrayTypeHandler" /> <typeAlias alias="BitNTypeHandler"
> type="com.asci.common.ibatis.BitNTypeHandler" /> <typeAlias alias="IntArrayTypeHandler"
> type="com.asci.common.ibatis.IntArrayTypeHandler" />

I don't know, if it is possible to place this elements in the resource 
files containing the SQL statements. I placed them in sqlmap-config.xml.

Ingmar

RE: Insert help

Posted by Rahul Saluja <ra...@vnl.in>.
Hello Ingmar,

Really appreciate your response, Well I do need to bother you for one more thing if you could tell me where exactly do I need to insert the following statement (In my sqlmap-config.xml file or under my resource file).

<typeAlias alias="DateArrayTypeHandler"
type="com.asci.common.ibatis.DateArrayTypeHandler" /> <typeAlias alias="BitNTypeHandler"
type="com.asci.common.ibatis.BitNTypeHandler" /> <typeAlias alias="IntArrayTypeHandler"
type="com.asci.common.ibatis.IntArrayTypeHandler" />


Once again appreciate your help.

Regards
Rahul Saluja



-----Original Message-----
From: Ingmar Lötzsch [mailto:iloetzsch@asci-systemhaus.de]
Sent: Wednesday, February 04, 2009 2:29 PM
To: user-java@ibatis.apache.org
Subject: Re: Insert help

Hello Rahul,

here an example for Date[]/date[]

> Can any one tell me how to use  typehandlercallback  implementation with
>  sqlmap  while doing insert

public void insert(Planschichteinheit record)
{
        getSqlMapClientTemplate().insert("planschichteinheit.insert", record);
}

> and one more thing how would I map my array data type in my sqlmap

<insert id="insert"
parameterClass="com.asci.nef.types.disposition.Planschichteinheit">
        INSERT INTO planschichteinheit
        (
                id,
                planschichtid,
                auftragstage
        )
        VALUES
        (
                #id:INTEGER#,
                #planschicht.id:INTEGER#,
                #auftragstage,handler=DateArrayTypeHandler#,
        )
</insert>

The same as with the <select>.

> I know I can map my class for int  but how I would do it for short array
> which holds the different account numbers which a person holds
>
> At my Backend AccountNumbers field map to varchar , so to overcome this
> I can use custom TypeHandlerCallback implementation  but how would
>
> Declare this in my sqlmap and I am not allowed to change my data type in DB.

<typeAlias alias="DateArrayTypeHandler"
type="com.asci.common.ibatis.DateArrayTypeHandler" />
<typeAlias alias="BitNTypeHandler"
type="com.asci.common.ibatis.BitNTypeHandler" />
<typeAlias alias="IntArrayTypeHandler"
type="com.asci.common.ibatis.IntArrayTypeHandler" />
...

> Say I have following class
>
> public class Person
> {
>       int age;
>
>       short [] Accountnumbers;
>
>       public short[] getAccountnumbers()
>       {
>             return Accountnumbers;
>       }
>
>       public void setAccountnumbers(short[] accountnumbers)
>       {
>             Accountnumbers = accountnumbers;
>       }
>
>       public int getAge()
>       {
>             return age;
>       }
>
>       public void setAge(int age)
>       {
>             this.age = age;
>       }
> }

OK.

> import java.sql.SQLException;
>
> import java.sql.Types;
>
> import com.ibatis.sqlmap.client.extensions.ParameterSetter;
> import com.ibatis.sqlmap.client.extensions.ResultGetter;
> import com.ibatis.sqlmap.client.extensions.TypeHandlerCallback;
>
> public class ArraysToStringTypeHandler implements TypeHandlerCallback
> {
>       public Object getResult(ResultGetter arg0) throws SQLException
>       {
>             return null;
>       }
>
>       public void setParameter(ParameterSetter setter, Object
> parameter) throws SQLException
>       {
>             if (parameter == null) {
>                   setter.setNull(Types./CHAR/);
>         } else {
>             setter.setString(ArraysToString( parameter));
>         }
>       }
>
>       public Object valueOf(String arg0)
>       {
>             return null;
>       }
>
>       private String ArraysToString(Object obj)
>       {
>             if (obj == null)
>             {
>                   throw new IllegalArgumentException ("Could not
> convert null to a String value. " +
>                   "Valid argument is an array of type short Only ");
>             }
>             else if (obj instanceof short[])
>             {
>                   short[] ourData = (short []) obj;
>                   int length = ourData.length;
>
>                   StringBuffer dataHolderSb = new StringBuffer();
>                   for (int i = 0; i < length; i++)
>                   {
>                         dataHolderSb.append(ourData[i]);
>                   }
>
>                   return dataHolderSb.toString();
>             }
>             else {
>                   return null;
>             }
>       }
> }

Dependend on your type of DBMS and its configuration you need to use an
java.sql.Array implementation.

Here is an working example for int[] and PostgreSQL 8.1:

package com.asci.common.ibatis;

import java.sql.Array;
import java.sql.SQLException;
import java.util.Collection;

import com.asci.common.jdbc.IntArray;
import com.ibatis.sqlmap.client.extensions.ParameterSetter;
import com.ibatis.sqlmap.client.extensions.ResultGetter;
import com.ibatis.sqlmap.client.extensions.TypeHandlerCallback;

public class IntArrayTypeHandler
implements TypeHandlerCallback
{
        public void setParameter(ParameterSetter setter, Object parameter)
        throws SQLException
        {
                Collection<Integer> keys = (Collection<Integer>) parameter;
                IntArray intArray = new IntArray(keys);
                setter.setArray(intArray);
        }

        public Object getResult(ResultGetter getter)
        throws SQLException
        {
                Array array = getter.getArray();
                return array;
        }

        public Object valueOf(String string)
        {
                return string;
        }
}

package com.asci.common.jdbc;

import java.sql.SQLException;
import java.sql.Types;
import java.util.Collection;

public class IntArray
extends SqlArrayAdapter
{
        private static final Integer[] emptyArray = new Integer[0];

        private int[] array;

        public IntArray(int[] array)
        {
                if (array == null)
                {
                        throw new IllegalArgumentException("parameter array should not be null");
                }
                this.array = array;
        }

        public IntArray(Collection<Integer> set)
        {
                if (set == null)
                {
                        throw new IllegalArgumentException("parameter set should not be null");
                }
                Integer[] keys = set.toArray(emptyArray);

                this.array = new int[keys.length];
                for (int i = 0; i < keys.length; ++i)
                {
                        Integer key = keys[i];
                        this.array[i] = key.intValue();
                }
        }

        @Override
        public int getBaseType()
        throws SQLException
        {
                return Types.INTEGER;
        }

        /**
         * This method is called by driver ver. 8 but not by ver. 7.
         */
        @Override
        public String getBaseTypeName()
        throws SQLException
        {
                return "int4";
        }

        /**
         * This method is called by both drivers ver. 8 and 7.
         */
        @Override
        public String toString()
        {
                String result = "{";
                for (int i = 0; i < this.array.length; ++i)
                {
                        if (i > 0)
                        {
                                result += ",";
                        }
                        result += this.array[i];
                }
                result += "}";
                return result;
        }
}

package com.asci.common.jdbc;

import java.sql.Array;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Map;

/**
  * Die Klasse implementiert java.sql.Array, so dass man in davon
abgeleiteten Klassen nur die
  * benötigten Methoden überschreiben muss.
  *
  * @author IngmarL
  */
public abstract class SqlArrayAdapter
implements Array
{
        public Object getArray() throws SQLException
        {
                return null;
        }

        public Object getArray(long index, int count) throws SQLException
        {
                return null;
        }

        public Object getArray(long index, int count, Map<String, Class< ? >>
map) throws SQLException
        {
                return null;
        }

        public Object getArray(Map<String, Class< ? >> map) throws SQLException
        {
                return null;
        }

        public int getBaseType() throws SQLException
        {
                return 0;
        }

        public String getBaseTypeName() throws SQLException
        {
                return null;
        }

        public ResultSet getResultSet() throws SQLException
        {
                return null;
        }

        public ResultSet getResultSet(long index, int count) throws SQLException
        {
                return null;
        }

        public ResultSet getResultSet(long index, int count, Map<String, Class<
? >> map) throws SQLException
        {
                return null;
        }

        public ResultSet getResultSet(Map<String, Class< ? >> map) throws
SQLException
        {
                return null;
        }
}

> <insert id="Person" parameterClass="com.foo.Contact">
>            insert into personTable (age,Accountnumbers)
>            values (#age #,#what to declare for short array here for
> Accountnumber field, handler=ArraysToStringTypeHandler #)
> </insert>

You didn't show us the class Contact. If there is the same method
getAccountnumbers() as in Person, write

values (#age#, #accountnumbers,handler=ArraysToStringTypeHandler#)

I didn't try, if the spaces are correct in

#age #

and

#accountnumbers, handler=ArraysToStringTypeHandler #

Ingmar
The information contained in this e-mail is private & confidential and may also be legally privileged. If you are not the intended recipient, please notify us, preferably by e-mail, and do not read, copy or disclose the contents of this message to anyone.