关于数据库和mybatis的mapper关系

MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJOs(Plain Ordinary Java Object,普通的 Java对象)映射成数据库中的记录。

关于数据库mybatis的mapper关系

原文地址

这里说明一下关于数据库,数据库对应实体各种复杂情况关系映射。
最基本的实体:
比如:(这里面不涉及复杂map,list,set等)

1
2
3
4
5
6
7
8
9
10
11
12
@Data
@Getter
@Setter
@Component
public class TestUser {

private Integer testUserNo;

private String testUserName;

private String testUserSex;
}

数据库:
在这里插入图片描述
resultMap最终将数据库查出的结果,映射到pojo(实体)上
type是指定映射到哪一个实体;id是相对应的resultMap的id

这里有两种属性,主键属性和普通属性
1,主键属性方式(是主键)
user_no是主键:

1
<id property="testUserNo" column="user_no"/>

2,普通属性(即不是主键)
user_name不是主键

1
<result property="testUserName" column="user_name"/>

完整的mapper.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://www.mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- namespace是对应的定义方法mapper,会去拿到对应的geTestUsers方法。这样才建立起了输入,返回的对应的关系 -->
<mapper namespace="com.cun.mapper.TestUserMapper">
<resultMap type="com.cun.entity.TestUser" id="TestUser">
<!-- property是对应的实体属性,column是对应的数据库column项-->
<id property="testUserNo" column="user_no"/>
<result property="testUserName" column="user_name"/>
<result property="testUserSex" column="user_sex"/>
</resultMap>

<select id="geTestUsers" resultMap="TestUser">
select * from test_user
</select>
</mapper>

在我们深入更加复杂情况前,我们需要了解mapper3.0下常用的标签。我们从mapper开始讲起。
mapper: 是总标签,所有标签都包含在内。
namespace:命名空间。如果采用的是Mapper接口代理的方式开发,Mapper的映射文件中namespace必须为接口的全名,比如这里namespace=“com.cun.mapper.TestUserMapper”。
在这里插入图片描述
最常见的增删改查select,insert,update,delete。

1
2
3
4
5
6
7
8
9
10
11
12
13
<?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="Mapper.EmpMapper">
// CURD操作标签
// 查 parameterType入参类型 resultType返回类型 id是唯一标识符
<select id="" parameterType="" resultType=""> </select>
<insert id="" parameterType=""> </insert>
<delete id="" parameterType=""> </delete>
<update id="" parameterType=""> </update>
// if片段
</mapper>

每一个其中的内含标签:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
下面逐一介绍其中的Content Model(内容模型)
selectKey : 标签表示子查询中主键的提取问题
它其中的标记:
keyColumn表示查询语句返回结果的列名
keyProperty表示将属性设置到某个列中
order=”BEFORE表示在插入语句之前执行
resultType=”int”表示返回值得类型为int类型
在这里插入图片描述
include:引入定义号的公共sql
这里不得不的引入另一个标签sql,因为这两者搭配使用。
例子:(通常用于有一段sql文,很长而且重复多次使用,我们把它抽象出来,之后直接引用)

1
2
3
4
5
6
7
8
9
<!--1、首先定义一个sql标签,一定要定义唯一id。(name,age是要查询的字段)-->
<sql id="Base_Column_List" >name,age</sql>
<!--2、然后通过id引用-->
<select id="selectAll">
select
<include refid="Base_Column_List" />
from student
</select>
<!--这个<include refid="Base_Column_List" />会自动把上面的代码贴过来。-->

trim : (这个不常用)
prefix:前缀;suffix:后缀
prefixOverrides:忽略第一个指定分隔符;suffixOverrides:会略最后一个分隔符。

如果id为null执行的sql语句为:
select * from user where name=“xxx” and gender=“xxx”
where : 主要是用来简化 sql 语句中 where 条件判断,自动地处理 AND/OR 条件。
例子:(并自动地把首个 and / or 给忽略。)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<select id="geTestUsers" parameterType="com.cun.entity.TestUser" resultMap="TestUser">
select user_no,user_name,user_sex
from test_user
<where>
<if test="testUserNo != null">
user_no = #{testUserNo}
</if>
<if test="testUserName != null">
and user_name = #{testUserName}
</if>
<if test="testUserSex != null">
and user_sex = #{testUserSex}
</if>
</where>
</select>

set : (主要作用于update语句)时若使用if标签,如果前面的if没有执行,则可能导致有多余逗号的错误。使用set标签可以将动态的配置SET 关键字,和剔除追加到条件末尾的任何不相关的逗号。
例子:(这里有一个坑,写完需要加逗号)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<update id="updateByPrimaryKeySelective" parameterType="RecruitmentConfBanner">
UPDATE conf_banner t
<set>
<if test="bannerName != null">
t.banner_name = #{bannerName},
</if>
<if test="bannerUrl != null">
t.banner_url = #{bannerUrl},
</if>
<if test="bannerLogo != null">
t.banner_logo = #{bannerLogo},
</if>
</set>
where t.banner_id = #{bannerId}
</update>

