MyBatis如何将关联表字段映射为String类型集合?
Hey there, let's work through this MyBatis collection mapping issue together! The problem you're facing comes from not properly configuring the ResultMap to handle the one-to-many relationship between comments and their photos, plus some small misconfigurations in your SQL and mapper setup.
First, let's fix the core issue: Mapping the photo URLs to List<String> urls
The key here is using MyBatis's <collection> tag correctly in your ResultMap—it's designed exactly for aggregating multiple related values into a collection property. Here's the step-by-step correct configuration:
1. Define the ResultMap to aggregate photo URLs
Add this to your mapper XML (make sure it's outside of any <select> tags):
<resultMap id="ToyCommentResultMap" type="com.domain.ToyComment"> <!-- Map the basic comment fields first --> <id property="id" column="id"/> <result property="content" column="content"/> <!-- Map the photo URLs to the `urls` List<String> --> <collection property="urls" ofType="java.lang.String"> <result column="userPhoto"/> </collection> </resultMap>
- The
<id>tag is critical here: MyBatis uses it to identify duplicate comment records (from the LEFT JOIN) and aggregate their photo URLs into a singleToyCommentobject. ofType="java.lang.String"tells MyBatis that the collection contains String elements (since yoururlsis aList<String>).
2. Update your SELECT statement to use the ResultMap
Replace your existing <select> with this—note we're using resultMap instead of resultType, and fixing the column name match (your t_comment_photo has photo_url, not user_photo_url):
<select id="getToyCommentList" resultMap="ToyCommentResultMap"> SELECT c.id, c.content, p.photo_url AS userPhoto FROM t_comment c LEFT JOIN t_comment_photo p ON c.id = p.comment_id </select>
Let's break down your original errors:
"Mapped Statements collection already contains value for..."
This usually happens when you have duplicate<select>IDs in your mapper XML. Double-check that you don't have another statement with the sameid="getToyCommentListByToyId"—if you copied code or renamed statements, you might have left a duplicate entry."No typehandler found for property userPhotos"
You can't use a plain<result>tag to map a collection property likeList<String>. MyBatis needs the<collection>tag to know how to aggregate multiple rows into a single list. Your attempts to setjavaTypedidn't work because you were using the wrong tag entirely.
Extra tips:
- If you want empty lists instead of
nullfor comments with no photos, initialize theurlslist in yourToyCommentclass's constructor:public ToyComment() { this.urls = new ArrayList<>(); } - Make sure your SQL's column alias (
userPhoto) matches exactly with thecolumnvalue in the<collection>'s<result>tag—case sensitivity matters depending on your database configuration.
内容的提问来源于stack exchange,提问作者fall

