springboot+mybatis,关于Native Dao开发

springboot+mybatis, About Native Dao development

我正在尝试一种新的开发方法。 在mybatis3中,我一般写mapper.java和mapper.xml。 我知道,sql 语句对应于 sqlId(namespace+id)。 我想像这样执行 sql 语句:

SqlSession sqlSession = sessionFactory.openSession();
return sqlSession.selectList(sqlId, param);

但我得到一个错误:

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)

这是我的 BaseDao.java

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;
  }
}

这里是UserMapper.xml

<mapper namespace="mapper.JinBoot">

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

application.properties

mybatis.mapperLocations=classpath:mapper/*.xml

我启动项目,发送一个 http 请求,在控制器和服务之后,BaseDao 中的参数 'sqlId' 是 'mapper.JinBoot.test'(查看错误信息)。

在方法'BaseDao.select'中,参数和结果类型都是Map。

所以我不想创建UserMapper.java,我想试试。

我该如何解决?这种方式有什么弊端?

这不起作用,因为 spring 引导创建它自己的 SqlSessionFactoryapplication.properties 中指定应在何处查找映射器的选项仅针对 SqlSessionFactory 设置。您正在 DAO 中创建不相关的会话工厂,它不知道在哪里加载映射器定义。

如果你想让它工作,你需要你的 DAO 是 spring 管理的,这样你就可以将 mybatis 会话工厂注入它并在 select 中使用它。这还需要您将 select 转换为非静态方法。

据我了解,您希望在您的基础 DAO class 中只有一种方法,并在个别特定的 DAO class 中使用它。我会说这没什么意义。如果方法 returns Map 会有一些地方实际将这个通用类型映射到某些应用程序特定类型。这可能在子 DAO 中。因此,您仍然需要使用一些输入参数和 returns 一些域对象的签名来创建子 DAO 的 API。这正是你想通过不创建 mybatis 映射器来避免的 classes.

关键是您可以将 mytabis 映射器视为 DAO。那就是你的映射器将是你的 DAO。而且你不需要另一层。据我所知,您现在有两个独立的层 - DAO 和映射器,并且您想删除样板代码。我认为最好删除 DAO classes。它们是真正的样板文件,mybatis mapper 可以完美地充当 DAO。您将它直接注入到您的服务中,而服务仅取决于映射器 class。映射的逻辑在映射器 xml 文件中。另请参阅此问题的答案