1. 输入输出映射
Mapper.xml映射文件中定义了操作数据库的sql,每个sql是一个statement,映射文件是mybatis的核心。
1.1 输入参数映射parameterType
1.1.1 传递简单类型
使用#{}占位符,或者${}字符串拼接指令进行sql拼接
1.1.2 传递pojo对象
mybatis中使用ognl表达式解析对象字段的值,#{}或者${}括号中的值为pojo属性
1.1.3 传递pojo包装对象
所谓pojo的包装对象,意思是说对象中包含对象,例如:
public class QueryPojo {
private User user;
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}
QueryPojo对象就是pojo包装对象。
应用场景:
1. pojo包装对象一般用作查询条件
2. 查询条件可能是综合的查询条件即不仅包含A的查询条件还包括B的查询条件
<select id="getUserByQueryVo" parameterType="querypojo" resultType="com.bjc.mybatis.pojo.User">
SELECT id,
`username`,
birthday,
sex,
address
FROM user
where `username` like '%${user.username}%'
</select>
1.2 resultType输出映射
resultType可以指定将查询结果映射为pojo,但是需要pojo的属性名和sql查询的列名一致方可映射成功。
1.2.1 输出简单类型
直接在<resultType>标签的属性值写简单类型的全路径名或者短名称即可
<select id="getUsesCount" resultType="int">
SELECT count(1) FROM user
</select>
注意:输出简单必须查询出来的结果集有一条记录,最终将第一个字段的值转换为输出类型。
1.2.2 输出pojo对象
<select id="getUserByID" parameterType="int" resultType="com.bjc.mybatis.pojo.User">
SELECT id,
username,
birthday,
sex,
address
FROM user
where id = #{id}
</select>
接口:
User getUserByID(Integer id);
1.2.3 输出pojo列表
<select id="getUserByName" parameterType="string" resultType="com.bjc.mybatis.pojo.User">
SELECT id,
`username`,
birthday,
sex,
address
FROM user
where `username` like '%${value}%'
</select>
接口:
List<User> getUserByName(String username);
1.3 resultMap输出映射
如果sql查询字段名与pojo的属性名不一致,就可以通过resultMap将字段名和属性名作一个对应关系,resultMap实质上还需要将 查询结果映射到pojo对象中。
resultMap还可以实现将查询结果映射为复杂类型的pojo,比如,在查询结果映射对象中包括pojo和list实现一对一查询和一对多查询。
1.3.1 <resultMap>标签介绍
<resultMap type="" id="">
<id property="" column=""/>
<result property="" column=""/>
</resultMap>
1. <resultMap>标签属性:
1.1 type:指定要映射的pojo的类的全路径或者短名称
1.2. id:resultMap的唯一标识
2. <id>标签:配置主键关联映射
2.1 property:pojo的属性名
2.2 column:pojo属性名对应的数据库中的字段名
注意:如果有多个字段name可以定义多个id
3. <result>标签:其他属性的配置
3.1 property:pojo的属性名
3.2 column:pojo属性名对应的数据库字段名称
1.3.2 <resultMap>标签的使用
1. 定义resultMap
<resultMap type="order" id="order_list_map">
<!-- 配置主键关联映射 -->
<id property="orderId" column="order_id"/>
<!-- 配置其他属性与数据库字段映射(普通属性) -->
<result property="spName" column="sp_name"/>
</resultMap>
2. 引用resultMap
<select id="getOrderListMap" resultMap="order_list_map">
SELECT * FROM `ORDER`
</select>
即resultMap的属性值为<resultMap>标签的id属性值
2. 动态sql
2.1 <if>标签
<if test="username != null and username != ''">
username like '%${username}%'
</if>
2.2 <where>标签
<where>
<if test="username != null and username != ''">
and username like '%${username}%'
</if>
</where>
1. <where>标签会自动补上where关键字,同时处理多余的and
2. 如果用了where标签,在sql中就不能显示的在添加where关键字了
2.3 <sql>片段
2.3.1 定义
<sql id="order_cloumn">
id,username,gender,address
</sql>
2.3.2 使用sql片段
<select id="getOrderListMap" resultMap="order_list_map">
SELECT
<include refid="order_cloumn"></include>
FROM `ORDER`
</select>
2.4 <foreach>循环标签
2.4.1 标签属性详解
1. collection:要遍历的集合
2. open:循环开始之前输出的内容
3. item:循环变量
4. separator:循环分隔符
5. close:循环结束之后输出的内容
<select id="getOrderListMap" resultMap="order_list_map">
SELECT
<include refid="order_cloumn"></include>
FROM `ORDER`
<where>
<foreach collection="idList" open="id in (" item = "uId" separator="," close=")">
#{id}
</foreach>
</where>
</select>
3. 关联查询
3.1 一对一关联
3.1.1 方式一:resultType
思路:为了实现一对一关系,我们需要建立两个pojo,A和B,让A继承B,这样A就能拥有B的属性了,然后在sql中通过返回A即可。
例如:
OrderUser
public class OrderUser extends Order {
private String username;
private String address;
…….get,set
}
映射文件:
<!-- 一对一关联查询,使用resultType -->
<select id="getOrderUser" resultType="orderuser">
SELECT
o.`id`,
o.`user_id` userId,
o.`number`,
o.`createtime`,
o.`note`,
u.`username`,
u.`address`
FROM `order` o
LEFT JOIN `user` u
ON u.id = o.`user_id`
</select>
3.1.2 方式二:通过resultMap标签的<association>
思路:
1. 定义一个resultMap
2. 先配置主体表的字段信息
3. 再在association标签中配置关联表字段信息
标签释义:
1. <resultMap>标签用于定义一个返回的映射关系
1.1 type:返回值类型
1.2 id:映射关系的唯一标识
2. <id>标签用于定义属性与主键映射关系
2.1 property:pojo中的属性
2.2 column:pojo对应的属性所对应的表的字段
3. <result>标签用于定义普通属性与表的映射关系
4. <association>标签,用于配置一对一映射关系
4.1 <association>标签属性:
4.1.1 property:对象属性
4.1.2 javaType:对象属性的数据类型,支持别名
4.2 <association>标签子标签:
4.2.1< id>标签:对象属性与对象属性所映射的表的主键映射关系
1. property:属性
2. column:对应的表的字段
4.2.2 <result>标签:普通属性的映射关系
例如:订单对用户是一对一的关系
pojo定义:
order
package com.bjc.mybatis.pojo;
import java.util.Date;
public class Order1 {
private Integer id;
private Integer userId;
private String number;
private Date createtime;
private String note;
private User1 user;
public User1 getUser() {
return user;
}
public void setUser(User1 user) {
this.user = user;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Integer getUserId() {
return userId;
}
public void setUserId(Integer userId) {
this.userId = userId;
}
public String getNumber() {
return number;
}
public void setNumber(String number) {
this.number = number;
}
public Date getCreatetime() {
return createtime;
}
public void setCreatetime(Date createtime) {
this.createtime = createtime;
}
public String getNote() {
return note;
}
public void setNote(String note) {
this.note = note;
}
@Override
public String toString() {
return "Order1 [id=" + id + ", userId=" + userId + ", number=" + number + ", createtime=" + createtime
+ ", note=" + note + ", user=" + user + "]";
}
}
user
package com.bjc.mybatis.pojo;
import java.util.Date;
public class User1 {
private Integer id;
private String username;// 用户姓名
private String sex;// 性别
private Date birthday;// 生日
private String address;// 地址
private String uuid2;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getUuid2() {
return uuid2;
}
public void setUuid2(String uuid2) {
this.uuid2 = uuid2;
}
@Override
public String toString() {
return "User1 [id=" + id + ", username=" + username + ", sex=" + sex + ", birthday=" + birthday + ", address="
+ address + ", uuid2=" + uuid2 + "]";
}
}
接口定义:
package com.bjc.mybatis.mapper;
import java.util.List;
import com.bjc.mybatis.pojo.Order1;
public interface OrderMapper1 {
public List<Order1> getOrder();
}
映射配置文件:
<?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.bjc.mybatis.mapper.OrderMapper1">
<!-- 定义resultMap -->
<resultMap type="com.bjc.mybatis.pojo.Order1" id="order_user">
<!-- 定义order表与order属性关联关系 -->
<id property="id" column="id"/>
<result property="userId" column="user_id"/>
<result property="number" column="number"/>
<result property="createtime" column="createtime"/>
<result property="note" column="note"/>
<!-- 定义一对一关系 -->
<association property="user" javaType="com.bjc.mybatis.pojo.User1">
<!-- 配置关联对象user与user表的关系 -->
<id property="id" column="user_id"/> <!-- 这里user_id为外键,所以可以直接使用 -->
<result property="username" column="username"/>
<result property="sex" column="sex"/>
<result property="birthday" column="birthday"/>
<result property="address" column="address"/>
<result property="uuid2" column="uuid2"/>
</association>
</resultMap>
<select id="getOrder" resultMap="order_user">
SELECT
t.id,
t.user_id,
t.number,
t.createtime,
t.note,
t1.username,
t1.birthday,
t1.sex,
t1.address,
t1.uuid2
FROM `order` t
LEFT JOIN `user` t1 ON t.user_id = t1.id
</select>
</mapper>
测试方法:
@Test
public void test002(){
SqlSession openSession = SqlSessionFactoryUtils.getSqlSessionFactory().openSession();
// 获取接口的代理人的实现类
OrderMapper1 mapper = openSession.getMapper(OrderMapper1.class);
List<Order1> orderList = mapper.getOrder();
orderList.forEach(item -> {
System.out.println(item);
});
}
注意:这里配置user的关联关系的时候,为什么要用<id property="id" column="user_id"/>了?因为,在订单表中user_id就是user表的id值,我们在查询语句中有查询user_id,所以这里就可以使用user_id来做为column的属性值了。如果,这里column写id,会怎么样了?还是可以关联出来,但是这个id就表示order表的id了,所以,这里需要写user_id
3.2 一对多关联
3.2.1 思路:
1. 定义一个resultMap
2. 先配置主体表的字段信息
3. 再在collection标签中配置一对多关联关系
3.2.2 标签详述
1. 基本上与一对一一样
2. 配置一对多关联用<collection>标签
3. 属性对象类型用ofType属性,也支持别名
例如:用户与订单是一对多的关系
<resultMap type="com.bjc.mybatis.pojo.User1" id="user_order">
<!-- 定义user表与user属性关联关系 -->
<id property="id" column="id"/>
<result property="username" column="username"/>
<result property="sex" column="sex"/>
<result property="birthday" column="birthday"/>
<result property="address" column="address"/>
<result property="uuid2" column="uuid2"/>
<!-- 定义一对一关系 -->
<collection property="orders" ofType="com.bjc.mybatis.pojo.Order1">
<id property="id" column="oid"/>
<result property="userId" column="user_id"/>
<result property="number" column="number"/>
<result property="createtime" column="createtime"/>
<result property="note" column="note"/>
</collection>
</resultMap>
3.2.3 用户与订单用例
1. pojo类
user
package com.bjc.mybatis.pojo;
import java.util.Date;
import java.util.List;
public class User1 {
private Integer id;
private String username;// 用户姓名
private String sex;// 性别
private Date birthday;// 生日
private String address;// 地址
private String uuid2;
private List<Order1> orders;
public List<Order1> getOrders() {
return orders;
}
public void setOrders(List<Order1> orders) {
this.orders = orders;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getUuid2() {
return uuid2;
}
public void setUuid2(String uuid2) {
this.uuid2 = uuid2;
}
@Override
public String toString() {
return "User1 [id=" + id + ", username=" + username + ", sex=" + sex + ", birthday=" + birthday + ", address="
+ address + ", uuid2=" + uuid2 + ", orders=" + orders + "]";
}
}
order
package com.bjc.mybatis.pojo;
import java.util.Date;
public class Order1 {
private Integer id;
private Integer userId;
private String number;
private Date createtime;
private String note;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Integer getUserId() {
return userId;
}
public void setUserId(Integer userId) {
this.userId = userId;
}
public String getNumber() {
return number;
}
public void setNumber(String number) {
this.number = number;
}
public Date getCreatetime() {
return createtime;
}
public void setCreatetime(Date createtime) {
this.createtime = createtime;
}
public String getNote() {
return note;
}
public void setNote(String note) {
this.note = note;
}
@Override
public String toString() {
return "Order1 [id=" + id + ", userId=" + userId + ", number=" + number + ", createtime=" + createtime
+ ", note=" + note + "]";
}
}
2. mapper接口
public interface UserMapper1 {
public List<User1> getUser1();
}
3. 配置文件
<?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.bjc.mybatis.mapper.UserMapper1">
<!-- 定义resultMap -->
<resultMap type="com.bjc.mybatis.pojo.User1" id="user_order">
<!-- 定义user表与user属性关联关系 -->
<id property="id" column="id"/>
<result property="username" column="username"/>
<result property="sex" column="sex"/>
<result property="birthday" column="birthday"/>
<result property="address" column="address"/>
<result property="uuid2" column="uuid2"/>
<!-- 定义一对一关系 -->
<collection property="orders" ofType="com.bjc.mybatis.pojo.Order1">
<id property="id" column="oid"/>
<result property="userId" column="user_id"/>
<result property="number" column="number"/>
<result property="createtime" column="createtime"/>
<result property="note" column="note"/>
</collection>
</resultMap>
<select id="getUser1" resultMap="user_order">
SELECT
t.id,
t.username,
t.birthday,
t.sex,
t.address,
t.uuid2,
t1.id oid,
t1.user_id,
t1.number,
t1.createtime,
t1.note
FROM `user` t
LEFT JOIN `order` t1 ON t1.user_id = t.id
</select>
</mapper>
测试方法
public void test003(){
SqlSession openSession = SqlSessionFactoryUtils.getSqlSessionFactory().openSession();
// 获取接口的代理人的实现类
UserMapper1 mapper = openSession.getMapper(UserMapper1.class);
List<User1> orderList = mapper.getUser1();
orderList.forEach(item -> {
System.out.println(item);
});
}
注意:一对多用的是ofType,一对一用的是JavaType