查询操作
1. 根据id查询
接口中的方法
/**
* 根据id查询单个用户
* @param userId
* @return
*/
User getUserById(Integer userId);
映射文件
<!-- 查询单个用户 -->
<select id="getUserById" parameterType="java.lang.Integer" resultType="cn.minifull.pojo.User">
SELECT * FROM user WHERE id = #{id}
</select>
使用
/**
* 测试查询单个用户
*/
@Test
public void testGetUserById() {
// 确保id存在,否则返回null
User user = mapper.getUserById(48);
System.out.println(user);
}
2. 模糊查询
接口中的方法
List<User> listUsersByName(String username);
映射文件
<!-- 根据姓名模糊查询多个用户 -->
<select id="listUsersByName" parameterType="java.lang.String" resultType="cn.minifull.pojo.User">
SELECT * FROM user WHERE username LIKE #{name}
</select>
使用
/**
* 测试模糊查询
*/
@Test
public void testListUsersByName() {
List<User> users = mapper.listUsersByName("%王%");
}
但这样在调用方法的时候我们必须手动为查询的关键字进行%拼接,这样很不方便。如果想调用方法查询时,只传入查询的关键字,那么可以采用以下方法
① 在 SQL 语句中,使用 MySQL 默认提供的函数 concat()
进行拼接
SELECT * FROM user WHERE username LIKE concat('%',#{name},'%');
② 在 SQL 语句中手动进行拼接
SELECT * FROM user WHERE username LIKE "%"#{name}"%";
3. 使用聚合函数
接口中的方法
/**
* 查询用户总数
*
* @return
*/
int countUser();
映射文件
<!-- 查询用户总数 -->
<select id="countUser" resultType="int">
SELECT count(id) FROM user
</select>
使用
/**
* 测试查询用户总数
*/
@Test
public void testCountUser() {
int count = mapper.countUser();
System.out.println("用户总记录数为 : " + count);
}
4. 使用pojo类作为参数查询
如果参数是基本类型或者基本类型的包装类,且只有一个参数,那么参数符号可以随便写 。也就是说,虽然 Mapper 接口中的方法声明为 HashMap selectPerson(Integer id)
,但是映射文件中既可以写 #{id}
,也可以写 #{aaaa}
但如果我们使用类作为参数,其中的参数符号#{username},#{birthday},#{birthday},#{sex},#{address}
必须和User类的每个属性名一一对应,不可以乱写
其实这里应该说一下OGNL 表达式,对象图导航语言;Mybatis就是使用OGNL表达式来解析对象字段的名称
<insert id="saveUser" parameterType="com.minifull.pojo.User">
INSERT INTO user(username,birthday,sex,address) VALUES (#{username},#{birthday},#{sex},#{address})
</insert>
它是通过对象的取值方法来获取数据。在写法上把get给省略了,也就是说我们的 user.getName()
可以直接写成user.name()
,但我们发现在上面的代码并没有写user.
,这是因为我们在parameterType就已经提供了属性所属的类
5. 使用pojo包装对象
在开发中如果想实现复杂查询 ,查询条件不仅包括用户查询条件,还包括其它的查询条件(比如将用户购买商品信息也作为查询条件),这时可以使用 pojo 包装对象传递输入参数,Pojo类包含pojo
- 编写
QueryVo
类来封装查询条件
/**
* 用于封装查询条件
*
*/
public class QueryVo implements Serializable {
private User user;
// 如果还有其他的查询条件,就可以一并封装进来
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}
- 编写接口层代码和映射文件
/**
* 根据查询条件模糊查询用户
*
* @param vo
* @return
*/
List<User> listUsersByVo(QueryVo vo);
<!-- 根据查询条件模糊查询 -->
<select id="listUsersByVo" parameterType="cn.minifull.pojo.QueryVo" resultType="cn.minifull.pojo.User">
SELECT * FROM user WHERE username LIKE CONCAT('%',#{user.username},'%')
</select>
- 使用
/**
* 测试根据Vo查询
*/
@Test
public void testListUsersByVo(){
QueryVo vo = new QueryVo();
User user = new User();
user.setUsername("王");
vo.setUser(user);
List<User> users = mapper.listUsersByVo(vo);
users.forEach(System.out::println);
}
6. 关于返回值
resultType
resultType
期望从这条语句中返回结果的类全限定名或别名。 注意,如果返回的是集合,那应该设置为集合包含的类型,而不是集合本身的类型
<select id="selectUsers" resultType="com.someapp.model.User">
select id, username, hashedPassword
from some_table
where id = #{id}
</select>
类型别名是你的好帮手。使用它们,你就可以不用输入类的全限定名了。比如
<!-- mybatis-config.xml 中 -->
<typeAlias type="com.someapp.model.User" alias="User"/>
<!-- SQL 映射 XML 中 -->
<select id="selectUsers" resultType="User">
select id, username, hashedPassword
from some_table
where id = #{id}
</select>
在这些情况下,MyBatis 会在幕后自动创建一个 ResultMap,再根据属性名来映射列到 JavaBean 的属性上。而且一旦指定了别名,那么别名就不再区分大小写
也就是说,此时我们可以在映射文件中这样写 resultType="user"
,也可以写 resultType="USER"
如果列名和属性名不能匹配上,可以在 SELECT 语句中设置列别名(这是一个基本的 SQL 特性)来完成匹配。比如:
<select id="selectUsers" resultType="User">
select
user_id as "id",
user_name as "userName",
hashed_password as "hashedPassword"
from some_table
where id = #{id}
</select>
resultMap
对外部 resultMap
的命名引用。结果映射是 MyBatis 最强大的特性,如果你对其理解透彻,许多复杂的映射问题都能迎刃而解。ResultMap 的设计思想是,对简单的语句做到零配置,对于复杂一点的语句,只需要描述语句之间的关系就行了。 resultType
和 resultMap
之间只能同时使用一个
上面使用ResultTyped的返回值属性名转换使用的是由Mybatis隐式的配置resultMap
,那么显式使用外部的 resultMap 怎么做呢
配置resultMap
<resultMap id="userResultMap" type="User">
<id property="id" column="user_id" />
<result property="username" column="user_name"/>
<result property="password" column="hashed_password"/>
</resultMap>
然后在引用它的语句中设置 resultMap
属性就行了(注意我们去掉了 resultType
属性)
<select id="selectUsers" resultMap="userResultMap">
select user_id, user_name, hashed_password
from some_table
where id = #{id}
</select>