mybatis中collection association优化使用及多参数传递
mybatis都会用,但要优雅的用就不是那么容易了
今天就简单举例,抛砖引玉,供大家探讨
1.主表
CREATE TABLE `test_one` ( `id` int(11) NOT NULL AUTO_INCREMENT, `nickname` varchar(255) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
对应的java实体类如下(自动生成的代码,省略get set)
@JsonIgnoreProperties(ignoreUnknown = true, value = {"handler"}) public class TestOne implements Serializable { private static final long serialVersionUID = 1L; private Integer id; private String nickname; @JsonIgnoreProperties(ignoreUnknown = true, value = {"testOne"}) private List<TestTwo> testTwos = new LinkedList<>();
注意:JsonIgnoreProperties请忽略,这是解决对象间循环依赖在json序列化时出错的,不在本次内容中
2.从表
CREATE TABLE `test_two` ( `id` int(11) NOT NULL AUTO_INCREMENT, `nickname` varchar(255) NOT NULL, `one_id` int(11) NOT NULL, PRIMARY KEY (`id`), KEY `test_two_ibfk_1` (`one_id`), CONSTRAINT `test_two_ibfk_1` FOREIGN KEY (`one_id`) REFERENCES `test_one` (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8;
对应的java实体类如下(自动生成的代码,省略get set)
@JsonIgnoreProperties(ignoreUnknown = true, value = {"handler"}) public class TestTwo implements Serializable { private Integer id; private String nickname; private Integer oneId; @JsonIgnoreProperties(ignoreUnknown = true, value = {"testTwos"}) private TestOne testOne;
注意:JsonIgnoreProperties请忽略,这是解决对象间循环依赖在json序列化时出错的,不在本次内容中
细心的同学发现,两个表用同名字段,后续会告诉为什么这么举例,而且这种情况项目中是非常常见的
3.TestOneMapper.xml
1 <?xml version="1.0" encoding="UTF-8"?> 2 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> 3 <mapper namespace="info.zycloud.xcx.merchant.dao.TestOneMapper"> 4 <resultMap id="BaseResultMap" type="info.zycloud.xcx.merchant.model.TestOne"> 5 <constructor> 6 <idArg column="id" javaType="java.lang.Integer" jdbcType="INTEGER"/> 7 <arg column="nickname" javaType="java.lang.String" jdbcType="VARCHAR"/> 8 </constructor> 9 </resultMap> 10 11 <!--一次查询查出collection-->
这里会一次查询就查询出主对象和关联的list对象, 查询语句是一个join语句 12 <resultMap id="OnceQueryBaseResultMap" type="info.zycloud.xcx.merchant.model.TestOne" extends="BaseResultMap"> 13 <collection property="testTwos" resultMap="info.zycloud.xcx.merchant.dao.TestTwoMapper.BaseResultMap" 14 columnPrefix="two_"/> 由于两个表有同名字段,所以需要做区分,这里可以采用前缀,就可以共用之前的ResultMap了 15 </resultMap> 16
17 <select id="onceQuery4Collection" resultMap="OnceQueryBaseResultMap"> 18 SELECT 19 one.*, 为什么要用*,是为了防止主表字段变了,因为这里是引用的生成的baseresultMap 20 two.id AS two_id, 21 two.nickname AS two_nickname, 22 two.one_id AS two_one_id 23 FROM 24 `test_one` one 25 LEFT JOIN test_two two ON one.id = two.one_id 26 </select> 27 28 <!-- 多次查询查出collection--> 29 <resultMap id="MultipleQueryBaseResultMap" type="info.zycloud.xcx.merchant.model.TestOne" extends="BaseResultMap"> 30 <collection property="testTwos" column="{oneId=id,nickname=nickname}" 多参数时在column中用"{}"将参数包起来, =左侧的为mapper中定义的param, =右侧为主查询的数据库字段名 31 select="info.zycloud.xcx.merchant.dao.TestTwoMapper.selectByOneId"/> 32 </resultMap> 33 34 <select id="multipleQuery4Collection" parameterType="java.lang.Integer" resultMap="MultipleQueryBaseResultMap"> 35 select 36 <include refid="Base_Column_List"/> 37 from test_one 38 where id = #{id,jdbcType=INTEGER} 39 </select> 40 41 </mapper>
对应的接口定义
1 public interface TestOneMapper { 2 3 List<TestOne> onceQuery4Collection(); 4 5 TestOne multipleQuery4Collection(Integer id); 6 }
3.TestTwoMapper.xml
<?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="info.zycloud.xcx.merchant.dao.TestTwoMapper"> <resultMap id="BaseResultMap" type="info.zycloud.xcx.merchant.model.TestTwo"> <constructor> <idArg column="id" javaType="java.lang.Integer" jdbcType="INTEGER"/> <arg column="nickname" javaType="java.lang.String" jdbcType="VARCHAR"/> <arg column="one_id" javaType="java.lang.Integer" jdbcType="INTEGER"/> </constructor> </resultMap> <select id="selectByOneId" resultMap="BaseResultMap"> select <include refid="Base_Column_List"/> from test_two where one_id=#{oneId} and nickname =#{nickname} </select> </mapper>
1 public interface TestTwoMapper { 2 List<TestTwo> selectByOneId(@Param("oneId") Integer oneId, @Param("nickname") String nickname); 3 }
解释了然后我们执行看下效果:
onceQuery4Collection:
multipleQuery4Collection:
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
· 三行代码完成国际化适配,妙~啊~