MyBatis基础入门
1.MyBatis 概述
- MyBatis 是一个优秀的持久层框架,它对 jdbc 的操作数据库的过程进行封装,使开发者只需要关注 SQL 本身,而不需要花费精力去处理例如注册驱动、创建 connection、创建 statement、手动设置参数、结果集检索等 jdbc 繁杂的过程代码。
- Mybatis 通过 xml 或注解的方式将要执行的各种 statement(statement、preparedStatement、CallableStatement)配置起来,并通过 java 对象和 statement 中的 sql 进行映射生成最终执行的 sql 语句,最后由 mybatis 框架执行 sql 并将结果映射成 java 对象并返回。
2. 为什么要使用 MyBatis(使用 JDBC 编程有哪些问题)?
-
数据库链接创建、释放频繁造成系统资源浪费从而影响系统性能,如果使用数据库链接池可解决此问题。
-
Sql 语句在代码中硬编码,造成代码不易维护,实际应用 sql 变化的可能较大,sql 变动需要改变 java 代码。
- 使用 preparedStatement 向占有位符号传参数存在硬编码,因为 sql 语句的 where 条件不一定,可能多也可能少,修改 sql 还要修改代码,系统不易维护。
- 对结果集解析存在硬编码(查询列名),sql 变化导致解析代码变化,系统不易维护,如果能将数据库记录封装成 pojo 对象解析比较方便。
3.MyBatis 架构
- MyBatis 配置
-
SqlMapConfig.xml,此文件作为 mybatis 的全局配置文件,配置了mybatis 的运行环境等信息。
- mapper.xml 文件即sql 映射文件,文件中配置了操作数据库的 sql 语句。此文件需要在 SqlMapConfig.xml 中加载。
-
-
通过 mybatis 环境等配置信息构造SqlSessionFactory 即会话工厂
-
由会话工厂创建 sqlSession 即会话,操作数据库需要通过 sqlSession 进行。
- mybatis 底层自定义了 Executor 执行器接口操作数据库,Executor 接口有两个实现,一个是基本执行器、一个是缓存执行器。
-
Mapped Statement 也是 mybatis 一个底层封装对象,它包装了 mybatis 配置信息及 sql 映射信息等。mapper.xml 文件中一个 sql 对应一个 Mapped Statement 对象,sql 的 id 即是 Mapped statement 的 id。
-
Mapped Statement 对 sql 执行输入参数进行定义,包括 HashMap、基本类型、pojo,Executor 通过 Mapped Statement 在执行 sql 前将输入的 java 对象映射至 sql 中,输入参数映射就是 jdbc 编程中对 preparedStatement 设置参数。
- Mapped Statement 对 sql 执行输出结果进行定义,包括 HashMap、基本类型、pojo,Executor
4.MyBatis 入门
创建 Maven 工程
修改 pom.xml 导入 MyBatis 以及 Junit 和 MySql 驱动的 jar 包
<dependencies> <!-- MySQL 驱动 --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.29</version> </dependency><span style="color: rgba(0, 128, 0, 1)"><!--</span><span style="color: rgba(0, 128, 0, 1)">junit </span><span style="color: rgba(0, 128, 0, 1)">--></span> <span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">dependency</span><span style="color: rgba(0, 0, 255, 1)">></span> <span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">groupId</span><span style="color: rgba(0, 0, 255, 1)">></span>junit<span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">groupId</span><span style="color: rgba(0, 0, 255, 1)">></span> <span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">artifactId</span><span style="color: rgba(0, 0, 255, 1)">></span>junit<span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">artifactId</span><span style="color: rgba(0, 0, 255, 1)">></span> <span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">version</span><span style="color: rgba(0, 0, 255, 1)">></span>4.12<span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">version</span><span style="color: rgba(0, 0, 255, 1)">></span> <span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">scope</span><span style="color: rgba(0, 0, 255, 1)">></span>test<span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">scope</span><span style="color: rgba(0, 0, 255, 1)">></span> <span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">dependency</span><span style="color: rgba(0, 0, 255, 1)">></span> <span style="color: rgba(0, 128, 0, 1)"><!--</span><span style="color: rgba(0, 128, 0, 1)"> mybatis </span><span style="color: rgba(0, 128, 0, 1)">--></span> <span style="color: rgba(0, 128, 0, 1)"><!--</span><span style="color: rgba(0, 128, 0, 1)"> https://mvnrepository.com/artifact/org.mybatis/mybatis </span><span style="color: rgba(0, 128, 0, 1)">--></span> <span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">dependency</span><span style="color: rgba(0, 0, 255, 1)">></span> <span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">groupId</span><span style="color: rgba(0, 0, 255, 1)">></span>org.mybatis<span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">groupId</span><span style="color: rgba(0, 0, 255, 1)">></span> <span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">artifactId</span><span style="color: rgba(0, 0, 255, 1)">></span>mybatis<span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">artifactId</span><span style="color: rgba(0, 0, 255, 1)">></span> <span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">version</span><span style="color: rgba(0, 0, 255, 1)">></span>3.4.5<span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">version</span><span style="color: rgba(0, 0, 255, 1)">></span>
</dependency>
</dependencies>
classpath 目录下创建 MyBatis 的核心配置文件 SqlMapConfig.xml
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"><configuration>
<environments default="development">
<environment id="development">
<!-- 使用 jdbc 事务管理 -->
<transactionManager type="JDBC" />
<!-- 数据库连接池 -->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver" />
<property name="url"
value="jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8" />
<property name="username" value="root" />
<property name="password" value="root" />
</dataSource>
</environment>
</environments><span style="color: rgba(0, 128, 0, 1)"><!--</span><span style="color: rgba(0, 128, 0, 1)"> 加载映射文件 --></span> <span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">mappers</span><span style="color: rgba(0, 0, 255, 1)">></span> <span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">mapper </span><span style="color: rgba(255, 0, 0, 1)">resource</span><span style="color: rgba(0, 0, 255, 1)">="User.xml"</span> <span style="color: rgba(0, 0, 255, 1)">/></span> <span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">mappers</span><span style="color: rgba(0, 0, 255, 1)">></span>
</configuration>
创建测试数据库
创建 po 类 ---Po 类作为 mybatis 进行 sql 映射使用,po 类通常与数据库表对应
package pojo;
import java.util.Date;
public class User {
private int id;
private String username;// 用户姓名
private String sex;// 性别
private Date birthday;// 生日
private String address;// 地址
getter and setter 方法......
@Override
public String toString() {
return "User [id=" + id + ", username=" + username + ", sex=" + sex + ", birthday=" + birthday + ", address="
+ address + "]";
}
}
创建 sql 映射文件 User.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"> <!-- namespace: 命名空间, 做 sql 隔离 --> <mapper namespace="test"><span style="color: rgba(0, 128, 0, 1)"><!--</span><span style="color: rgba(0, 128, 0, 1)"> id:sql语句唯一标识 parameterType:指定传入参数类型 resultType:返回结果集类型 #{}占位符:起到占位作用,如果传入的是基本类型(string,long,double,int,boolean,float等),那么#{}中的变量名称可以随意写. </span><span style="color: rgba(0, 128, 0, 1)">--></span> <span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">select </span><span style="color: rgba(255, 0, 0, 1)">id</span><span style="color: rgba(0, 0, 255, 1)">="findUserById"</span><span style="color: rgba(255, 0, 0, 1)"> parameterType</span><span style="color: rgba(0, 0, 255, 1)">="java.lang.Integer"</span><span style="color: rgba(255, 0, 0, 1)"> resultType</span><span style="color: rgba(0, 0, 255, 1)">="cn.itheima.pojo.User"</span><span style="color: rgba(0, 0, 255, 1)">></span><span style="color: rgba(0, 0, 0, 1)"> select * from user where id=#{id} </span><span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">select</span><span style="color: rgba(0, 0, 255, 1)">></span> <span style="color: rgba(0, 128, 0, 1)"><!--</span><span style="color: rgba(0, 128, 0, 1)"> 如果返回结果为集合,可以调用selectList方法,这个方法返回的结果就是一个集合,所以映射文件中应该配置成集合泛型的类型 ${}拼接符:字符串原样拼接,如果传入的参数是基本类型(string,long,double,int,boolean,float等),那么${}中的变量名称必须是value 注意:拼接符有sql注入的风险,所以慎重使用 </span><span style="color: rgba(0, 128, 0, 1)">--></span> <span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">select </span><span style="color: rgba(255, 0, 0, 1)">id</span><span style="color: rgba(0, 0, 255, 1)">="findUserByUserName"</span><span style="color: rgba(255, 0, 0, 1)"> parameterType</span><span style="color: rgba(0, 0, 255, 1)">="java.lang.String"</span><span style="color: rgba(255, 0, 0, 1)"> resultType</span><span style="color: rgba(0, 0, 255, 1)">="cn.itheima.pojo.User"</span><span style="color: rgba(0, 0, 255, 1)">></span><span style="color: rgba(0, 0, 0, 1)"> select * from user where username like '%${value}%' </span><span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">select</span><span style="color: rgba(0, 0, 255, 1)">></span> <span style="color: rgba(0, 128, 0, 1)"><!--</span><span style="color: rgba(0, 128, 0, 1)"> #{}:如果传入的是pojo类型,那么#{}中的变量名称必须是pojo中对应的属性.属性.属性..... 如果要返回数据库自增主键:可以使用select LAST_INSERT_ID() </span><span style="color: rgba(0, 128, 0, 1)">--></span> <span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">insert </span><span style="color: rgba(255, 0, 0, 1)">id</span><span style="color: rgba(0, 0, 255, 1)">="insertUser"</span><span style="color: rgba(255, 0, 0, 1)"> parameterType</span><span style="color: rgba(0, 0, 255, 1)">="cn.itheima.pojo.User"</span> <span style="color: rgba(0, 0, 255, 1)">></span> <span style="color: rgba(0, 128, 0, 1)"><!--</span><span style="color: rgba(0, 128, 0, 1)"> 执行 select LAST_INSERT_ID()数据库函数,返回自增的主键 keyProperty:将返回的主键放入传入参数的Id中保存. order:当前函数相对于insert语句的执行顺序,在insert前执行是before,在insert后执行是AFTER resultType:id的类型,也就是keyproperties中属性的类型 </span><span style="color: rgba(0, 128, 0, 1)">--></span> <span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">selectKey </span><span style="color: rgba(255, 0, 0, 1)">keyProperty</span><span style="color: rgba(0, 0, 255, 1)">="id"</span><span style="color: rgba(255, 0, 0, 1)"> order</span><span style="color: rgba(0, 0, 255, 1)">="AFTER"</span><span style="color: rgba(255, 0, 0, 1)"> resultType</span><span style="color: rgba(0, 0, 255, 1)">="java.lang.Integer"</span><span style="color: rgba(0, 0, 255, 1)">></span><span style="color: rgba(0, 0, 0, 1)"> select LAST_INSERT_ID() </span><span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">selectKey</span><span style="color: rgba(0, 0, 255, 1)">></span><span style="color: rgba(0, 0, 0, 1)"> insert into user (username,birthday,sex,address) values(#{username},#{birthday},#{sex},#{address}) </span><span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">insert</span><span style="color: rgba(0, 0, 255, 1)">></span> <span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">delete </span><span style="color: rgba(255, 0, 0, 1)">id</span><span style="color: rgba(0, 0, 255, 1)">="delUserById"</span><span style="color: rgba(255, 0, 0, 1)"> parameterType</span><span style="color: rgba(0, 0, 255, 1)">="int"</span><span style="color: rgba(0, 0, 255, 1)">></span><span style="color: rgba(0, 0, 0, 1)"> delete from user where id=#{id} </span><span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">delete</span><span style="color: rgba(0, 0, 255, 1)">></span> <span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">update </span><span style="color: rgba(255, 0, 0, 1)">id</span><span style="color: rgba(0, 0, 255, 1)">="updateUserById"</span><span style="color: rgba(255, 0, 0, 1)"> parameterType</span><span style="color: rgba(0, 0, 255, 1)">="cn.itheima.pojo.User"</span><span style="color: rgba(0, 0, 255, 1)">></span><span style="color: rgba(0, 0, 0, 1)"> update user set username=#{username} where id=#{id} </span><span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">update</span><span style="color: rgba(0, 0, 255, 1)">></span>
</mapper>
加载映射文件 --mybatis 框架需要加载映射文件,将 User.xml 添加在 SqlMapConfig.xml
<!-- 加载映射文件 --> <mappers> <mapper resource="User.xml" /> </mappers>
创建测试类 UserTest 进行测试
查询单个 User 对象
@Test public void test1() throws IOException { // 核心配置文件 String resource = "SqlMapConfig.xml"; // 通过流将核心配置文件加载进来 InputStream inputStream = Resources.getResourceAsStream(resource); // 通过配置文件创建会话工厂 SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream); // 通过会话工厂获取会话 SqlSession openSession = factory.openSession(); // 通过会话执行 sql 第一个参数是名称空间 +SqlID 第二个参数表示 sql 执行需要的参数 User user = openSession.selectOne("test.findUserById", 1); System.out.println(user.toString()); // 关闭会话 openSession.close();}</span></pre>
通过 username 进行模糊查询
@Test public void test2() throws IOException { // 核心配置文件 String resource = "SqlMapConfig.xml"; // 通过流将核心配置文件加载进来 InputStream inputStream = Resources.getResourceAsStream(resource); // 通过配置文件创建会话工厂 SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream); // 通过会话工厂获取会话 SqlSession openSession = factory.openSession(); // 调用 User.xml 中的魔化查询方法 返回集合 List<User> selectList = openSession.selectList("test.findUserByName", "张"); // 循环结果 System.out.println(selectList.size()); for (User user : selectList) {System.out.println(user.toString()); } // 关闭会话 openSession.close();}
添加一条 User 用户到数据库
@Test public void test3() throws IOException { // 核心配置文件 String resource = "SqlMapConfig.xml"; // 通过流将核心配置文件加载进来 InputStream inputStream = Resources.getResourceAsStream(resource); // 通过配置文件创建会话工厂 SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream); // 通过会话工厂获取会话 SqlSession openSession = factory.openSession(); // 创建需要插入的 User 对象 User user = new User(); user.setUsername("Jimisun"); user.setSex("1"); user.setAddress("北京"); System.out.println("==== 插入前的 User 的 id=" + user.getId()); // 会话调用插入的 sql openSession.insert("test.insertUser", user); // 默认 mybatis 自动开启事务, 需要手动提交事务 openSession.commit(); System.out.println("==== 插入后的 User 的 id=" + user.getId()); // 关闭会话 openSession.close();}
删除一条记录
@Test public void test4() throws IOException { // 核心配置文件 String resource = "SqlMapConfig.xml"; // 通过流将核心配置文件加载进来 InputStream inputStream = Resources.getResourceAsStream(resource); // 通过配置文件创建会话工厂 SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream); // 通过会话工厂获取会话 SqlSession openSession = factory.openSession(); // 会话执行 sql 操作 openSession.delete("test.deleteUserById", 1); // 提交事务 openSession.commit(); // 关闭会话 openSession.close();}
更新一条记录
@Test public void test5() throws Exception { // 核心配置文件 String resource = "SqlMapConfig.xml"; // 通过流将核心配置文件加载进来 InputStream inputStream = Resources.getResourceAsStream(resource); // 通过配置文件创建会话工厂 SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream); // 通过会话工厂获取会话 SqlSession openSession = factory.openSession(); //创建 User 对象 User user = new User (); user.setId(1); user.setUsername("王麻子"); openSession.update("test.updateByUserId", user); //提交事务 openSession.commit(); //关闭会话 openSession.close();}</span></pre>
5. 使用 MyBatis 的开发方法
- 原生 Dao 方法
- UserDao 接口
- UserDaoImpl 实现类
- findUserById() ----- 方法内使用 MyBatis 框架进行操作
// 核心配置文件 String resource = "SqlMapConfig.xml"; // 通过流将核心配置文件加载进来 InputStream inputStream = Resources.getResourceAsStream(resource); // 通过配置文件创建会话工厂 SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream); // 通过会话工厂获取会话 SqlSession openSession = factory.openSession(); // 通过会话执行 sql 第一个参数是名称空间 +SqlID 第二个参数表示 sql 执行需要的参数 User user = openSession.selectOne("test.findUserById", 1); System.out.println(user.toString()); // 关闭会话 openSession.close();
- findUserById() ----- 方法内使用 MyBatis 框架进行操作
- Mapper 接口开发 ----Mapper 接口开发方法只需要程序员编写 Mapper 接口(相当于 Dao 接口),由Mybatis 框架根据接口定义创建接口的动态代理对象,代理对象的方法体同上边 Dao 接口实现类方法。
- 开发规范
-
Mapper.xml 文件中的 namespace 与 mapper 接口的类路径相同。
- Mapper 接口方法名和 Mapper.xml 中定义的每个 statement 的 id 相同
-
Mapper 接口方法的输入参数类型和 mapper.xml 中定义的每个 sql 的 parameterType 的类型相同
-
Mapper 接口方法的输出参数类型和 mapper.xml 中定义的每个 sql 的 resultType 的类型相同
-
- 开发目录
- UserDao 接口 遵循上面规则
- UserServiceImpl 直接调用
@Test public void testFindUserById() throws Exception{ SqlSession openSession = factory.openSession(); //通过 getMapper 方法来实例化接口 UserMapper mapper = openSession.getMapper(UserMapper.class);
User user </span>= mapper.findUserById(1<span style="color: rgba(0, 0, 0, 1)">); System.out.println(user); }</span></pre>
- 开发规范
6.SqlMapConfig.xml 配置文件
- properties(属性) 常用于加载配置文件
<properties resource="db.properties"></properties> <environments default="development"> <environment id="development"> <!-- 使用 jdbc 事务管理--> <transactionManager type="JDBC" /> <!-- 数据库连接池--> <dataSource type="POOLED"> <property name="driver" value="${jdbc.driver}" /> <property name="url" value="${jdbc.url}" /> <property name="username" value="${jdbc.username}" /> <property name="password" value="${jdbc.password}" /> </dataSource> </environment> </environments>
-
typeAliases(类型别名)
<typeAliases> <!-- 定义单个 pojo 类别名 type: 类的全路劲名称 alias: 别名 --> <typeAlias type="cn.itheima.pojo.User" alias="user"/>
<span style="color: rgba(0, 128, 0, 1)"><!--</span><span style="color: rgba(0, 128, 0, 1)"> 使用包扫描的方式批量定义别名 定以后别名等于类名,不区分大小写,但是建议按照java命名规则来,首字母小写,以后每个单词的首字母大写 </span><span style="color: rgba(0, 128, 0, 1)">--></span> <span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">package </span><span style="color: rgba(255, 0, 0, 1)">name</span><span style="color: rgba(0, 0, 255, 1)">="cn.itheima.pojo"</span><span style="color: rgba(0, 0, 255, 1)">/></span> <span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">typeAliases</span><span style="color: rgba(0, 0, 255, 1)">></span></pre>
-
mappers(映射器)
- 相对于类路径的资源
<mapper resource="sqlmap/User.xml" />
- 使用 mapper 接口开发
<mapper class="cn.redrat.mybatis.mapper.UserMapper"/>
- 注册指定包下所有的 mapper 接口
<package name="cn.redrat.mybatis.mapper"/>
- 注意:此种方法要求 mapper 接口名称和 mapper 映射文件名称相同,且放在同一个目录中。
- 相对于类路径的资源
7. 输入映射和输出映射
- Mapper.xml 映射文件中定义了操作数据库的 sql,每个 sql 是一个 statement,映射文件是 mybatis 的核心。
-
parameterType(输入类型)
- 传递基本类型包含 String
- 传递 pojo 对象
- 传递 vo 对象
-
resultType(输出类型)
- 返回 pojo 类型
- 返回集合
- 返回基本类型包含 String
-
8. 动态 Sql -- 通过 mybatis 提供的各种标签方法实现动态拼接 sql
- if
<!-- 传递 pojo 综合查询用户信息 注意要做不等于空字符串校验--> <select id="findUserList" parameterType="user" resultType="user"> select * from user where 1=1 <if test="id!=null"> and id=#{id} </if> <if test="username!=null and username!=''"> and username like '%${username}%' </if> </select>
- where
<select id="findUserList" parameterType="user" resultType="user"> select * from user <where> <if test="id!=null and id!=''"> and id=#{id} </if> <if test="username!=null and username!=''"> and username like '%${username}%' </if> </where> </select
where 标签的作用可以去掉 sql 语句中的 where 1=1 并自动处理第一个 and
- foreach
<select id="findUserByIds" parameterType="cn.redrat.pojo.QueryVo" resultType="cn.redrat.pojo.User"> select * from user <where> <if test="ids != null"> <!-- foreach: 循环传入的集合参数 collection: 传入的集合的变量名称 item: 每次循环将循环出的数据放入这个变量中 open: 循环开始拼接的字符串 close: 循环结束拼接的字符串 separator: 循环中拼接的分隔符 --> <foreach collection="ids" item="id" open="id in (" close=")" separator=","> #{id} </foreach> </if> </where> </select>
9.MyBatis 关联查询核心示例
- 一对一查询
<!-- 一对一: 自动映射 --> <select id="findOrdersAndUser1" resultType="cn.redrat.pojo.CustomOrders"> select a.*, b.id uid, username, birthday, sex, address from orders a, user b where a.user_id = b.id </select>
<span style="color: rgba(0, 128, 0, 1)"><!--</span><span style="color: rgba(0, 128, 0, 1)"> 一对一:手动映射 </span><span style="color: rgba(0, 128, 0, 1)">--></span> <span style="color: rgba(0, 128, 0, 1)"><!--</span><span style="color: rgba(0, 128, 0, 1)"> id:resultMap的唯一标识 type:将查询出的数据放入这个指定的对象中 注意:手动映射需要指定数据库中表的字段名与java中pojo类的属性名称的对应关系 </span><span style="color: rgba(0, 128, 0, 1)">--></span> <span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">resultMap </span><span style="color: rgba(255, 0, 0, 1)">type</span><span style="color: rgba(0, 0, 255, 1)">="cn.<span style="color: rgba(0, 0, 255, 1)">redrat</span>.pojo.Orders"</span><span style="color: rgba(255, 0, 0, 1)"> id</span><span style="color: rgba(0, 0, 255, 1)">="orderAndUserResultMap"</span><span style="color: rgba(0, 0, 255, 1)">></span> <span style="color: rgba(0, 128, 0, 1)"><!--</span><span style="color: rgba(0, 128, 0, 1)"> id标签指定主键字段对应关系 column:列,数据库中的字段名称 property:属性,java中pojo中的属性名称 </span><span style="color: rgba(0, 128, 0, 1)">--></span> <span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">id </span><span style="color: rgba(255, 0, 0, 1)">column</span><span style="color: rgba(0, 0, 255, 1)">="id"</span><span style="color: rgba(255, 0, 0, 1)"> property</span><span style="color: rgba(0, 0, 255, 1)">="id"</span><span style="color: rgba(0, 0, 255, 1)">/></span> <span style="color: rgba(0, 128, 0, 1)"><!--</span><span style="color: rgba(0, 128, 0, 1)"> result:标签指定非主键字段的对应关系 </span><span style="color: rgba(0, 128, 0, 1)">--></span> <span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">result </span><span style="color: rgba(255, 0, 0, 1)">column</span><span style="color: rgba(0, 0, 255, 1)">="user_id"</span><span style="color: rgba(255, 0, 0, 1)"> property</span><span style="color: rgba(0, 0, 255, 1)">="userId"</span><span style="color: rgba(0, 0, 255, 1)">/></span> <span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">result </span><span style="color: rgba(255, 0, 0, 1)">column</span><span style="color: rgba(0, 0, 255, 1)">="number"</span><span style="color: rgba(255, 0, 0, 1)"> property</span><span style="color: rgba(0, 0, 255, 1)">="number"</span><span style="color: rgba(0, 0, 255, 1)">/></span> <span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">result </span><span style="color: rgba(255, 0, 0, 1)">column</span><span style="color: rgba(0, 0, 255, 1)">="createtime"</span><span style="color: rgba(255, 0, 0, 1)"> property</span><span style="color: rgba(0, 0, 255, 1)">="createtime"</span><span style="color: rgba(0, 0, 255, 1)">/></span> <span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">result </span><span style="color: rgba(255, 0, 0, 1)">column</span><span style="color: rgba(0, 0, 255, 1)">="note"</span><span style="color: rgba(255, 0, 0, 1)"> property</span><span style="color: rgba(0, 0, 255, 1)">="note"</span><span style="color: rgba(0, 0, 255, 1)">/></span> <span style="color: rgba(0, 128, 0, 1)"><!--</span><span style="color: rgba(0, 128, 0, 1)"> 这个标签指定单个对象的对应关系 property:指定将数据放入Orders中的user属性中 javaType:user属性的类型 </span><span style="color: rgba(0, 128, 0, 1)">--></span> <span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">association </span><span style="color: rgba(255, 0, 0, 1)">property</span><span style="color: rgba(0, 0, 255, 1)">="user"</span><span style="color: rgba(255, 0, 0, 1)"> javaType</span><span style="color: rgba(0, 0, 255, 1)">="cn.<span style="color: rgba(0, 0, 255, 1)">redrat</span>.pojo.User"</span><span style="color: rgba(0, 0, 255, 1)">></span> <span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">id </span><span style="color: rgba(255, 0, 0, 1)">column</span><span style="color: rgba(0, 0, 255, 1)">="uid"</span><span style="color: rgba(255, 0, 0, 1)"> property</span><span style="color: rgba(0, 0, 255, 1)">="id"</span><span style="color: rgba(0, 0, 255, 1)">/></span> <span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">result </span><span style="color: rgba(255, 0, 0, 1)">column</span><span style="color: rgba(0, 0, 255, 1)">="username"</span><span style="color: rgba(255, 0, 0, 1)"> property</span><span style="color: rgba(0, 0, 255, 1)">="username"</span><span style="color: rgba(0, 0, 255, 1)">/></span> <span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">result </span><span style="color: rgba(255, 0, 0, 1)">column</span><span style="color: rgba(0, 0, 255, 1)">="birthday"</span><span style="color: rgba(255, 0, 0, 1)"> property</span><span style="color: rgba(0, 0, 255, 1)">="birthday"</span><span style="color: rgba(0, 0, 255, 1)">/></span> <span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">result </span><span style="color: rgba(255, 0, 0, 1)">column</span><span style="color: rgba(0, 0, 255, 1)">="sex"</span><span style="color: rgba(255, 0, 0, 1)"> property</span><span style="color: rgba(0, 0, 255, 1)">="sex"</span><span style="color: rgba(0, 0, 255, 1)">/></span> <span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">result </span><span style="color: rgba(255, 0, 0, 1)">column</span><span style="color: rgba(0, 0, 255, 1)">="address"</span><span style="color: rgba(255, 0, 0, 1)"> property</span><span style="color: rgba(0, 0, 255, 1)">="address"</span><span style="color: rgba(0, 0, 255, 1)">/></span> <span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">association</span><span style="color: rgba(0, 0, 255, 1)">></span> <span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">resultMap</span><span style="color: rgba(0, 0, 255, 1)">></span> <span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">select </span><span style="color: rgba(255, 0, 0, 1)">id</span><span style="color: rgba(0, 0, 255, 1)">="findOrdersAndUser2"</span><span style="color: rgba(255, 0, 0, 1)"> resultMap</span><span style="color: rgba(0, 0, 255, 1)">="orderAndUserResultMap"</span><span style="color: rgba(0, 0, 255, 1)">></span><span style="color: rgba(0, 0, 0, 1)"> select a.*, b.id uid, username, birthday, sex, address from orders a, user b where a.user_id = b.id </span><span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">select</span><span style="color: rgba(0, 0, 255, 1)">></span></pre>
- 一对多
<resultMap type="cn.redrat.pojo.User" id="userAndOrdersResultMap"> <id column="id" property="id"/> <result column="username" property="username"/> <result column="birthday" property="birthday"/> <result column="sex" property="sex"/> <result column="address" property="address"/>
<span style="color: rgba(0, 128, 0, 1)"><!--</span><span style="color: rgba(0, 128, 0, 1)"> 指定对应的集合对象关系映射 property:将数据放入User对象中的ordersList属性中 ofType:指定ordersList属性的泛型类型 </span><span style="color: rgba(0, 128, 0, 1)">--></span> <span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">collection </span><span style="color: rgba(255, 0, 0, 1)">property</span><span style="color: rgba(0, 0, 255, 1)">="ordersList"</span><span style="color: rgba(255, 0, 0, 1)"> ofType</span><span style="color: rgba(0, 0, 255, 1)">="cn.<span style="color: rgba(0, 0, 255, 1)">redrat</span>.pojo.Orders"</span><span style="color: rgba(0, 0, 255, 1)">></span> <span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">id </span><span style="color: rgba(255, 0, 0, 1)">column</span><span style="color: rgba(0, 0, 255, 1)">="oid"</span><span style="color: rgba(255, 0, 0, 1)"> property</span><span style="color: rgba(0, 0, 255, 1)">="id"</span><span style="color: rgba(0, 0, 255, 1)">/></span> <span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">result </span><span style="color: rgba(255, 0, 0, 1)">column</span><span style="color: rgba(0, 0, 255, 1)">="user_id"</span><span style="color: rgba(255, 0, 0, 1)"> property</span><span style="color: rgba(0, 0, 255, 1)">="userId"</span><span style="color: rgba(0, 0, 255, 1)">/></span> <span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">result </span><span style="color: rgba(255, 0, 0, 1)">column</span><span style="color: rgba(0, 0, 255, 1)">="number"</span><span style="color: rgba(255, 0, 0, 1)"> property</span><span style="color: rgba(0, 0, 255, 1)">="number"</span><span style="color: rgba(0, 0, 255, 1)">/></span> <span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">result </span><span style="color: rgba(255, 0, 0, 1)">column</span><span style="color: rgba(0, 0, 255, 1)">="createtime"</span><span style="color: rgba(255, 0, 0, 1)"> property</span><span style="color: rgba(0, 0, 255, 1)">="createtime"</span><span style="color: rgba(0, 0, 255, 1)">/></span> <span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">collection</span><span style="color: rgba(0, 0, 255, 1)">></span> <span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">resultMap</span><span style="color: rgba(0, 0, 255, 1)">></span> <span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">select </span><span style="color: rgba(255, 0, 0, 1)">id</span><span style="color: rgba(0, 0, 255, 1)">="findUserAndOrders"</span><span style="color: rgba(255, 0, 0, 1)"> resultMap</span><span style="color: rgba(0, 0, 255, 1)">="userAndOrdersResultMap"</span><span style="color: rgba(0, 0, 255, 1)">></span><span style="color: rgba(0, 0, 0, 1)"> select a.*, b.id oid ,user_id, number, createtime from user a, orders b where a.id = b.user_id </span><span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">select</span><span style="color: rgba(0, 0, 255, 1)">></span></pre>