How to get primary keys after batch insert in MyBatis - 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.

Related

execute "insert" raw sql query with on conflict "ignore" replacing bulk create in django rest framework

This is the listserializer I am using to create multiple objects.
class listSerializer(serializers.ListSerializer):
def create(self, validated_data):
objs = [klass(**item) for item in validated_data]
return klass.objects.bulk_create(objs)
But bulk_create throws error for unique key error in postgres,So I need to execute this raw sql in same create function.I need help on translating validated_data to sql query.
insert into table (count,value,type,mark,created_at) values
(3,32,2,162,CURRENT_TIMESTAMP),
(4,33,1,162,CURRENT_TIMESTAMP),
(3,33,1,162,CURRENT_TIMESTAMP)
on CONFLICT do nothing
class listSerializer(serializers.ListSerializer):
def create(self, validated_data):
values = ''
for data in validated_data:
values+='('
for item in data.values():
values+=str(item)+','
values+='CURRENT_TIMESTAMP),'
cursor = connection.cursor()
cursor.execute("insert into table (count,value,type,mark,created_at) values "+values[:-1]+"
on conflict do nothing)

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?

MyBatis Batch Insert/Update Using Annotations

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.

EF 4.0 Entity does not pick up new values after insert (select entity after insert)

I am using Entity Framework 4.0 POCO entity
I have mapped custom stored procedure on insert
PROCEDURE [dbo].[usp_MyTable_Insert]
(
#Value1 char(1),
#Value2 varchar(5),
#Value3 varchar(20)
....
)
AS
BEGIN TRANSACTION
INSERT INTO "dbo"."MyTable"
(
"Value1",
"Value2",
"Value3"
)
VALUES
(
#Value1,
#Value2,
#Value3
)
DECLARE #Id int
--Get the latest Id.
SET #Id = ( SELECT CAST(##IDENTITY AS INT) )
--update the table with the some values
UPDATE "dbo"."MyTable"
SET Value3 = ( SELECT SomeTableColumn
FROM SomeTable
WHERE Something = Something
)
WHERE [Id] = #Id
COMMIT TRANSACTION
SELECT #Id AS "Id"
END
It is inserting entity into database and then updating some of the columns in database
then returning identity. All pretty simple.
public int InsertRecord(RecEntity recEntity)
{
context.AddObject("RecEntities", recEntity);
context.SaveChanges();
return recEntity.Id;
}
Method insert working well.
Then i need to update current entity with values which stored procedure inserted.
I have method in my repository to retrieve data
public RecEntity SingleRecEntity(Expression> where)
{
return context.RecEntities.Single(where);
}
When i am calling this method values values inserted by stored procedure doesn't come to entity.
id = repository.InsertRecord(recEntity);
recEntity = repository.SingleBrokerPreRegistration(x => x.Id == id); // new values didnt come here from database
I run the query generated by entity framework in query analyzer, it is returning all up to date values.
But fore some reason datacontext don't want to update this entity.
Probably there is should be some ways to change this.
May be some one may explain this behaviour.
Need help.
Try the Refresh method with the StoreWins parameter.
EF does not refresh the values in case there is already an attached object with Entity Key specified unless the Refresh method is not called explicitly
If you run .Load(Objects.MergeOption.OverwriteChanges) on the collection you'll get any newly added items. If you want the deleted items to be "refreshed" you'll need to detach the entities from the collection before running .Load
Putting it all together (sorry about the vb)
For Each child in Parent.ChildCollection.ToArray()
context.Detatch(child)
Next
Parent.ChildCollection.Load(Objects.MergeOption.OverwriteChanges)
This works for me, but if there's a more elegant way I'd love to see it!