MyBatis高级
一.动态sql
1 if
-
格式
<if test="条件"> sql 语句 </if> 当条件成立的时候,会执行sql语句 if (条件){ sql 语句 }
-
案例
<select id="queryUserByCondition" resultType="com.xinzhi.model.User" parameterType="com.xinzhi.model.User"> select id,username,password,age,phone from user where 1=1 <if test="age!=null and age!=''"> and age=#{age} </if> <if test="phone!=null and phone!=''"> and phone=#{phone} </if> </select>
-
java代码
@Test public void test02(){ User user = new User(); user.setPhone("120"); user.setAge(11); List<User> users = userMapper.queryUserByCondition(user); System.out.println(users); }
-
运行日志
DEBUG [main] - ==> Preparing: select id,username,password,age,phone from user where 1=1 and age=? and phone=?
DEBUG [main] - ==> Parameters: 11(Integer), 120(String)
2 choose…when…otherwise…
-
格式
<choose> <when test="条件1"> sql语句1 </when> <when test="条件2"> sql语句2 </when> <otherwise> sql语句3 </otherwise> </choose> 和我们java的if...else if ...else格式一样 当条件1成立,那么就不会执行后面的代码
-
案例
<select id="queryUserByCondition" resultType="com.xinzhi.model.User" parameterType="com.xinzhi.model.User"> select id,username,password,age,phone from user where 1=1 <choose> <when test="age!=null and age!=''"> and age=#{age} </when> <when test="phone!=null and phone!=''"> and phone=#{phone} </when> <otherwise> and password='112233' </otherwise> </choose> </select>
3 where
# 说明
- 标签里边的if 至少有一个成立,就会动态添加一个where,如果都不成立,不添加where
- 第一个if条件成立的,会自动去除连接符and 或者 or
-
案例
<select id="queryUserByCondition" resultType="com.xinzhi.model.User" parameterType="com.xinzhi.model.User"> select id,username,password,age,phone from user <where> <if test="age!=null and age!=''"> and age=#{age} </if> <if test="phone!=null and phone!=''"> and phone=#{phone} </if> </where> </select>
4 set
-
说明
说明: 动态添加了set字段,也会动态的去掉最后一个逗号
-
案例
<update id="updateUser" parameterType="com.xinzhi.model.User"> update user <set> <if test="username!=null and username!=''">username=#{username},</if> <if test="password!=null and password!=''">password=#{password},</if> </set> where id=#{id} </update>
-
代码
@Test public void test03(){ User user = new User(); user.setId(1); user.setUsername("韩哥哥123"); user.setPassword("332211"); String message = userMapper.updateUser(user)>0?"成功":"失败"; System.out.println(message); }
5 foreach
-
说明: 适用于 id in (x,x,x)
-
格式
循环遍历标签。适用于多个参数或者的关系。 <foreach collection=“”open=“”close=“”item=“”separator=“”> 获取参数 </foreach>
-
案例
<select id="queryUsersByIds" resultType="com.xinzhi.model.User" parameterType="java.lang.Integer"> select id,username,password,age,phone from user <where> <foreach collection="list" item="id" open="id in (" close=")" separator=","> #{id} </foreach> </where> </select>
-
代码
@Test public void test04(){ ArrayList<Integer> ids = new ArrayList<Integer>(); Collections.addAll(ids, 1, 2, 3, 4); List<User> users = userMapper.queryUsersByIds(ids); System.out.println(users); }
6 trim
-
格式 pre- presay
格式 <trim prefix=前缀'' prefixoverrides='' suffix=后缀'' suffixoverrides=''>
-
替换where
<select id="queryUserByCondition" resultType="com.xinzhi.model.User" parameterType="com.xinzhi.model.User"> select id,username,password,age,phone from user <trim prefix="where" prefixOverrides="and"> <if test="age!=null and age!=''"> and age=#{age} </if> <if test="phone!=null and phone!=''"> and phone=#{phone} </if> </trim> </select>
-
替换set
<update id="updateUser" parameterType="com.xinzhi.model.User"> update user <trim prefix="set" suffixOverrides=","> <if test="password!=null and password!=''"> password=#{password}, </if> <if test="age!=null and age!=''"> age=#{age}, </if> </trim> where id=#{id} </update>
7 Sql片段
-
格式
<sql id="别名"> 查询的所有字段 </sql> 使用的时候 <include refid="别名"/>
二.分页的使用步骤
1 导入maven依赖
<!-- pageHelper依赖-->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>4.1.6</version>
</dependency>
<dependency>
<groupId>com.github.jsqlparser</groupId>
<artifactId>jsqlparser</artifactId>
<version>0.9.6</version>
</dependency>
2 mybatis配置文件中指定方言
<plugins>
<!-- 注意:分页助手的插件 配置在通用mapper之前 -->
<plugin interceptor="com.github.pagehelper.PageHelper">
<!-- 指定方言 -->
<property name="dialect" value="mysql"/>
</plugin>
</plugins>
3 java代码测试
@Test
public void test02(){
User user = new User();
PageHelper.startPage(1, 3);
List<User> users = userMapper.queryUsersByCondition(user);
PageInfo<User> pageInfo = new PageInfo<User>(users);
System.out.println("总条数:"+pageInfo.getTotal());
System.out.println("总页数:"+pageInfo.getPages());
System.out.println("当前页:"+pageInfo.getPageNum());
System.out.println("每页显示长度:"+pageInfo.getPageSize());
System.out.println("是否第一页:"+pageInfo.isIsFirstPage());
System.out.println("是否最后一页:"+pageInfo.isIsLastPage());
List<User> list = pageInfo.getList();
for (User user1 : list) {
System.out.println(user1);
}
}
三 .mybatis的多表查询
MyBatis的多表查询可以通过XML映射文件中的<select>
标签来实现。以下是一个简单的示例:
- 标签介绍
<resultMap>:配置数据库库字段和Java对象属性的映射关系标签。
id 属性:唯一标识
type 属性:实体对象类型
<id>:配置主键映射关系标签。
<result>:配置非主键映射关系标签。
column 属性:表中字段名称
property 属性: 实体对象变量名称
<association>:配置被包含对象的映射关系标签。
property 属性:被包含对象的变量名
javaType 属性:被包含对象的数据类型
- 测试
假设有两个表users
和orders
,每个用户可以有多个订单,需要查询每个用户和他们的订单信息。可以使用以下SQL语句进行查询:
SELECT *
FROM users u
LEFT JOIN orders o ON u.id = o.user_id
ORDER BY u.id ASC, o.id ASC;
在MyBatis的映射文件中,可以定义一个<select>
标签来执行上述查询,并将结果映射到一个User
类中:
<select id="find" resultMap="userMap">
SELECT *
FROM users u
LEFT JOIN orders o ON u.id = o.user_id
ORDER BY u.id ASC, o.id ASC;
</select>
<resultMap id="userMap" type="User">
<id column="u.id" property="id"/>
<result column="u.name" property="name"/>
<result column="o.id" property="orderId"/>
<result column="o.amount" property="orderAmount"/>
</resultMap>
其中,resultMap
标签定义了如何将查询结果中的每列映射到User
类的属性中。上述示例中,u.id
、u.name
分别对应User
类的id
属性、name
属性,o.id
、o.amount
分别对应User
类的orderId
属性、orderAmount
属性。
在Java代码中,可以通过SqlSession
执行这个查询,并将结果映射到List<User>
中:
SqlSession sqlSession = sqlSessionFactory.openSession();
List<User> userList = sqlSession.selectList("find");
sqlSession.close();
通过这种方式,可以方便地执行多表查询,并将结果映射到Java对象中。当然,在实际项目中,还需要根据具体情况进行调整和优化。