单表查询
单表查询在《初始Mybatis》中已经介绍过,这里就不在介绍了。咱们这里只说单表查询中的“like查询”。
like查询单独使用#{}报错
<select id="selectByKeyword" resultType="com.example.demo.entity.Userinfo">
select * from userinfo where username like '%#{username}%'
</select>
转换成jdbc代码如下
正确的打开方式是配合concat函数使用
<select id="selectByKeyword" resultType="com.example.demo.entity.Userinfo">
select * from userinfo where username like concat('%', #{username}, '%')
</select>
此时的转换成jdbc代码如下:
多表联查
resultType和resultMap
在咱们前面几篇文章中,在select标签中返回类型都是使用resultType,这是因为resultType使用简单,所以大部分查询场景都是使用resultType。
而resultMap用来返回字典映射,resultMap使用场景如下:
- 数据库中的字段名和程序中的属性名不同时,可使用resultMap 配置映射
- 在一对一和一对多中使用resultMap映射并查询数据
字段名和属性名不同的情况,使用resultMap解决
程序的属性:
通过id查询用户信息
<select id="selectById" resultType="com.example.demo.entity.Userinfo">
select * from userinfo where id = #{id}
</select>
单元测试代码:
@Test
void selectById() {
int id = 1;
Userinfo userinfo = userMapper.selectById(id);
System.out.println("用户名:" + userinfo.getName());
}
mybatis是ORM框架,将mysql查询结果放到程序实体类中,当数据库的字段名和属性名相同时就会赋值,由于在数据库中是username,而实体类中是name,无法对应起来,导致赋值失败。
此时可以通过resultMap解决
<resultMap id="baseMap" type="com.example.demo.entity.Userinfo">
<id column="id" property="id"></id>
<result column="username" property="name"></result>
<result column="password" property="password"></result>
<result column="photo" property="photo"></result>
<result column="createtime" property="createtime"></result>
<result column="updatetime" property="updatetime"></result>
<result column="state" property="state"></result>
</resultMap>
<select id="selectById" resultMap="baseMap">
select * from userinfo where id = #{id}
</select>
此时再运行单元测试代码:
使用as别名解决
<select id="selectById2" resultType="com.example.demo.entity.Userinfo">
select username as name, password, photo, createtime, updatetime, state from userinfo where id
</select>
多表查询
现在除了userinfo表,还有一个文章表articleinfo.
需求:在文章表中根据文章id查询文章作者和文章信息
在文章表中并没有username字段,所以需要将articleinfo表和userinfo表联查(因为要展示文章信息所以是left join),联查的条件是articleinfo.uid = userinfo.id.得到的结果既不是userinfo也不是articleinfo,所以我们需要继承articleinfo,创建一个articleinfoVO对象。(VO就是View Object视图对象)
@Mapper
public interface ArticleMapper {
public ArticleinfoVO getById(@Param("id") Integer id);
}
<?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.example.demo.mapper.ArticleMapper">
<select id="getById" resultType="com.example.demo.entity.vo.ArticleinfoVO">
select articleinfo.* , userinfo.username from articleinfo left join userinfo
on userinfo.id = articleinfo.uid
where articleinfo.id = #{id}
</select>
</mapper>
@SpringBootTest
@Transactional
class ArticleMapperTest {
@Autowired
private ArticleMapper articleMapper;
@Test
void getById() {
ArticleinfoVO articleinfoVO = articleMapper.getById(1);
System.out.println(articleinfoVO.toString());
}
}
总结:多表查询时使用连表查询(left join/inner join) + XXXVO解决