MyBatis select
1. 前言
本小节,我们将一起学习 MyBatis select。
在 MyBatis 中,select 标签对应于 SQL 语句中的 select 查询,我们会在 select 标签中填充 SQL 查询语句,然后在代码中通过对应接口方法来调用。
2. 定义
慕课解释:select 标签用于映射 SQL 中的
查询
语句
3. 实例
MyBatis select 可分为xml
和注解
两种使用方式。
3.1 xml 实例
将 select 查询写在 mapper.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="com.imooc.mybatis.mapper.UserMapper">
<select id="selectUserAgeById" parameterType="java.lang.Integer" resultType="java.lang.Integer">
SELECT age FROM imooc_user WHERE id = #{id}
</select>
</mapper>
其中名为 selectUserAgeById 的 select 标签(一般以 id 做为名称),接收 Integer 类型的参数(parameterType),并返回 Integer 类型的结果(resultType);再看 select 标签中的查询语句,接收 id 参数,类型为 int,返回 age,类型为 int,二者一一对应。
3.2 参数符号
注意,在 select 标签中的 SQL 语句几乎与真实的 SQL 语句一致,但它的参数符号稍有不同:
#{id}
若以 #{}
作为参数符号,MyBatis 则会创建一个预处理语句(PreparedStatement),它会被处理成?
。如果你不希望使用预处理,那么可以使用${}
参数符号,MyBatis 会将其以字符串的形式进行拼接,不过我们推荐你使用 #{}
,几乎所有人也都这样做。
3.3 注解实例
将 SQL 语句写在注解中,如下:
@Select("SELECT username FROM imooc_user WHERE id = #{id}")
String selectUsernameById(Integer id);
注解中的 select 语句无需再添加 id、parameterType 等属性,只需写上对应的 SQL 语句,MyBatis 会自动根据其修饰的方法来推断出这些参数。
TIPS: 提示,使用注解来书写 MyBatis 相对会方便一些,但是注解无法发挥 MyBatis 动态 SQL 真正的威力,因此大部分人都还是会选择 xml 的方式来书写 SQL,但是对于一些 demo 的展示,注解无疑容易上手一些。在后面的学习中,我们都会介绍到注解的使用,但是在实践中我们默认使用 xml 方式。
4. select 属性
select 标签支持很多属性来改变查询语句的行为。
我们摘取其中常见且重要的属性,如下表所示:
属性 | 描述 |
---|---|
id | 在命名空间中唯一的标识符 |
parameterType | 语句的参数类型,默认可选,MyBatis 会自动推断 |
resultType | 语句返回值类型,如果返回的是集合,那应该设置为集合包含的类型 |
resultMap | 语句返回映射的 id;可以使用 resultType 或 resultMap,但不能同时使用。 |
flushCache | 设置为 true 后,只要语句被调用,都会导致本地缓存和二级缓存被清空,默认为 false |
useCache | 设置为 true 后,本条语句的查询结果被二级缓存缓存起来,默认 select 标签为 true。 |
timeout | 设置超时时间 |
fetchSize | 设置预期返回的记录数量 |
statementType | STATEMENT,PREPARED 或 CALLABLE 中的一个,默认为 PREPARED(预处理) |
5. 参数
在上面的实例中,我们介绍了#{id}
参数,这是参数的最简单情况,对于复杂情况,参数还有其它更多的妙用。
5.1 对象参数
有时候,参数可以是一个复杂的对象,如 Java 中的一个 User 类。
<select id="selectUserByAgeAndScore" parameterType="com.imooc.mybatis.model.User"
resultType="com.imooc.mybatis.model.User">
SELECT * FROM imooc_user WHERE age = #{age} AND score = #{score}
</select>
selectUserByAgeAndScore 查询的参数是一个复杂 Java 对象 User,当 User 作为参数对象时,User 中的属性都可作为查询语句的参数,如 age 和 score。
5.2 参数配置
#{}
不仅可以传入参数名称,还可以传入参数类型和类型处理器。
比如:
#{age,javaType=int,jdbcType=int,typeHandler=IntegerTypeHandler}
其中 javaType 表示 age 的 Java 类型,jdbcType 表示 age 的数据库类型,typeHandler 表示 age 的类型处理器,关于类型处理器我们将在后面的章节介绍。
对于参数配置,90% 的情况你都只需要传入参数名即可,因为 MyBatis 都会自动推断出配置。
6. 实践
介绍了这么多概念,我们一起来实操巩固一下。
6.1 例1. 通过年龄和分数查询用户
请使用 MyBatis 完成在 imooc_user 表中通过年龄
和分数
查询用户的功能。
分析:
按照 MyBatis 的开发模式,先在对应 UserMapper.xml 文件中添加通过年龄和分数查询用户的 select 标签,然后在 UserMapper.java 中增加上对应的方法即可。
步骤:
首先,我们在 com.imooc.mybatis 包下新建 model 包,用于保存数据库对象,并在 model 包下新建 User.java 类:
package com.imooc.mybatis.model;
public class User {
private Long id;
private String username;
private Integer age;
private Integer score;
// 省略了 getter 和 setter 方法,请务必通过 IDE 生成,否则 MyBatis 无法自动映射
}
在 UserMapper.xml 文件中,我们新增 selectUserByAgeAndScore 标签,该 select 标签的作用是:通过年龄和分数查询用户。
<select id="selectUserByAgeAndScore" parameterType="com.imooc.mybatis.model.User"
resultType="com.imooc.mybatis.model.User">
SELECT * FROM imooc_user WHERE age = #{age} AND score = #{score}
</select>
然后在 UserMapper.java 接口中,我们新增对应的方法,方法接收复杂参数 User:
package com.imooc.mybatis.mapper;
import com.imooc.mybatis.model.User;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface UserMapper {
User selectUserByAgeAndScore(User user);
}
结果:
通过如下代码,我们运行 selectUserByAgeAndScore 方法。
// 得到 mapper
UserMapper userMapper = session.getMapper(UserMapper.class);
User condition = new User();
condition.setAge(18);
condition.setScore(100);
// 调用方法
User user = userMapper.selectUserByAgeAndScore(condition);
// 得到 user
System.out.println(user);
输出结果为:
User{id=1, username='peter', age=18, score=100}
7. 小结
- MyBatis 虽然提供了
#{}
和${}
两种方式来传递参数,但无疑#{}
更加实用。 - select 标签属性虽然多,但是大部分情况下都不会针对某一个 select 标签来定制化,多会在全局里进行配置。
- 互联网的应用场景多数为读多写少,那么 select 肯定是使用
最为广泛
的标签了。