自定义SQL
如果MybatisPlus的BaseMapper中提供的方法无法满足我们的业务需求,我们也可以自定义SQL语句实现对数据库的操作,这里的SQL可以使用两种方式书写
- 注解方式:适合比较简单的SQL书写
- XML方式:适合比较复杂的SQL书写
注解方式(了解)
注解方式自定义SQL需要在Mapper接口中自定义方法,然后再使用Mybatis提供注解(@Insert、@Select、@Delete、@Update)声明SQL
创建UserMapper
java
package com.itheima.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.itheima.entity.User;
import org.apache.ibatis.annotations.*;
import java.util.List;
@Mapper
public interface UserMapper extends BaseMapper<User> {
@Insert("insert into user values (null,#{username},#{password},#{name},#{age})")
Integer addUser(User user);
@Update("update user set username = #{username},password = #{password},name = #{name},age=#{age} where id = #{id}")
Integer updateUser(User user);
@Delete("delete from user where id = #{id}")
Integer deleteUser(Integer id);
@Select("select * from user")
List<User> findAll();
@Select("select * from user where username = #{username} and password = #{password}")
User findByUsernameAndPassword(@Param("username") String username, @Param("password") String password);
}代码测试
java
package com.itheima.mapper;
import com.itheima.entity.User;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.List;
@SpringBootTest
class UserMapperTest6 {
@Autowired
private UserMapper userMapper;
@Test
void addUser() {
userMapper.addUser(new User(null, "yangguo", "123456", "杨过", 20));
}
@Test
void updateUser() {
User user = userMapper.selectById(4);
user.setPassword("123456");
user.setAge(30);
userMapper.updateUser(user);
}
@Test
void deleteUser() {
userMapper.deleteUser(4);
}
@Test
void findAll() {
List<User> userList = userMapper.findAll();
userList.forEach(user -> System.out.println(user));
}
@Test
void findByUsernameAndPassword() {
User user = userMapper.findByUsernameAndPassword("yangguo", "123456");
System.out.println(user);
}
}XML方式(重要)
如果要定义的SQL比较复杂,使用XML方式更加合适一些。
创建UserMapper
自定义SQL实现用户表的CRUD操作。上面的注解方式中的@Insert这样的代码就可以不用写在Mapper中了。
这里以自定义的多表联合查询结合Mybatisplus本身提供的分页功能进行代码示例:
IPage<UserVo>表示Mybatisplus默认提供的分页功能,我们只需要查询分页中的列表数据这块功能即可。
java
package com.cghbh.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.cghbh.dto.UserPageDto;
import com.cghbh.entity.User;
import com.cghbh.vo.UserVo;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
@Mapper
public interface UserMapper extends BaseMapper<User> {
// 第一个参数是跟userMappper.selectPage(new Page<>())一样的功能,第二个参数则是分页需要的参数
// @Param不写的情况下,传递给对应UserMapper.xml文件的变量名称就是dto1!!!
// 如果写了@Param的话,则传入到UserMapper.xml的变量名称就是dto2!!!
IPage<UserVo> getUsersByPage(IPage<UserVo> page, @Param("dto2") UserPageDto dto1);
}创建UserMapper.xml
在resources目录下创建一个mapper目录,然后将资料中提供的UserMapper.xml文件复制到此目录
(官方推荐在和Mapper接口同层级的文件夹中创建xml文件)
请注意
在MybatisPlus中使用XML映射文件方式开发,需要符合一定的规范:
- XML映射文件中namespace的值必须跟Mapper接口全限定名一致
- XML映射文件中sql语句的id必须与Mapper接口中的方法名一致
- XML映射文件中sql语句的idresultType必须跟接口中的方法返回值中实体类类型一致

xml
<?xml version="1.0" encoding="UTF-8" ?>
<!-- 引入mybatis的xml方式编写sql的约束 -->
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- mapper跟标签的namespace属性的值必须是接口的完全限定路由 -->
<mapper namespace="com.cghbh.mapper.UserMapper">
特别提示一下:resultType决定了返回的字段,不在这个UserVo里面的字段,即便你在SQL中查询到了也会被过滤掉
<select id="getUsersByPage" resultType="com.cghbh.vo.UserVo">
SELECT
u.*,
d.name AS dept_name,
r.name AS role_name,
r.label AS role_label
FROM `user` u
LEFT JOIN `dept` d ON u.dept_id = d.id
LEFT JOIN `role` r ON u.role_id = r.id
<where>
<if test="dto.status != null">
u.status = #{dto.status}
</if>
<if test="dto.deptId != null">
u.dept_id = #{dto.deptId}
</if>
<if test="dto.name != null and dto.name != ''">
u.name LIKE CONCAT('%',#{dto.name},'%')
</if>
<if test="dto.phone != null and dto.phone != ''">
u.phone LIKE CONCAT('%',#{dto.phone},'%')
</if>
</where>
ORDER BY u.update_time DESC
</select>
</mapper>!!!
在xml文件中写的SQL查询语句禁止加分号,因为在分页处理的时候Mybatisplus会帮我们拦截SQL增加分页的语句,加了分号运行代码会报错。
如何快速创建MyBatisMapper
打开File → Settings → Editor → File and Code Templates,

填写模板的名称、类型和填充的内容:

模板内容如下:
xml
<?xml version="1.0" encoding="UTF-8" ?>
<!-- 引入mybatis的xml方式编写sql的约束 -->
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="">
<!-- namespace表示对应的mapper包文件地址,例如com.cghbh.mapper.UserMapper,这个Mapper就是你之前在mapper文件夹下创建的-->
</mapper>然后创建文件的时候,鼠标右键选择如下即可使用:

修改配置文件
在SpringBoot的配置文件application.yaml中配置xml文件所在的位置。
yml
# 配置MyBatis-Plus
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
mapper-locations: classpath:mapper/*.xml # 注意我们刚才把mapper接口对应的xml放到了mapper目录中 , 所以这里需要配置一下代码测试
java
/**
* 测试查询年龄姓张并且年龄大于18的用户方法
*/
@Test
public void testSelectByNameAndAge() {
List<User> list = userMapper.selectByNameAndAge("张",18);
System.out.println(list);
}