鍍金池/ 問答/Java/ springboot+mybatis,原生dao開發(fā)問題

springboot+mybatis,原生dao開發(fā)問題

最近想嘗試一種比較簡單的開發(fā)方法。
只在xml文件中寫sql語句,傳入和傳出參數(shù)都是map。在controller和service中再做其他操作。

然后寫了份測試代碼。

這是通用Dao,service層傳入sqlId和map類型的param,根據(jù)sqlId調(diào)用對應(yīng)sql語句,返回結(jié)果也是map

public class BaseDao {

    private static SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();

    public static List<Map> select(String sqlId, Map param) {
        try {
            factoryBean.setDataSource(new DruidDataSource());
            SqlSessionFactory sessionFactory = factoryBean.getObject();
            SqlSession sqlSession = sessionFactory.openSession();
            return sqlSession.selectList(sqlId, param);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}

自定義的mapper.xml

<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="mapper.JinBoot">

    <select id="test" parameterType="hashMap" resultType="hashMap">
        select * from user
    </select>
</mapper>

在application中也做了配置

mybatis.mapperLocations=classpath:mapper/*.xml

執(zhí)行的時候,經(jīng)過controller接口和service層,傳到Dao層的sqlId是mapper.JinBoot.test, param是空。
執(zhí)行報錯。

報錯信息如下:

Cause: java.lang.IllegalArgumentException: Mapped Statements collection does not contain value for mapper.JinBoot.test
    at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:30)
    at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:150)
    at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:141)
    at cn.tianyustudio.jinboot.dao.BaseDao.select(BaseDao.java:20)
    at cn.tianyustudio.jinboot.service.BaseService.select(BaseService.java:10)
    at cn.tianyustudio.jinboot.controller.BaseController.test(BaseController.java:21)

上網(wǎng)查了下,大概意思是沒有掃描到mapper.JinBoot.test這個id對應(yīng)的sql語句,但mybatis中不是根據(jù)namespace+id來尋找的嗎?我這里沒有用mybatis的mapper映射方式(有對應(yīng)的Dao.java),但通過這種手工指定id的方式理論上來說應(yīng)該是可行的,是哪里的配置問題還是?

回答
編輯回答
護她命

mapper.JinBoot應(yīng)該是一個接口,里面聲明一個test方法,mapper.JinBoot貼出來看看
報錯源碼

public V get(Object key) {
/* 670 */       V value = super.get(key);
/* 671 */       if (value == null) {
/* 672 */         throw new IllegalArgumentException(this.name + " does not contain value for " + key);
/*     */       }
/* 674 */       if ((value instanceof Ambiguity)) {
/* 675 */         throw new IllegalArgumentException(((Ambiguity)value).getSubject() + " is ambiguous in " + this.name + " (try using the full name including the namespace, or rename one of the entries)");
/*     */       }
/*     */       
/* 678 */       return value;
/*     */     }
protected final Map<String, MappedStatement> mappedStatements = new StrictMap("Mapped Statements collection");

Mybatis會解析xml文件,使用StrictMap把namespace+id作為key,MappedStatement作為value存儲起來,執(zhí)行selectList方法時會根據(jù)sqlId查找對應(yīng)的MappedStatement,如果value為null,則報出這個異常 Mapped Statements collection does not contain value for mapper.JinBoot.test。

2018年9月6日 19:08
編輯回答
悶油瓶

把mapper里查詢方法的id改成select.也就是dao的方法名.

2017年12月31日 18:41
編輯回答
情未了

是不是被加進了IncompleteStatement這個集合? XML文件讀取轉(zhuǎn)換失敗的話會直接加進這個集合,不會報異常的。

建議打斷點看看,mapper文件的掃描都會經(jīng)過這個方法

// 出處
// mybatis-3.4.4.jar
// org.apache.ibatis.builder.xml.XMLMapperBuilder line:132
private void buildStatementFromContext(List<XNode> list, String requiredDatabaseId) {
    for (XNode context : list) {
      final XMLStatementBuilder statementParser = new XMLStatementBuilder(configuration, builderAssistant, context, requiredDatabaseId);
      try {
        statementParser.parseStatementNode();
      } catch (IncompleteElementException e) {
        configuration.addIncompleteStatement(statementParser);
      }
    }
  }
2017年4月21日 10:42