在使用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>