介绍
MyBatis是一个基于Java的持久层框架,具备长期存储能力,可以使用巨大的磁盘空间存储相当量的数据。
- 持久化:将程序的数据在持久状态和瞬时状态转化的过程
- 持久层:完成持久化框架的代码块
MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。
此外,在MyBatis-Spring中提供了@Mapper注解和@MapperScan注解,用于和Spring进行整合。
为什么使用MyBatis
在传统JDBC中,我们除了提供SQL外,还需要操作Connection、Statment、ResultSet,不仅如此,为了访问不同的表,不同字段的数据,我们需要些很多雷同模板化的代码。而我们在使用了 MyBatis 之后,只需要提供 SQL 语句就好了,其余的诸如:建立连接、操作 Statment、ResultSet,处理 JDBC 相关异常等等都可以交给 MyBatis 去处理,我们的关注点于是可以就此集中在 SQL 语句上,关注在增删改查这些操作层面上。
灵活,SQL写在XML里面,便于统一管理和优化。
解除SQL与程序代码的耦合,将业务逻辑和数据访问逻辑分离,提高了可维护性。
提供映射标签,支持对象与数据库的orm字段关系映射。
提供对象关系映射标签,支持对象关系组建维护。
提供xml标签,支持编写动态sql。
MyBatis程序
代码块
Java
package com.pojo;
public class User {
private Long id;
private String name;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", name=‘" + name + ‘\‘‘ +
‘}‘;
}
}
代码块
Java
package com.dao;
public interface UserDao {
List<User> getUserList();
User getUserById(int id);
int addUser(User user);
int updateUser(User user);
int deleteUser(int id);
}
代码块
XML
<!--UserMapper.xml(mapper配置文件)-->
<?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=绑定一个对应的Dao/Mapper接口-->
<mapper namespace="com.dao.UserDao">
<!--id对应Dao里面的方法名字-->
<!--resultType是前面User类的路径-->
<select id="getUserList" resultType="com.pojo.User">
select * from user
</select>
<select id="getUserById" parameterType="int" resultType="com.pojo.User">
select * from user where id = #{id}
</select>
<!--对象中的属性,可以直接取出来 eg:id,name-->
<insert id="addUser" parameterType="com.pojo.User">
insert into user (id, name) values (#{id}, #{name});
</insert>
<update id="updateUser" parameterType="com.pojo.User">
update user set name=#{name} where id=#{id};
</update>
<!--parameter="int"等类型时可以省略-->
<delete id="deleteUser" parameter="int">
delete from user where id=#{id};
</delete>
</mapper>
XML映射器
1. namespace
namespace中的包名要和dao/mapper接口的包名一致
2. select,insert,update,delete
- id是对应的namespace中的方法名
- resultType:SQL语句执行的返回值。
- parameterType:参数类型
动态SQL
用于拼接SQL语句
1. if
使用动态 SQL 最常见情景是根据条件包含 where 子句的一部分。
比如:想利用两个参数进行可选搜索
代码块
XML
<!--SELECT * FROM User WHERE name="Lisa" AND id=1;-->
<select id="queryUser" resultType="com.pojo.User">
select * from user where
<if test="name != null">
name = #{name}
</if>
<if test="id != null">
id = #{id}
</if>
</select>
2. choose,when,otherwise
不想使用所有条件的时候,想从多个条件中选择一个使用,类似Java中的switch语句
eg:传入了id就按id查找,传入了name就按name查找,如果两者都没有传入,就返回age为23的User
代码块
XML
<select id="queryUser" resultType="User">
select * from user where
<choose>
<when test="id != null">
id = #{id}
</when>
<when test="name != null">
name = #{name}
</when>
<otherwise>
age = 23
</otherwise>
</choose>
</select>
3. where
上述情况会出现变量都没有传入的情况,导致查询失败
做如下调整:
代码块
XML
<select id="queryUser" resultType="com.pojo.User">
select * from user
<where>
<if test="name != null">
name = #{name}
</if>
<if test="age != null">
and age = #{age}
</if>
</where>
</select>
where 元素只会在子元素返回任何内容的情况下才插入 “WHERE” 子句。而且,若子句的开头为 “AND” 或 “OR”,where 元素也会将它们去除。
4. set
用于动态更新语句的类似解决方案是set,set元素可以用于动态包含需要更新的列,忽略其他不更新的列
代码块
XML
<update id="updateUser">
update User
<set>
<if test="name != null">
name = #{name},
</if>
<if test="age != null">
age = #{age}
</if>
</set>
where id=#{id}
</update>
5. trim,prefix,prefixOverrides,suffix,suffixOverrides
trim标记是一个格式化的标记,可以完成set或者是where标记的功能
WHERE
代码块
XML
select * from user
<trim prefix="WHERE" prefixOverride="AND |OR "> <!--后面的空格是有存在的必要的-->
<if test="id != null">
AND id= #{id}
</if>
<if test="name != null">
AND name= #{name}
</if>
</trim>
如果id和name都不为null的话,SQL为SELECT * FROM user WHERE id="**" AND name="***"
prefix:在trim标签内sql语句加上前缀。
prefixOverrides:指定去除多余的前缀内容 如:prefixOverrides = "and",去除trim标签内sql语句多余的前缀"and"。
SET
代码块
XML
insert into user
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="id != null">
id,
</if>
<if test="name != null">
name,
</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="id != null">
#{id,jdbcType=BIGINT},
</if>
<if test="name != null">
#{name. jdbcType=VARCHAR},
</if>
</trim>
suffix:在trim标签内sql语句加上后缀。
suffixOverrides:指定去除多余的后缀内容,如:suffixOverrides=",",去除trim标签内sql语句多余的后缀","。
6. inclue refid & resultMap
1、首先定义一个sql标签,一定要定义唯一id
2、然后通过id引用
<select id="selectAll"> select <include refid="Base_Column_List" /> from 表名 </select>
resultMap可以将查询到的复杂数据(比如查询到几个表中数据)映射到一个结果集当中。
eg:
代码块
XML
<resultMap id="BaseResultMap" type="com.pojo.User">
<id column="id" jdbcType="BIGINT" property="id" />
<result column="name" jdbcType="VARCHAR" property="name" />
<result column="age" jdbcType="INTEGER" property="age" />
</resultMap>
<sql id="Base_Column_List">
id, name, age
</sql>
<select id="queryUser" resultMap="BaseResultMap">
select
<include refid="Base_Column_List" />
from user
where id = #{id,jdbcType=BIGINT}
order by id desc
<if test="pageNum != null and pageSize != null">
limit ${pageNum*pageSize}, #{pageSize}
<!--limit两个参数,第一个表示从第几行数据开始查,第二个表示查几条数据-->
</if>
</select>