mybatis学习3
parameterType(输入类型)
传递简单类型::使用#{}占位符,或者${}进行sql拼接
传递pojo对象: Mybatis使用ognl表达式解析对象字段的值,#{}或者${}括号中的值为pojo的属性名称
传递pojo包装对象:开发中通过可以使用pojo传递查询条件。
查询条件可能是综合的查询条件,不仅包括用户查询条件还包括其它的查询条件(比如查询用户信息的时候,将用户购买商品信息也作为查询条件)
这时可以使用包装对象传递输入参数。
包装对象:Pojo类中的一个属性是另外一个pojo。
public class QueryVo { // 包含其他的pojo private User user; public User getUser() { return user; } public void setUser(User user) { this.user = user; } }
<insert id="insertUserByPojo" parameterType="Pojo"> INSERT INTO `Users`(name,age) Values(#{user.name},#{user.age}) </insert> // 要设置 更细 主键这里不行
也可以使用 ${user.name} 进行字符串拼接
public void testQueryUserByQueryVo() { // mybatis和spring整合,整合之后,交给spring管理 SqlSession sqlSession = this.sqlSessionFactory.openSession(); // 创建Mapper接口的动态代理对象,整合之后,交给spring管理 UserMapper userMapper = sqlSession.getMapper(UserMapper.class); // 使用userMapper执行查询,使用包装对象 QueryVo queryVo = new QueryVo(); // 设置user条件 User user = new User(); user.setUsername("张"); // 设置到包装对象中 queryVo.setUser(user); // 执行查询 List<User> list = userMapper.queryUserByQueryVo(queryVo); for (User u : list) { System.out.println(u); } // mybatis和spring整合,整合之后,交给spring管理 sqlSession.close(); }
resultType(输出类型)
输出简单类型:例如查询数据的条数 <select resultType="int"> SELECT Count(*) From `Users` </select>
注意:输出简单类型必须查询出来的结果集有一条记录,最终将第一个字段的值转换为输出类型。
输出pojo对象 / 输出pojo列表
resultMap:如果sql查询字段名和pojo的属性名不一致,可以通过resultMap将字段名和属性名作一个对应关系 ,resultMap实质上还需要将查询结果映射到pojo对象中。
resultType可以指定将查询结果映射为pojo,但需要pojo的属性名和sql查询的列名一致方可映射成功
resultMap可以实现将查询结果映射为复杂类型的pojo,比如在查询结果映射对象中包括pojo和list实现一对一查询和一对多查询。
namespace: Mapper动态代理开发的时候使用,需要指定Mapper的类路径
<mapper namespace="cn.itcast.mybatis.mapper.OrderMapper"> <!-- resultMap最终还是要将结果映射到pojo上,type就是指定映射到哪一个pojo --> <!-- id:设置ResultMap的id --> <resultMap type="order" id="orderResultMap"> <!-- 定义主键 ,非常重要。如果是多个字段,则定义多个id --> <!-- property:主键在pojo中的属性名 --> <!-- column:主键在数据库中的列名 --> 类型可以只能对应 <id property="id" column="id" /> 里面可以直接定义不一样的名字 <!-- 定义普通属性 --> <result property="userId" column="user_id" /> <result property="number" column="number" /> <result property="createtime" column="createtime" /> <result property="note" column="note" /> </resultMap> <!-- 查询所有的订单数据 --> <select id="queryOrderAll" resultMap="orderResultMap"> SELECT id, user_id, number, createtime, note FROM `order` </select> </mapper>
动态sql
通过mybatis提供的各种标签方法实现动态拼接sql
If标签
<!-- 根据条件查询用户 --> <select id="queryUserByWhere" parameterType="user" resultType="user"> SELECT id, username, birthday, sex, address FROM `user` WHERE sex = #{sex} AND username LIKE '%${username}%' </select>
<!-- 根据条件查询用户 --> <select id="queryUserByWhere" parameterType="user" resultType="user"> SELECT id, username, birthday, sex, address FROM `user` WHERE 1=1 <if test="sex != null and sex != ''"> AND sex = #{sex} </if> <if test="username != null and username != ''"> AND username LIKE '%${username}%' </if> </select>
注意字符串类型的数据需要要做不等于空字符串校验
Where标签
上面的sql还有where 1=1 这样的语句,没有意义 可以使用where标签进行改造
<select id="queryUserByWhere" parameterType="user" resultType="user"> SELECT id, username, birthday, sex, address FROM `user` <!-- where标签可以自动添加where,同时处理sql语句中第一个and关键字 --> <where> <if test="sex != null"> AND sex = #{sex} </if> <if test="username != null and username != ''"> AND username LIKE '%${username}%' </if> </where> </select>
Sql片段
Sql中可将重复的sql提取出来,使用时用include引用即可,最终达到sql重用的目的
<select id="queryUserByWhere" parameterType="user" resultType="user"> <!-- SELECT id, username, birthday, sex, address FROM `user` --> <!-- 使用include标签加载sql片段;refid是sql片段id --> SELECT <include refid="userFields" /> FROM `user` <where> <if test="sex != null"> AND sex = #{sex} </if> <if test="username != null and username != ''"> AND username LIKE '%${username}%' </if> </where> </select> <!-- 声明sql片段 --> <sql id="userFields"> id, username, birthday, sex, address </sql>
如果要使用别的Mapper.xml配置的sql片段,可以在refid前面加上对应的Mapper.xml的namespace
<!-- set标签自动判断哪个是最后一个字段,会自动去掉最后一个,号 --> <update id="dynaUpdate" parameterType="map"> update students <set> <if test="pname!=null"> students_name = #{pname}, </if> <if test="psal!=null"> students_sal = #{psal}, </if> </set> where students_id = #{pid} </update>
<sql id="key"> <!-- 去掉最后一个, --> <trim suffixOverrides=","> <if test="id!=null"> students_id, </if> <if test="name!=null"> students_name, </if> <if test="sal!=null"> students_sal, </if> </trim> </sql>
foreach标签
向sql传递数组或List, mybatis使用foreach解析
例如:SELECT * FROM user WHERE id IN (1,10,24)
Integer[] <foreach collection="array" 必须要用array
List<Integer> <foreach collection="list"
pojoVo 放在里面好使 上面的不好使 <foreach collection="ids"
<select id="queryUserByIds" parameterType="queryVo" resultType="user"> SELECT * FROM `user` <where> <!-- foreach标签,进行遍历 --> <!-- collection:遍历的集合,这里是QueryVo的ids属性 --> <!-- item:遍历的项目,可以随便写,,但是和后面的#{}里面要一致 --> <!-- open:在前面添加的sql片段 --> <!-- close:在结尾处添加的sql片段 --> <!-- separator:指定遍历的元素之间使用的分隔符 --> <foreach collection="ids" item="item" open="id IN (" close=")" separator=","> #{item} </foreach> </where> </select>
关联查询
left join / right join / join / full join
关联查询 都要用resultMap 手动映射
手动映射最好把所有的都映射出来 如果是单表查询 可以省略手动映射
一对一查询
sql语句:
SELECT o.id, o.user_id userId, o.number, o.createtime, o.note, u.username, u.address
FROM `order` o LEFT JOIN `user` u ON o.user_id = u.id
使用resultType
OrderUser类继承Order类后OrderUser类包括了Order类的所有字段,只需要定义转有的字段即可
<select id="queryOrderUser" resultType="orderUser"> SELECT o.id, o.user_id userId, o.number, o.createtime, o.note, u.username, u.address FROM `order` o LEFT JOIN `user` u ON o.user_id = u.id </select>
定义专门的pojo类作为输出类型,其中定义了sql查询结果集所有的字段
此方法较为简单,企业中使用普遍。
使用resultMap
使用resultMap,定义专门的resultMap用于映射一对一查询结果
<resultMap type="order" id="orderUserResultMap"> <id property="id" column="id" /> <result property="userId" column="user_id" /> <result property="number" column="number" /> <result property="createtime" column="createtime" /> <result property="note" column="note" /> <!-- association :配置一对一属性 --> <!-- property:order里面的User属性名 --> <!-- javaType:属性类型 --> <association property="user" javaType="user"> <!-- id:声明主键,表示user_id是关联查询对象的唯一标识--> <id property="id" column="user_id" /> <result property="username" column="username" /> <result property="address" column="address" /> </association> </resultMap> <!-- 一对一关联,查询订单,订单内部包含用户属性 --> <select id="queryOrderUserResultMap" resultMap="orderUserResultMap"> SELECT o.id, o.user_id, o.number, o.createtime, o.note, u.username, u.address FROM `order` o LEFT JOIN `user` u ON o.user_id = u.id </select>
一对多查询
sql语句:
SELECT u.id, u.username, u.birthday, u.sex, u.address, o.id oid, o.number, o.createtime, o.note
FROM `user` u LEFT JOIN `order` o ON u.id = o.user_id
<resultMap type="user" id="userOrderResultMap"> <id property="id" column="id" /> <result property="username" column="username" /> <result property="birthday" column="birthday" /> <result property="sex" column="sex" /> <result property="address" column="address" /> <!-- 配置一对多的关系 --> <collection property="orders" javaType="list" ofType="order"> <!-- 配置主键,是关联Order的唯一标识 --> <id property="id" column="oid" /> <result property="number" column="number" /> <result property="createtime" column="createtime" /> <result property="note" column="note" /> </collection> </resultMap> <!-- 一对多关联,查询订单同时查询该用户下的订单 --> <select id="queryUserOrder" resultMap="userOrderResultMap"> SELECT u.id, u.username, u.birthday, u.sex, u.address, o.id oid, o.number, o.createtime, o.note FROM `user` u LEFT JOIN `order` o ON u.id = o.user_id </select>
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律