【问题标题】:Having trouble understanding how my Spring DTO works无法理解我的 Spring DTO 是如何工作的
【发布时间】:2016-12-13 00:29:32
【问题描述】:

我目前正在处理由第三方承包商构建的遗留项目。它是一个使用 Spring 和 MyBatis 并与 MySQL 服务器对话的 Java 服务器。

我试图在我的 DTO getter/setter 中重构一些丑陋的方法名称,其中包含 CamelCase 和下划线。我将使用方法getCommon_name() 作为示例。当我将其重命名为 getCommonName()) 时,该方法的数据库查找停止工作。我尝试进行文本搜索以查找调用该方法的代码中出现的情况,但它似乎只存在于 DTO 定义中。可能有一些我无法正确理解的到数据库的自动映射,因为该方法会查找一个名为 common_name 的表,但我不能确定。

有没有人能够对可能发生的事情有所了解?这是我第一次使用 Spring/MyBatis。

编辑更多细节:

到目前为止,答案一直在询问我的映射是如何设置的。它看起来像这样:

mybatis-config.xml

<configuration>
  <typeAliases>
    <typeAlias type="com.example.dto.SpeciesDTO" alias="species" />
    <!--aliases for other DTOs-->
  </typeAliases>

  <mappers>
    <mapper resource="com/example/dao/species/speciesSQL.xml" />
    <!--aliases for other DAOs-->
  </mappers>
</configuration>

mybatis-context.xml

<beans>
  <bean id="SpeciesDao" class="org.mybatis.spring.mapper.MapperFactoryBean">
    <property name="mapperInterface"
        value="com.example.dao.species.SpeciesDAO" />
    <property name="sqlSessionFactory" ref="sqlSessionFactory" />
  </bean>
  <!--beans for other DAOs-->
</beans>

此外,DAO 文件都有相关联的 .xml 文件,如下所示:

<mapper namespace="com.example.species.speciesDAO">
  <select id="getSpecies" parameterType="String" resultType="species">
    SELECT * FROM SPECIES
  </select>
  <!--other methods executing SQL-->
</mapper>

我还没有看到任何以 DAO 方法的方式显式映射 DTO getter/setter 的东西。例如,如果我搜索方法 getCommon_name(),唯一出现的是 DTO 本身中的定义以及在我的一个服务中对该方法的调用(我确保在重命名该方法时编辑了这两个事件)。该方法所做的只是返回一个名为common_name 的属性。

【问题讨论】:

  • 如果不查看您的 DTO 和注释/映射文件,很难判断。就像你说的,可以根据你的字段名称自动映射。
  • 问题是,一个完整的项目文本搜索应该返回到我修改的方法的映射(如果它们存在的话)。似乎映射发生在我的代码之外的某个地方。

标签: java mysql spring mybatis


【解决方案1】:

是否有设置名称约定的 mybatis-config.xml 或其他 xml 映射文件?比如来自here

<mapper namespace="org.podcastpedia.dao.PodcastDao">
<!--    result maps     -->
<resultMap id="podcastsMap" type="Podcast" >
    <id column="podcast_id" property="podcastId"  />
    <result column="url" property="url" />
    <result column="rating" property="rating" />
    <result column="numberRatings" property="number_ratings" />
    <result column="number_visitors" property="numberOfVisitors" />
    <result column="DESCRIPTION" property="description" />
    <result column="PODCAST_IMAGE_URL" property="urlOfImageToDisplay" />
    <result column="TITLE" property="title" />
    <result column="last_episode_url" property="lastEpisodeMediaUrl" />
    <result column="title_in_url" property="titleInUrl" />
    <result column="publication_date" property="publicationDate"/>
</resultMap>

【讨论】:

  • 我已将我的配置添加到原始问题中。我确实有mybatis-config.xml,它引用了其他包含 DAO 方法映射的 XML 文件,但 DTO 似乎没有任何此类映射。
【解决方案2】:

与 Hibernate 一样,MyBatis 是一个持久化框架,它使用 XML 文件来定义哪些类和字段映射到哪些数据库表。

当您在 Java 中重命名该方法时,您破坏了 XML 文件中定义的映射。例如,这个映射文件定义了一个 SQL 选择:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
  PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.mybatis.example.BlogMapper">
  <select id="selectBlog" resultType="Blog">
    select * from Blog where id = #{id}
  </select>
</mapper>

然后调用这个的Java实现:

Blog blog = session.selectOne("org.mybatis.example.BlogMapper.selectBlog", 101);

如果在 Java 代码中将 selectBlog 重命名为 selectMyBlog 并且没有更新地图,则可能会收到 NoClassDefFoundError。确保您的文本搜索包括所有 .java 文件以及 .xml 等非 Java 文件。

另外,您没有说明您使用的是哪个 IDE(如果有的话),但我知道 Hibernate 为 IDEA 和 Eclipse 提供了插件。可能还有一个 MyBatis 插件可以让这个映射更容易处理。

【讨论】:

  • 我确实有许多 .xml 映射器,但它们仅适用于 DAO 而不是 DTO。我进行了文本搜索以查看项目中是否有对我修改的方法的任何引用,但唯一出现在 DTO 本身中。
  • 如果没有'get'前缀来搜索呢? Common_name 或 CommonName 而不是 getCommon_name 或 getCommonName?也许 getter 的方法名是根据字段名动态生成的?
  • 我其实也有同样的想法,但是区分大小写的搜索只返回 getCommon_name 实例,不区分大小写只额外返回 SQL 调用。我还认为方法名称可能直接映射到数据库(例如,我有一个名为 common_name 的列,它可能与 getCommon_name 相关)但似乎并非如此 - 我有一个不同的方法称为getUserName 引用名为 user_name 的列。
猜你喜欢
  • 1970-01-01
  • 2021-12-28
  • 2021-12-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多