以下测试中的testLog是一个日志对象,只有id和tableName被设值,其他字段都是null。
经过测试,发现的几个大致的规律【约定:处理的字段,指的是insert和update关键字后面跟的字段】:
1.selective:表示只处理参数对象中非NULL属性对应的表字段,NULL属性对应的表字段数据库会按默认值处理。
2.primaryKey:参数是Object类型。
如果实体类有被注解为主键的属性,则参数可以为实体类对象,也可以是主键的值,where条件只会使用主键属性对应的字段。
如果实体类没有被注解为主键的属性,则参数只能是实体类对象,并且where条件会使用所有属性对应的字段。
3.内置方法的方法名不含以上两者:表示会处理参数对象所有属性对应的表字段,where条件只含有参数对象非NULL属性对应的表字段。
4.selective:用来限定操作含有的字段,primaryKey:用来限定where条件含有的字段。如果没有两者,表示都不作限定。
4.这些规律都有佐证例子,如下。
·········································································································`·······························································
operateLog 实体类***没有被注解为主键的字段***
insertSelective对应的sql语句加入了NULL校验,即只会插入数据不为null的字段值(没有插入的字段,如果有默认值,则会使用默认值)。
insert则会插入所有字段,会插入null(不使用默认值)。
1.updateByPrimaryKeySelective会对字段进行判断再更新(如果为Null则不更新),如果你只想更新某一字段,可以用这个方法。
2.updateByPrimaryKey对你注入的字段全部更新
1和2的where条件是参数对象的所有字段(不管是否为空)
sql示例(只有id和tableName被set值):
--------------begin:updateByPrimaryKey(testLog)
2018-10-15 15:49:53 [INFO] UPDATE operateLog SET id = 0,tableName = 'test',type = NULL,oldValue = NULL,operateAccount
= NULL,operateName = NULL,addTime = NULL WHERE id = 0 AND tableName = 'test' AND type = NULL
AND oldValue = NULL AND operateAccount = NULL AND operateName = NULL AND addTime = NULL
{executed in 65 msec}
--------------end:updateByPrimaryKey(testLog)
--------------begin:updateByPrimaryKeySelective(testLog)
2018-10-15 15:49:53 [INFO] UPDATE operateLog SET id = 0,tableName = 'test' WHERE id = 0 AND tableName = 'test' AND type = NULL AND oldValue = NULL AND operateAccount = NULL AND operateName = NULL AND addTime = NULL
{executed in 30 msec}
--------------end:updateByPrimaryKeySelective(testLog)
select:
sql.append(SqlHelper.selectAllColumns(entityClass));
sql.append(SqlHelper.fromTable(entityClass, this.tableName(entityClass)));
sql.append(SqlHelper.whereAllIfColumns(entityClass, this.isNotEmpty()));
拼接的语句含有很多mybatis标签,如 if 标签,最终拼接的语句和我们平时写的语句差不多
在拼接条件时,做了null 和 ‘’的处理
OperateLog类***没有被注解为主键的字段***
#1.selectByPrimaryKey(0L):参数不能是主键的值,报异常
Error setting non null for parameter #2 with JdbcType null . Try setting a different JdbcType for this parameter or a different configuration property. Cause: java.lang.ClassCastException: java.lang.Long cannot be cast to java.lang.String
#2.selectByPrimaryKey(testLog):where条件是参数对象的所有字段(不管是否为空)
------------------begin:selectByPrimaryKey(testLog)
2018-10-16 10:10:28 [INFO] SELECT id,tableName,type,oldValue,operateAccount,operateName,addTime FROM operateLog WHERE
id = 0 AND tableName = 'testTable' AND type = NULL AND oldValue = NULL AND operateAccount =
NULL AND operateName = NULL AND addTime = NULL
{executed in 73 msec}
------------------end:selectByPrimaryKey(testLog)
#3.select(testLog):where条件是对象所有非空字段
------------------begin:select(testLog)
2018-10-16 10:10:28 [INFO] SELECT id,tableName,type,oldValue,operateAccount,operateName,addTime FROM operateLog WHERE
id = 0 AND tableName = 'testTable'
{executed in 72 msec}
------------------end:select(testLog)
#4.selectOne(testLog):where条件是对象所有非空字段(如果结果有多个,mybatis会报异常)
------------------begin:selectOne(testLog)
2018-10-16 10:10:28 [INFO] SELECT id,tableName,type,oldValue,operateAccount,operateName,addTime FROM operateLog WHERE id = 0 AND tableName = 'testTable'
{executed in 60 msec}
------------------end:selectOne(testLog)
#5.selectCount(testLog):where条件是对象所有非空字段
------------------begin:selectCount(testLog)
2018-10-16 10:10:28 [INFO] SELECT COUNT(*) FROM operateLog WHERE id = 0 AND tableName = 'testTable'
{executed in 74 msec}
------------------end:selectCount(testLog)
#6.selectByExample(example):
Example example = new Example(OperateLog.class);
Example.Criteria criteria = example.createCriteria();
criteria.andEqualTo("id", testLog.getId());
criteria.andNotEqualTo("tableName",testLog.getTableName());
criteria.andBetween("type",1,3);
example.setOrderByClause("addTime desc");
operateLogMapper.selectByExample(example);
----------------------begin:selectByExample(example)
2018-10-16 10:47:17 [INFO] SELECT id,tableName,type,oldValue,operateAccount,operateName,addTime FROM operateLog WHERE ( id = 0 and tableName <> 'testTable' and type between 1 and 3 ) order by addTime desc
{executed in 12 msec}
----------------------end:selectByExample(example)
CustInfoStatus类***没有被注解为主键的字段***
custInfoStatusMapper.deleteByPrimaryKey(custId);
Caused by: org.apache.ibatis.type.TypeException: Could not set parameters for mapping: ParameterMapping{property=‘approveStatus’, mode=IN, javaType=class java.lang.Integer, jdbcType=null, numericScale=null, resultMapId=‘null’, jdbcTypeName=‘null’, expression=‘null’}. Cause: org.apache.ibatis.type.TypeException: Error setting non null for parameter #3 with JdbcType null . Try setting a different JdbcType for this parameter or a different configuration property. Cause: java.lang.ClassCastException: java.lang.Long cannot be cast to java.lang.Integer
CustInfoStatus2 有被注解为主键的字段
CustInfoStatus2 custInfoStatus2 = new CustInfoStatus2();
custInfoStatus2.setCustId(custId);
custInfoStatus2Mapper.delete(custInfoStatus2);
对应的SQL:
DELETE FROM custInfoStatus WHERE custId = 10;
CustInfoStatus2 custInfoStatus2 = new CustInfoStatus2();//id属性被注解为表的主键
custInfoStatus2.setCustId(custId);
custInfoStatus2Mapper.deleteByPrimaryKey(custInfoStatus2);
对应的SQL:
DELETE FROM custInfoStatus WHERE id = NULL;
-----------------deleteByPrimaryKey(1111L)
ApiCust类的id属性***被注解为数据库主键***,为Long类型
apiCustMapper.deleteByPrimaryKey(1111L);
对应的SQL:
2018-10-19 13:51:40 [INFO] DELETE FROM apiCust WHERE id = 1111
-----------------deleteByPrimaryKey(testLog)
OperateLog对象***没有字段被注解为主键***
OperateLog testLog = new OperateLog();
testLog.setId(2222L);
operateLogMapper.deleteByPrimaryKey(testLog);
对应的SQL:
2018-10-19 13:51:40 [INFO] DELETE FROM operateLog WHERE id = 2222 AND tableName = NULL AND type = NULL AND oldValue =
NULL AND operateAccount = NULL AND operateName = NULL AND addTime = NULL AND memo = NULL
-----------------deleteByPrimaryKey(3333L)
OperateLog对象***没有字段被注解为主键***
operateLogMapper.deleteByPrimaryKey(3333L);
报错:
org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.type.TypeException: Could not set parameters for mapping: ParameterMapping{property=‘tableName’, mode=IN, javaType=class java.lang.String, jdbcType=null, numericScale=null, resultMapId=‘null’, jdbcTypeName=‘null’, expression=‘null’}. Cause: org.apache.ibatis.type.TypeException: Error setting non null for parameter #2 with JdbcType null . Try setting a different JdbcType for this parameter or a different configuration property.
Cause: java.lang.ClassCastException: java.lang.Long cannot be cast to java.lang.String
ApiCust类的id属性***被注解为数据库主键***,为Long类型
ApiCust apiCust = new ApiCust();
apiCust.setId(id);
apiCustMapper.selectByPrimaryKey(apiCust);
对应的SQL:
2018-10-19 14:15:32 [INFO] SELECT id,telNo,pwd,device,createTime FROM apiCust WHERE id = 10
apiCustMapper.selectByPrimaryKey(4444L);
对应的SQL:
2018-10-19 14:15:32 [INFO] SELECT id,telNo,pwd,device,createTime FROM apiCust WHERE id = 4444