现在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>
时间: 2024-10-12 08:03:39