MyBatis - lists of primitive types - mybatis

This seems to have eluded me. I know I can use a map to return a vanilla set of rows from a myBatis query but how to do it with a list of primitive types?
e.g. If I had SQL like:
select product_price from products
Does this require a resultMap? I've tried to use java.util.ArrayList as the result type but get class not found errors.
In a similar vein, how do I pass a list of items as an argument to a query.
Any input, pointers to docs appreciated.

Just declare the resultType as the primitive type that you want, which in your case is a Long. It will be returned as a list.
<select id="getPrice" resultType="java.lang.Long">
select product_price from products
</select>
In the mapper interface you should expect to get back a list of Long.
List<Long> getPrice();

Try using below code snippet inside your resultmap for product_price column mapping -
<collection property="price" ofType="java.lang.Long">
<result property="price" column="product_price"/>
</collection>

try using resultMap
<resultMap type="java.lang.Long" id="domainsResult">
<result property="" column="product_price"/>
</resultMap>
<select id="getPrice" resultMap="domainsResult">
select product_price from products
</select>
It will give you a List priceList.

Trey this :
You will get it as a list of map if you write like this:
<select id="getPrice" resultType="Hashmap">
select product_price from products
</select>
Where the key will be column name. Each map will contain a single entry. If You want an ArrayList then you can write a function to convert this map to an ArrayList:
public List listFromListOfMap (List<Map> listOfMap ) {
List<Integer> prices = new ArrayLisyt<Integer>();
for(int i = 0; i < listOfMap.size(); i++) {
Integer value = (Integer)listOfMap.get(i).get("product_price");
prices.add(value);
}
return prices;
}
Hope this helps :)

Related

by use mybatis ,when the column name include dot notation, like this 'test.name' ,it will return nested Object,how to solve it?

his is my test sql:
<select id="getMap" resultType="java.util.LinkedHashMap">
select "test.name" from test where id = 1
</select>
java:
List<LinkedHashMap<String, String>> map = dataMapper.getMap();
log.info("{}", map);
output: [{test={name=628}}]
correct output should be: [{test.name=628}]
just like:mybatis autoMapping map and the column name has spot like this 'test.name' , the name will be split

In CrafterCMS, how can I query a model to get an array with all the fields in a repeated group?

In CrafterCMS, I have a component Team with a itemSelector field where I'm assigning some instances of another component TeamMember.
In the template of Team I'm using siteItemService.getSiteItem to get the model information of child components:
<#assign memberModel = siteItemService.getSiteItem(memberItem.storeUrl) />
Between the fields of type TeamMember I have:
Some fields of TeamMember
I'm able to get the value of skillTitle like this:
<#assign skillsTitle = memberModel.queryValue("//skillsTitle")!"" />
But I'm not able to get the value of the values in the repeating group.
I tried with:
<#assign skills = memberModel.queryValues("//skills")![] />
It returns an array of just one element, I think is an empty string
<#assign skills = memberModel.queryValues("//skills/item")![] />
It returns an array with the right number of elements, but I think all of them are empty strings
If I use:
<#assign skills = memberModel.queryValues("//skills/item/skillName")![] />
I get a correct array with all the skill names, but I need iterate over both values (skillName and skillLevel)
How can I query the model in order to get an array which elements have all the values in the repeated group?
Once you get the SiteItem with
<#assign memberModel = siteItemService.getSiteItem(memberItem.storeUrl) />
it works just like any other contentModel variable within a FreeMarker template. So, you can iterate it with
<#list memberModel.skills.item as skill>
${skill.skillName} = ${skill.skillLevel}
</#list>

Get HashMap as Result for select

Hi i want query database with myBatis and want return Map
I have daoInterface Like
public interface IDocDao extends IBasicDao {
public Map<Integer, Integer> getDocByA();
}
And mapper
<select id="getDocByA" resultMap="myHashMap">
SELECT b_id, count(1) AS count FROM table_a GROUP BY b_id
</select>
And need to return 1 map with all this values, not List of Maps
thx. Pavel
If you want to return a HashMap, you need to set it as a resultType, not as a resultMap. You don't need to define myHashMap, hashmap is enough.
<select id="getDocByA" resultType="hashmap">
SELECT b_id, count(1) AS count FROM table_a GROUP BY b_id
</select>
In your way, mybatis will return this:
[{b_id=b_id1, count=count1}, {b_id=b_id2, count=count2}]. So you need to define a list to receive this data, then you can convert it into a Map by additional code to loop the list.

Composite keys in MyBatis <collection> mappings

I am unable to pass a composite key to a MyBatis <collection> element (using version 3.2.7). The MyBatis documentation states:
Note: To deal with composite keys, you can specify multiple column names to pass to the nested select statement by using the syntax column="{prop1=col1,prop2=col2}". This will cause prop1 and prop2 to be set against the parameter object for the target nested select statement.
However, all my attempts to implement this produce the Exception
org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.reflection.ReflectionException: Error instantiating class java.lang.Integer with invalid types () or values (). Cause: java.lang.NoSuchMethodException: java.lang.Integer.<init>()
The collection (which resides in another ResultsMap) is:
<collection property="foos" ofType="FooObject"
column="{param1=user_id,param2=foo_id}" select="getFoosByUser" >
<id property="userId" column="user_id" />
<id property="foo" column="foo_id" />
<result property="fooName" column="foo_name" />
</collection>
It should return an ArrayList of Foo objects. The composite key is user_id and foo_id. The select query is:
<select id="getFoosByUser" parameterType="Integer" resultType="FooObject">
SELECT
user_id AS userId,
foo_id AS fooId,
foo_name AS fooName
FROM foo_table
WHERE user_id = #{param1}
AND foo_id = #{param2}
</select>
The query works correctly if I only use one parameter, e.g. removed foo_id=#{param2} and then use column=user_id in the collection, but I cannot work out how to structure the column attribute correctly for two keys. Any ideas?
MyBatis is confused by using parameterType when there are more than one parameter. Modify you query mapping like this:
<select id="getFoosByUser" resultType="FooObject">
SELECT
user_id AS userId,
foo_id AS fooId,
foo_name AS fooName
FROM foo_table
WHERE user_id = #{param1}
AND foo_id = #{param2}
</select>

How to make the myBatis select result(list) be set to object's property?

Generally, myBatis's select method returns single object or generic List types. for example, I want to fetch all students of a class:
<select id="fetchStudentsOfClass" parameterType="int" resultMap="resultMapStudent">
SELECT * FROM students WHERE class_id=#{id}
</select>
I can easily get a result like this: List<Student>.
Now, if I want to get the result like this rather than List<Student>:
class MyClass
{
List<Student> getStudents{return this.students;}
void setStudents(List<Student> students){this.students = students}
private List<Student> students;
}
how can I do?
This is what the <collection/> element is for. It's important that you properly mark both the container and the values with their <id/> so that MyBatis knows how to deal with collapsing multiple rows into one object.
<resultMap id="resultMapClass" type="some.package.MyClass" autoMapping="true">
<id property="classId" column="class_id" javaType="integer"/>
<collection property="students" ofType="some.package.Student" autoMapping="true">
<id property="studentId" column="student_id" javaType="integer"/>
</collection>
</resultMap>
<select id="fetchStudentsOfClass" parameterType="int" resultMap="resultMapClass">
SELECT *
FROM students
WHERE class_id = #{id}
</select>
See http://mybatis.github.io/mybatis-3/sqlmap-xml.html#Result_Maps for more details.