foreach : 主要用于批量删除或批量插入。
它的6个参数说明:
collection:要循环的集合
index:循环索引;
item:集合中的一个元素(item和collection,按foreach循环理解);
open:以什么开始;
close:以什么结束;
separator:循环内容之间以什么分隔
mybatis接受的参数分为:(1)基本类型;(2)对象;(3)List;(4)数组;(5)Map
例子:(入参为list,collection为list)

1
2
3
4
5
6
7
<update id="deleteWorkshopByIds" parameterType="Integer" >
update workshop set status =0
where id in
<foreach collection="list" index="i" item="id" open="(" separator="," close=")">
#{id}
</foreach>
</update>

choose : 是按顺序判断其内部when标签中的test条件出否成立,如果有一个成立,则 choose 结束。当 choose 中所有 when 的条件都不满则时,则执行 otherwise 中的sql。
例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<!--  choose(判断参数) - 按顺序将实体类 User 第一个不为空的属性作为:where条件 -->  
<select id="getUserList_choose" resultMap="resultMap_user" parameterType="com.yiibai.pojo.User">
SELECT *
FROM User u
<where>
<choose>
<when test="username !=null ">
u.username LIKE CONCAT(CONCAT('%', #{username, jdbcType=VARCHAR}),'%')
</when >
<when test="sex != null and sex != '' ">
AND u.sex = #{sex, jdbcType=INTEGER}
</when >
<when test="birthday != null ">
AND u.birthday = #{birthday, jdbcType=DATE}
</when >
<otherwise>
</otherwise>
</choose>
</where>

标签
if : 这个签前面已经涉及到了。
bind : 可以从 OGNL 表达式中创建一个变量并将其绑定到上下文

1
2
3
4
5
<select id="selectBlogsLike" resultType="Blog">
<bind name="pattern" value="'%' + _parameter.getTitle() + '%'" />
SELECT * FROM BLOG
WHERE title LIKE #{pattern}
</select>

回到原先的话题映射涉及复杂map,list,set等。
一对多collection 例子:一个班级相关的学生。StudentEntity是学生实体。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import java.util.List;

@Data
@Getter
@Setter
@Component
public class ClazzEntity {

private int clazzID;

private String clazzName;

private List<StudentEntity> studentList;
}

例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<resultMap id="ClazzResultMap" type="com.cn.hnust.pojo.ClazzEntity" >
<id column="classID" property="clazzID" jdbcType="INTEGER" />
<result column="className" property="clazzName" jdbcType="VARCHAR" />
<collection property="studentList" column="classID" javaType="ArrayList"
ofType="com.cn.hnust.pojo.StudentEntity" select="getStudentByClassID"/>
</resultMap>

<resultMap id="StudentResultMap" type="com.cn.hnust.pojo.StudentEntity">
<id property="stuID" column="stuID" />
<result property="stuName" column="stuName" />
<result property="stuAge" column="stuAge" />
<result property="stuAddress" column="stuAddress" />
</resultMap>

<select id="getClassByID" resultMap="ClazzResultMap" parameterType="java.lang.Integer" >
select classID,className
from class_t
where classID = #{clazzID}
</select>

<select id="getStudentByClassID" resultMap="StudentResultMap" parameterType="java.lang.Integer" >
select stuID,stuName,stuAge,stuAddress,classID
from student_t
where classID = #{clazzID}
</select>

一对多,一对一(association ):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<resultMap type="Bill" id="ResultBill">  
<id property="id" column="id"/>
<result property="dh" column="dh" />
<result property="rq" column="rq"/>
<association property="author" javaType="Author" >
<id property="id" column="idAutor" />
<result property="name" column="authorName" />
<result property="email" column="authorEmail"/>
</association>
<collection property="det1" javaType="ArrayList" ofType="BillDet1" >
<id property="id" column="idDet1"/>
<result property="dh" column="dhDet1"/>
<result property="wlbm" column="wlbm"/>
<result property="wlmc" column="wlmc"/>
<result property="unit" column="unit"/>
<result property="qty" column="qty"/>
</collection>
</resultMap>
<resultMap type="com.sailod.shiro.dto.HtAuthorityMenuDTO" id="OneMenuAuthority">
<id property="htAuthorityId" column="htAuthorityId" javaType="java.lang.Long" />
<result property="name" column="name" javaType="java.lang.String" />
<result property="currentUserId" column="currentUserId" javaType="java.lang.Long" />
<collection property="htAuthorityDTO" ofType="com.sailod.shiro.dto.HtAuthorityDTO"
select="selectAuthority" column="{htAuthorityId2 = htAuthorityId ,currentUserId2 = currentUserId}" >
</collection>
</resultMap>
-------------本文结束感谢您的阅读-------------
云澈 wechat
扫一扫,用手机访问哦
坚持原创技术分享,您的支持将鼓励我继续创作!
0%