updateByPrimaryKeySelective
updateByPrimaryKey
前者只是更新新的model中不为空的字段。
后者则会将为空的字段在数据库中置为NULL。
updateByPrimaryKeySelective会对字段进行判断再更新(如果为Null就忽略更新),如果你只想更新某一字段,可以用这个方法。
updateByPrimaryKey对你注入的字段全部更新
以上是从别处拷贝过来的,不问出处,纯属当做实例
两段解释的是同一个问题:updateByPrimaryKey与updateByPrimaryKeySelective函数,且都有提到为空。
不过有种人云亦云之感,要探究本质还需查看本源(源码)
那么为空是什么?
为null
为空字符串
为null和为空字符串(胡扯,不可能)
为null或空字符串
贴上源码
BaseUpdateProvider.java
/**
* 通过主键更新不为null的字段
*
* @param ms
* @return
*/
public String updateByPrimaryKeySelective(MappedStatement ms) {
Class<?> entityClass = getEntityClass(ms);
StringBuilder sql = new StringBuilder();
sql.append(SqlHelper.updateTable(entityClass, tableName(entityClass)));
sql.append(SqlHelper.updateSetColumns(entityClass, null, true, isNotEmpty()));
sql.append(SqlHelper.wherePKColumns(entityClass));
return sql.toString();
}
---------------------------------------------------------------------------
public boolean isNotEmpty() {
return mapperHelper.getConfig().isNotEmpty();
}
/**
* 对于一般的getAllIfColumnNode,是否判断!='',默认不判断
*/
private boolean notEmpty = false;
public boolean isNotEmpty() {
return notEmpty;
}
------------------------------------------------------------------------------
<!--<!– spring与mybatis整合配置,扫描所有dao –>-->
<!--<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"-->
<!--p:basePackage="com.landi.dao"-->
<!--p:sqlSessionFactoryBeanName="sqlSessionFactory"/>-->
<bean class="tk.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.landi.dao"/>
<property name="properties">
<value>
mappers=com.landi.common.MyMapper
notEmpty=true
style=normal
</value>
</property>
// 配置属性可以改变notEmpty的值
String notEmpty = properties.getProperty("notEmpty");
if (StringUtil.isNotEmpty(notEmpty)) {
this.notEmpty = notEmpty.equalsIgnoreCase("TRUE");
}
/**
* update set列
*
* @param entityClass
* @param entityName 实体映射名
* @param notNull 是否判断!=null
* @param notEmpty 是否判断String类型!=''
* @return
*/
public static String updateSetColumns(Class<?> entityClass, String entityName, boolean notNull, boolean notEmpty) {
StringBuilder sql = new StringBuilder();
sql.append("<set>");
//获取全部列
Set<EntityColumn> columnList = EntityHelper.getColumns(entityClass);
//当某个列有主键策略时,不需要考虑他的属性是否为空,因为如果为空,一定会根据主键策略给他生成一个值
for (EntityColumn column : columnList) {
if (!column.isId() && column.isUpdatable()) {
if (notNull) {
sql.append(SqlHelper.getIfNotNull(entityName, column, column.getColumnEqualsHolder(entityName) + ",", notEmpty));
} else {
sql.append(column.getColumnEqualsHolder(entityName) + ",");
}
}
}
sql.append("</set>");
return sql.toString();
}
/**
* 判断自动!=null的条件结构
*
* @param entityName
* @param column
* @param contents
* @param empty
* @return
*/
public static String getIfNotNull(String entityName, EntityColumn column, String contents, boolean empty) {
StringBuilder sql = new StringBuilder();
sql.append("<if test=\"");
if (StringUtil.isNotEmpty(entityName)) {
sql.append(entityName).append(".");
}
sql.append(column.getProperty()).append(" != null");
if (empty && column.getJavaType().equals(String.class)) {
sql.append(" and ");
if (StringUtil.isNotEmpty(entityName)) {
sql.append(entityName).append(".");
}
sql.append(column.getProperty()).append(" != '' ");
}
sql.append("\">");
sql.append(contents);
sql.append("</if>");
return sql.toString();
}
mybatis 中isNull, isNotNull与isEmpty, isNotEmpty标签用于动态sql的判断
在mybatis中isNull用于判断参数是否为Null,isNotNull相反
isEmpty判断参数是否为Null或者空,满足其中一个条件则其true
isNotEmpty相反,当参数既不为Null也不为空时其为true
判断之后做相对应的表达式操作
通过下面的代码可以看到假如用isNotEmpty的时候页面假如有值,现在改成空的字符串数据库是不会有效果的,因为isNotEmpty判断的是null和“”这两个属性,所以就不会进这个方法。
<select id="countAgencyName" resultType="java.lang.Integer" parameterType="map">
update agency a
<set>
<if test="map.ageName!= null and map.ageName!=''">
a.ageName = #{map.ageName},
</if>
</set>
<where>
<if test="map.ageId != null and map.ageId !=''">
AND a.ageId = #{map.ageId}
</if>
</where>
</select>
假如要用的话必须用isNotnull这个值判断null,而不判断“”,所以最后会把有值的改成空的字符串的。
<select id="countAgencyName" resultType="java.lang.Integer" parameterType="map">
update agency a
<set>
<if test="map.ageName!= null">
a.ageName = #{map.ageName},
</if>
</set>
</select>
注意:更新多个字段,set语句之后一定别忘记加逗号。set标记已经自动把最后一个逗号给去掉了
public String updateByPrimaryKey(MappedStatement ms) {
Class<?> entityClass = getEntityClass(ms);
StringBuilder sql = new StringBuilder();
sql.append(SqlHelper.updateTable(entityClass, tableName(entityClass)));
sql.append(SqlHelper.updateSetColumns(entityClass, null, false, false));
sql.append(SqlHelper.wherePKColumns(entityClass));
return sql.toString();
}