mybatis will return a map that columnName is key,and columnValue as value.But the result map I want is that the key is the value of column 1, and the value is the
value of column 2.
I use this to map,and it did'n work,and throw TooManyResultsException.
<resultMap id="countMap" type="HashMap">
<result property="key" column="column1"/>
<result property="value" column="column2"/>
</resultMap>
Related
I am having a postgresql database. I am using liquibase to insert data into the tables in postgresql from CSV files.
Here I have table ABC with column of type SMALLINT.
CREATE TABLE ABC (
NAME VARCHAR(20),
REQUIRED SMALLINT DEFAULT 0,
SUMMARY VARCHAR(50)
);
My CSV
NAME,REQUIRED,SUMMARY
John,,Playing
I get the following error
liquibase.exception.DatabaseException: ERROR: syntax error at or near ","n
The changeset
<changeSet id="12345"
author="test" runOnChange="true">
<loadUpdateData
encoding="UTF-8"
file="/data/ABC.csv"
quotchar=""
separator=","
tableName="ABC">
<column name="NAME" type="STRING"/>
<column name="REQUIRED" type="NUMERIC"/>
<column name="SUMMARY" type="STRING"/>
</loadUpdateData>
</changeSet>
Can anyone please help here. Another question is , why is the default not working in this case ?
Required is defined as smallint - this means it can be any integer between -32768 and 32767 OR NULL.
NULLcan be inserted by
NAME,REQUIRED,SUMMARY
John,NULL,Playing
Something like '' can't be inserted into a int column. I assume [NULL] and empty(blank) is just a different rendering by different db tools.
Can I use Spring's JdbcTemplate to get a column value of a row just inserted?
E.g. the SQL looks so:
insert into table1 (name, age) values ('name', 20) returning name;
And I want to get the value of the name column.
The update() method returns the number of inserted rows only.
It looks like you can insert rows if you use JdbcTemplate.queryForObject() and the sql uses with ... as construct:
String sql="with result as (\n" +
"insert into table1 (name, age) values ('name', 20) returning name\n" +
")\n" +
"select name from result;";
String name = jdbcTemplate.queryForObject(sql, String.class);
Can MyBatis return a HashMap of results, instead of a List?
e.g. given a table:
foo | bar
1 | a
2 | b
and a query
SELECT foo, bar FROM foobar
Return a result of HashMap<String, String> map where map.get(1) == 'a', map.get(2) == 'b' etc?
I've tried variations on the following:
<resultMap id="hashMapResult" type="java.util.HashMap">
<id column="foo" />
<result property="bar" column="bar"/>
</resultMap>
<select id="personStatuses" resultMap="hashMapResult">
SELECT foo, bar FROM foobar
</select>
But just get the error: Expected one result (or null) to be returned by selectOne(), but found: ...
Where tables have primary keys, it would be more useful to be able to get the results as a Map of PK => row, than just a List of rows.
You have to pivot your table, let column foo's rows as column, Mybatis can not do this, but you can use sql to achieve this(here is a mysql solution):
select
max(case when foo = 1, then bar else null end) as `1`,
max(case when foo = 2, then bar else null end) as `2`
from foobar;
Use like below and your multiple results will be handled without any problem.
// in your mapper XML
<select id="personStatuses" resultType="java.util.HashMap" >
SELECT foo, bar FROM foobar
</select>
// From Java code - list of hashmaps
List<HashMap> personStatuses = yourMyBatisDao.personStatuses();
sysout(personStatuses);
Here is example table used for getting some basic operations with xml column in postgreSQL table.
DROP TABLE IF EXISTS temp1;
CREATE TABLE temp1(myindex serial PRIMARY KEY, description xml);
INSERT INTO temp1(description)
VALUES
('<?xml version="1.0" encoding="utf-8"?>
<setup xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<DATABASE>herdatabase</DATABASE>
<DBSERVER>127.0.0.1</DBSERVER>
<DBUSER>saly</DBUSER>
<DBPORT>5432</DBPORT>
</setup>'),
('<?xml version="1.0" encoding="utf-8"?>
<setup xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<DATABASE>mydatabase</DATABASE>
<DBSERVER>127.0.0.1</DBSERVER>
<DBUSER>john</DBUSER>
<DBPORT>4424</DBPORT>
</setup>');
I decided to use XML instead of hstore and JSON since I'm working in .NET where XML functions and serialization is well supported and I haven't much of such data so speed is not much important.
From here I try some basic queries to get data.
--1) That one work
SELECT xpath('/setup/DBPORT/text()', description) FROM temp1;
--2) That work but give two arrays with single value
-- How to get one array with 2 values like "{5432, 127.0.0.1}"
SELECT xpath('/setup/DBPORT/text()', description), xpath('/setup/DBSERVER/text()', description) FROM temp1;
--3) How to get description when condition is met?
-- Here I get ERROR: could not identify an equality operator for type xml
SELECT description FROM temp1 WHERE xpath('/setup/DBSERVER/text()', description) = '{127.0.0.1}';
--4) How to get all values when condition is met?
SELECT allvalues FROM temp1 WHERE xpath('/setup/DBUSER/text()', description) = 'john';
How to get working those queries which don't work?
2 - Use the XPath "or" operator, |, to select either a DBPORT or DBSERVER:
SELECT xpath('/setup/DBPORT/text()|/setup/DBSERVER/text()', description)
FROM temp1;
3 - The xpath() function returns an XML array which can be cast to a TEXT array for easier matching to other values:
SELECT description
FROM temp1
WHERE xpath('/setup/DBSERVER/text()', description)::TEXT[] = '{127.0.0.1}'::TEXT[];
4 - Similar to the previous, cast the XML array to a Text array to match to a value:
SELECT xpath('/setup/node()/text()', description)
FROM temp1
WHERE xpath('/setup/DBUSER/text()', description)::TEXT[] = '{john}'::TEXT[];
For the second, you have two arrays, so you can use array_cat():
SELECT array_cat(xpath('/setup/DBPORT/text()', description),
xpath('/setup/DBSERVER/text()', description))
FROM temp1;
For the third, you have one array of values (it's possible that your xpath matches multiple /setup/DBSERVER elements, thus the array type). This takes the first element from the array and casts to text so that you can compare to the string
SELECT description
FROM temp1
WHERE (xpath('/setup/DBSERVER/text()', description))[1]::text = '127.0.0.7';
Finally, you can use an xpath to generate an array of your elements, then unnest() them (so you get one row per element), then use another xpath to get at the element content. This gives the element content, but not the element name - I don't know the xpath to get the tag name off the top of my head.
SELECT xpath('/', unnest(xpath('/setup/*', description)))
FROM temp1
WHERE (xpath('/setup/DBUSER/text()', description))[1]::text = 'john';
I got error similar to this: Unitils dataset - insert into sybase datetime column
My case is that need to insert a date value that is empty. Empty String does not do the thing. Can anyone help me?
If you leave your date element off of the row definition, it won't add anything in that field. So with a table definition of:
CREATE TABLE Table (
id INTEGER,
name VARCHAR,
birthDate DATE
);
create a row like this:
<table id="3" name="Katie"/>
<table id="4" name="Christie" birthDate="2001-04-22"/>
to load an empty date in ID 3.