Mybatis數據庫操作容易掉的坑

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

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章