Mybatis - 查询注意点

查询操作

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 的设计思想是,对简单的语句做到零配置,对于复杂一点的语句,只需要描述语句之间的关系就行了。 resultTyperesultMap 之间只能同时使用一个

上面使用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>
发布了167 篇原创文章 · 获赞 3 · 访问量 5406

猜你喜欢

转载自blog.csdn.net/weixin_43907800/article/details/104876291
今日推荐