I'm using Mybatis 3.2, Orace 12c for my project. I used code generator to generate insert() method. In the <insert> tag it has schema name; for ex:
insert into CPORTAL.CARD_USER_MASTER
Now, the schema is dynamic, so I put the parameter to change the schema:
insert into ${schema}.CARD_USER_MASTER
Parameter schema is defined in mapper.java as
insert(CardUserMaster record, #Param("schema") String schema)
However, without that schema, insert works but when has schema, error happen:
org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.binding.BindingException: Parameter 'carduserSeqno' not found. Available parameters are [0, schema, param1, param2]
In other class I set schema parameter like that on insert method and it works. Don't know what happen to this class.
Any comments will be appreciated.
Thanks.
Change it to
insert(#Param("entity") CardUserMaster record, #Param("schema") String schema)
and use the params as entity.carduserSeqno in the SQL.
Looks like it cannot recognize that 0 parameter is POJO. Without the #Param("schema") it uses pojo fields directly as params btu with adding the schema param it cannot.
Related
I am trying to create an annotated insert statement using MyBatis where the type handler is specified in an annotation.
For example, in a select query we can specify the typehandler like this:
#Results({
#Result(column = "strings", property = "strings", typeHandler = StringArrayTypeHandler.class)
})
#Select("SELECT * FROM ${name} ORDER BY id ASC;")
List<StringObject> getStringObjects(#Param("name") String name);
However, the same does not appear possible for an insert query as the #Results annotation is only for #Select queries.
Currently, my work around is to specify the type handler as part of the query string like this:
#Options(useGeneratedKeys = true)
#Insert({"INSERT INTO ${name} (text, value, strings) VALUES (#{obj.text}, #{obj.value}, #{obj.strings, typeHandler=com.mypackage.typehandler.StringArrayTypeHandler});"})
void insertStringObject(#Param("obj") SenticConcept concept, #Param("name") String version);
My question is, can we specify the type handler class in an annotation rather than being part of the query string?
This can't be done.
The result mapping uses column names as keys because column values in the result set can be identified using column name, that is mybatis can get the value of some column by its name. So it can use a mapping configuration (for example typeHandler) to process the value in that column.
The input parameters to the query in JDBC are identifiable only by the index of the parameter. In principle it is possible to implement an annotation that would specify the typeHandler based on the index of the parameter, but this is error prone because a change in the query may cause the change in the parameter indices (that's probably the reason it is not done in mybatis).
I am using mybatis from spring boot version 1.3.1 and I used annotation to return nested query result, but I don't get why the column value I used in where clause are all null in the result set, although they are not empty in database.
The returned json is
The mapper is like this:
The data in db:
The bean is simple, 2 items under the main item.
public class TestBean {
String id;
String name;
List<TestSubBean> items;
}
Could anyone give a hint on this?
Change column = "ID" to column = "id".
I guess that mybatis use id_test's property 'id' as parameter,and 'ID' is not a property of id_test
I want to insert an Object with more than 10 properties into mysql via mybatis based on annotation. But I must list all properties, it's too inconvenient. I want to know is there some ways to insert an object easily without list all properties via mybatis. Here is my snippet. Thanks a lot.
#Insert("insert into poi_shop(name,brand,tags,status,phone,mobile,business_time,address,city,lng,lat,business_type,attribute_json) values(#{name},#{brand},#{tags},#{status},#{phone},#{mobile},#{business_time},#{address},#{city},#{lng},#{lat},#{business_type},#{attribute_json})")
#Options(useGeneratedKeys = true, keyProperty = "id", keyColumn = "id")
public Long insertPoiInfo(PoiBo poiBo);
It is not possible in MyBatis (at least version 3) out of the box.
MyBatis has auto mapping when reading data from database but doesn't have option to automatically map fields on insertion.
The reason for this is that MyBatis is very SQL centric that is you need to write SQL manually. It is possible to have implicit fields in SQL select statement (select * from table) so there is automatic mapping to POJO in this case but it is not possible to have implicit fields in update or insert hence no auto-mapping.
MyBatis can be extended of cause. For example you can use #InsertProvider/#UpdateProvider with the sql generator that generates sql using reflection to get object fields.
I have a table T with columns defined as usual.
#Entity
#Table(name="T")
public class T {
#Column(name="test_id")
private Long testId;
}
Given entity property "testId", I want to get corresponding DB column name (i.e. "test_id"). How could it be achieved?
Edit 1:
I want to keep this column at separate location with actual DB column name (test_id) than testId. I fetched these values from DB using HQL which have key as entity name (i.e. testId) and I want actual column name in DB.
If I understood your requirement correctly, you want to use HQL while having a consistent name for both DB column and the entity field, like this:
SELECT t.test_id FROM Test t
instead of
SELECT t.testId FROM Test t
There is only one way to do that - renaming the field to test_id. HQL works on entities, not on DB tables, so you must use proper field names in the query.
Since test_id contradicts the usual Java coding conventions, I would advise against it.
EDIT: Getting the annotation attribute value with reflection would work along this outline:
Field field = MyEntity.class.getDeclaredField("testId");
Column a = field.getAnnotation(Column.class);
String columnName = a.name();
I would try to avoid this by any means, but if you're really sure you'll need it, use:
Configuration configuration = sessionFactory.getConfiguration();
PersistentClass persistentClass = configuration
.getClassMapping(T.class.getName());
String columnName = ((Column) persistentClass.getProperty("testId")
.getColumnIterator().next()).getName();
See also Get table column names in Hibernate
I would like to insert a list of strings into a single column in my database using Mybatis. I've tried using a Custom TypeHandler but I can't even get Mybatis to invoke it.
For a more detailed report on what I've already done click here
While specifying parameters for INSERT statement do like this:
INSERT INTO tableName(a) VALUES(#{aVal, typeHandler=com.test.YourTypeHandler})
where aVal is the parameter that you have passed to statement. Also intead of full name of typehandler you can use it alias. But don't forget to register it(typeHandler) in configuration file of MyBatis
edited
A good practise is specifying a type of value to be inserted like this:
#{aVal, jdbcType=VARCHAR, typeHandler=com.test.YourTypeHandler}. It will save you from issues with null values of aVal