在使用Mybatis操作数据库时,一般需要编写pojo类,也就是实体类对数据进行封装,例如用户注册的实现,需要完成数据的插入,这个时候会涉及User实体类的成员变量与数据库表的字段名保持一致的问题,加入不一致,插入是失败的
假如User实体类如下
public class Student {
private Integer id;
private String name;
private String pass_word;
private Date bithday;
private Integer chin_ese;
private Integer math;
private Integer english;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPass_word() {
return pass_word;
}
public void setPass_word(String pass_word) {
this.pass_word = pass_word;
}
public Date getBithday() {
return bithday;
}
public void setBithday(Date bithday) {
this.bithday = bithday;
}
public Integer getChin_ese() {
return chin_ese;
}
public void setChin_ese(Integer chin_ese) {
this.chin_ese = chin_ese;
}
public Integer getMath() {
return math;
}
public void setMath(Integer math) {
this.math = math;
}
public Integer getEnglish() {
return english;
}
public void setEnglish(Integer english) {
this.english = english;
}
@Override
public String toString() {
return "Student{" +
"id=" + id +
", name='" + name + '\'' +
", pass_word='" + pass_word + '\'' +
", bithday=" + bithday +
", chin_ese=" + chin_ese +
", math=" + math +
", english=" + english +
'}';
}
}
而数据库表设计为
在配置Mybatis语句的时候,会根据实体类的对应属性去插入字段,容易出现以下实体类属性名与数据库字段名不一致问题问题
<insert id="insertStu" parameterType="domain.Student">
insert into
student(name,password,birthday,chinese,math,english)
values(#{name},#{password},#{birthday},#{chinese},#{math},#{english});
</insert>
则会报以下错误
org.apache.ibatis.exceptions.PersistenceException: ### Error updating database. Cause: org.apache.ibatis.reflection.ReflectionException: There is no getter for property named 'password' in 'class domain.Student' ### The error may involve mapper.StudentMapper.insertStu-Inline ### The error occurred while setting parameters ### SQL: insert into student(name,password,birthday,chinese,math,english) values(?,?,?,?,?,?); ### Cause: org.apache.ibatis.reflection.ReflectionException: There is no getter for property named 'password' in 'class domain.Student' at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:26) at org.apache.ibatis.session.defaults.DefaultSqlSession.update(DefaultSqlSession.java:154) at org.apache.ibatis.session.defaults.DefaultSqlSession.insert(DefaultSqlSession.java:141) at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:51) at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:52) at com.sun.proxy.$Proxy4.insertStu(Unknown Source) at MybatisTest.test(MybatisTest.java:32) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47) at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) at org.junit.runners.ParentRunner.run(ParentRunner.java:363) at org.junit.runner.JUnitCore.run(JUnitCore.java:137) at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68) at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47) at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242) at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70) Caused by: org.apache.ibatis.reflection.ReflectionException: There is no getter for property named 'password' in 'class domain.Student' at org.apache.ibatis.reflection.Reflector.getGetInvoker(Reflector.java:380) at org.apache.ibatis.reflection.MetaClass.getGetInvoker(MetaClass.java:170) at org.apache.ibatis.reflection.wrapper.BeanWrapper.getBeanProperty(BeanWrapper.java:152) at org.apache.ibatis.reflection.wrapper.BeanWrapper.get(BeanWrapper.java:48) at org.apache.ibatis.reflection.MetaObject.getValue(MetaObject.java:116) at org.apache.ibatis.scripting.defaults.DefaultParameterHandler.setParameters(DefaultParameterHandler.java:76) at org.apache.ibatis.executor.statement.PreparedStatementHandler.parameterize(PreparedStatementHandler.java:80)
解决方法之一:在不修改sql语句的情况下,使用parameterMap标签,关联不一致的属性名即可
但是注意问题:parameterMap在后面已经废弃了
<!-- 实体类字段与数据库字段不一致的情况下,插入数据的解决方法 -->
<parameterMap id="paramMap" type="domain.Student">
<parameter property="pass_word" resultMap="paramMap"></parameter>
<parameter property="bithday" resultMap="paramMap"></parameter>
<parameter property="chin_ese" resultMap="paramMap"></parameter>
</parameterMap>
<insert id="insertStu" parameterMap="paramMap">
insert into
student(name,password,birthday,chinese,math,english)
values(#{name},#{password},#{birthday},#{chinese},#{math},#{english});
</insert>
除此之外,也可以通过修改实体类与SQL语句达到同样的效果
同理,在查询数据时也会出现数据库字段名与实体类属性不一致的情况
在不修改SQL语句的情况下,添加resultMap标签,添加不一致的属性名映射
<!-- 实体类字段与数据库字段不一致情况下,查询数据的解决方法 -->
<resultMap id="stuMap" type="domain.Student">
<id property="id" column="id"></id>
<result property="pass_word" column="password"></result>
<result property="bithday" column="birthday"></result>
<result property="chin_ese" column="chinese"></result>
</resultMap>
<select id="findAllStu" resultMap="stuMap">
select * from student;
</select>