MyBatis Batch Insert/Update Using Annotations - mybatis

Please let me know, how to perform batch insert/update in mybatis using annotated mappers.

you can do it like this:
#Insert({
"<script>",
"insert into mybatis_demo (name, age)",
"values ",
"<foreach collection='dmoList' item='dmo' separator=','>",
"( #{dmo.name,jdbcType=VARCHAR}, #{dmo.age,jdbcType=INTEGER})",
"</foreach>",
"</script>"
})
int insertBatch(#Param("dmoList") List<MybatisDemoDMO> dmoList);

do in simple way
#Insert({"<script>",
"insert into user_master (first_name,last_name) values ",
"<foreach collection='userList' item='user' index='index' open='(' separator = '),(' close=')' >#{user.first_name},#{user.last_name}</foreach>",
"</script>"})
int insertUserList(#Param("userList") List<UserNew> userList);
It's work perfect for me and i inserted bulk record in my PostgreSQL database using above single insert.

Related

Calling StoredProcedure using JPA in Spring Boot

I am trying to call a stored procedure, which is built in mysql, in my Spring boot app using JPA. My stored procedure returns the result which cant be contain in single model as it fetches data from combination of tables.
I can do this with "call " but i guess that is not JPA's way. COuld you please let me know what is the best way to do it?
In case you're using plain JPA you need to do a native query call. Something like below.
Query q = em.createNativeQuery("select my_store_pro(?, ?)");
List<Object[]> results = q.getResultList();
for (Object[] a : results) {
System.out.println("result " + a[0] + " " + a[1]);
}
If you're using Spring Data repositories then you want something like below.
#Query(nativeQuery = true, value = "select my_store_pro(?, ?)")
Date callMyStoreProc(int val1, int val2);

Injecting JSON parameter in nativeQuery of Spring JPA

I have a table with a JSONB column. In my project I am using Spring JPA and to query that column I want to use nativeQuery. My problem is to inject varibale into the query like below:
#Query(nativeQuery = true, value = "SELECT * FROM items WHERE item_json -> 'attributes' #> '{\"Param1\": \"" + :param + "\"}' ")
List<Items> findByParameter(#Param("param") String param);
The above query does not work as param is not considered as JPA parameter. I am wondering if anyone knows how to do this? or I should do it in another way?

Spring Data JPA-Retrieve generated id when using native sql insert

I have the following native sql insert query when using Spring Data JPA:
#Modifying
#Query(value = "insert into marker(name, event_id, position, tag_ids, gmt_create, gmt_modified)" +
" values(?#{#m.name}, ?#{#m.eventId}, ST_GeomFromText(?#{#m.position})" +
", ?#{#m.tagIds}, ?#{#m.gmtCreate}, ?#{#m.gmtModified})"
, nativeQuery = true)
Marker save(#Param(value = "m") Marker marker);
The question is how to get the auto generated id? Thank you so much!

How to get primary keys after batch insert in MyBatis

use annotation #Options(useGeneratedKeys = true, keyProperty = "id") to get the generated primary key for single insert is fine for me , but when I use annotation #InsertProvider to make a batch insert , I have no idea how to get the generated primary keys , any comments will be appreciated . thx in advance
Now Mybatis 3.3.1 had supported it. Please see https://github.com/mybatis/mybatis-3/pull/547
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Options;
import org.apache.ibatis.annotations.Param;
public interface TestMapper {
...
#Options(useGeneratedKeys = true, keyProperty = "id", keyColumn = "id")
#Insert({
"<script>",
"INSERT INTO test_table",
"(column_one, column_two)",
"VALUES" +
"<foreach item='item' collection='list' open='' separator=',' close=''>" +
"(" +
"#{item.columnOne,jdbcType=VARCHAR},",
"#{item.columnTwo,jdbcType=VARCHAR}" +
")" +
"</foreach>",
"</script>"})
void insertBatchTestTable(#Param("list") List<TestObject> testObjs);
}
ps.:
Set keyColumn and keyProperty
Use #Param("list")
MyBatis will set objects keyProperty by reflection
I haven't used annotations with mybatis, only xml. But, I have used both useGeneratedKeys and batch insert, together.
With Mybatis, you have to execute the same query ( One with useGeneratedKeys ) and call the insert repeatedly for each object in your collection. This will map the generated key to your pojo. Flush the session after every N records, and commit.
That's it. I hope you are not using Oracle as your DB. As, with Oracle you'll have to flush after call to insert, which beats to purpose of batch.

Inserting multiple values into table with anorm

I want to insert multiple values into a table from a SQL query in Anorm. In the following snippet, is there a way to bind a list of usernames as values instead of just one username?
SQL("insert into users (username) " +
"values ({username})").on(
'username -> username,
).executeUpdate()
As an alternative, I can create a concatenated string from my inputs, but that's prone to SQL injection and isn't quite as clean.
A possible way to insert multiple values at once, using Anorm:
var fields: List[String] = Nil
var values: List[(String,ParameterValue[_])] = Nil
for ((username,i) <- usernames.zipWithIndex) {
fields ::= "({username%s})".format(i)
values ::= ("username" + i, username)
}
SQL("INSERT INTO users (username) VALUES %s".format(fields.mkString(",")))
.on(values: _*)
.executeUpdate()
You're wanting to repeat the insert command for all of the values?
How about wrapping it in a foreach:
usernames.foreach(username =>
SQL("insert into users (username) " +
"values ({username})").on(
'username -> username,
).executeUpdate())
Or something of that sort.
Anorm is a relatively simple library--check out the code here:
https://github.com/playframework/Play20/tree/master/framework/src/anorm/src/main/scala/anorm