首页 > 代码库 > Mybatis映射实体改造和异常问题

Mybatis映射实体改造和异常问题

现在WEB开发经常使用 Mybatis 作为持久化框架,在开发过程中,会在Java代码中构建实体类与数据库表字段相互映射,

下面提出一个关于映射实体优化的方案:通过链式编程实现给实例对象赋值。

参考代码:

public class UserEntity{
    private int userId;
    private String userName;
    private long lastLogin;
    
    public int getUserId() {
        return userId;
    }

    public UserEntity setUserId(int userId) {
        this.userId = userId;
        return this;
    }

    public String getUserName() {
        return userName;
    }

    public UserEntity setUserName(String userName) {
        this.userName = userName;
        return this;
    }

    public long getLastLogin() {
        return lastLogin;
    }

    public UserEntity setLastLogin(long lastLogin) {
        this.lastLogin = lastLogin;
        return this;
    }
}

  

通过返回 this ,实现链式编程,但是返回 this 以后,Mybatis持久化框架给属性赋值的时候会不会出现问题,为了确认这个问题,查看了Mybatis的源码

Mybaits是通过反射给实体对象赋值的,在主要是调用的 Invoker 接口的相关实现类。

Invoker 接口定义:

public interface Invoker {
Object invoke(Object target, Object[] args) throws IllegalAccessException, InvocationTargetException; Class<?> getType(); }

在Mybatis中,通过Invoker的实现类 SetFieldInvoker 给实体赋值,通过 GetFieldInvoker 获取实体的值。

SetFieldInvoker 类定义:

public class SetFieldInvoker implements Invoker {
  private Field field;

  public SetFieldInvoker(Field field) {
    this.field = field;
  }

  public Object invoke(Object target, Object[] args) throws IllegalAccessException, InvocationTargetException {
    field.set(target, args[0]);
    return null;
  }

  public Class<?> getType() {
    return field.getType();
  }
}

 

GetFieldInvoker 类定义:

public class GetFieldInvoker implements Invoker {
  private Field field;

  public GetFieldInvoker(Field field) {
    this.field = field;
  }

  public Object invoke(Object target, Object[] args) throws IllegalAccessException, InvocationTargetException {
    return field.get(target);
  }

  public Class<?> getType() {
    return field.getType();
  }
}

 

二、Mybatis 异常情况

mapper.xml 定义:

<mapper namespace="xxx.xxx.xxx.UserMapper">
    <sql id="user_field">
        user_id,username,last_login
    </sql>

    <resultMap id="user" type="xxx.xxx.xxx.User">
        <id property="userId" column="user_id"/>
        <result property="userName" column="username"/>
        <result property="" column="last_login"/>
    </resultMap>
<update id="updateLastLogin" parameterType="xxx.xxx.xxx.User">
UPDATE user SET last_login = #{last_login} WHERE user_id = #{user_id}
</update>
</mapper> 

 当调用updateUser方法的时候,程序报错:There is no getter for property named ‘‘last_login" in ‘class xxx.xxx.xxx.User‘

   报这个错的原因是因为我们在#{} 里面应该填写User的属性,而不是列名,我们将 Update语句改为以下形式就正确了:

<update id="updateLastLogin" parameterType="xxx.xxx.xxx.User">
    UPDATE user SET lastLogin = #{last_login} WHERE user_id = #{userId}
</update>

  

 

Mybatis映射实体改造和异常问题