使用MyBatis
个人认为分为以下几大块
SQL
,方便编写查询条件和批量操作其中如何使用查询参数和处理返回结果部分都在xml
文件中进行定义。
查询参数一般有两种情况:
第一种情况我们不需要任何注解,直接在mapper
方法中传入对象,然后在sql
语句中直接使用该对象的属性即可;
// 接口声明,根据实体查询会议
Meet queryByMeet(Meet meet);
// 在xml文件中使用
<!-- 传入一个实体,直接使用实体字段 -->
<select id="queryByMeet" resultType="com.hjyp.mybatislearning.entity.Meet">
select * from meettable where meet_id = #{meetId}
</select>
第二种情况可以使用@Param()
注解表示每个参数,底层会封装为一个map
对象,这样可以在xml
文件中根据名称直接使用。
// 接口声明,根据id查询会议
Meet queryById(@Param("id") Integer id);
// 在xml文件中使用
<!-- 根据id查询 -->
<select id="queryById" resultType="com.hjyp.mybatislearning.entity.Meet">
select * from meettable where meet_id = #{id}
</select>
使用查询参数一般通过两种方式#{}, ${}
。
#{}
会根据参数的类型自动填充,如果是字符串会自动加上引号,不会引起SQL注入
,日常情况下多使用这种方式。
${}
是字符串拼接,不会自动加引号
,如果是字符串类型或者日期类型的字段进行赋值时,需要手动加引号。常用的方式有三种:
like %#{content}%
则匹配条件为like %'content'%
,应该使用like %${content}%
,匹配条件为like %content%
,这样才是正确的。"1, 2, 3"
。这个时候只能使用代码delete from t_table where id in (${ids})
。因为这样不会加引号,可以正确删除。${}
,只有这样才不会额外多一个引号。select * from ${table_name}
其实还有另一种模糊查询方法更常见也更安全,不会sql注入
,即使用字符串的自动拼接功能,代码为like "%"#{content}"%"
如果返回结果已有对应的实体类,那么直接在sql
文件中指定resultType
就可以了。Mybatis
会自动为实体类属性赋值。
<select id="queryById" resultType="com.hjyp.mybatislearning.entity.Meet">
select * from meettable where meet_id = #{id}
select>
注意:对于没有查询出来的字段会直接设为null
。
对于返回结果是多条时,接口返回值用List
接收,xml
文件还是指定实体类型
即可。
任何查询都可以用Map来接收,因为对象本身也是一个map。这时接口的返回值类型为Map
,xml
文件的resultType='java.util.Map'
接口定义
// 根据实体查询会议
Map<String, Object> queryByMeet(Meet meet);
xml
文件定义
<select id="queryByMeet" resultType="java.util.Map">
select * from meettable where meet_id = #{meetId}
select>
ResultMap
解决数据库表字段与实体类属性不匹配我们可以使用resultMap
自定义返回结果,在resultMap
中绑定属性名与字段名。
resultMap
是一个标签,该标签有id属性
:用来唯一标识自定义结果映射; type属性
:用来指定实体类型。
id
是resultMap
的子标签,用来标识主键;result
也是resultMap
的子标签。
子标签拥有property属性
:用来指定实体类的字段名;column属性
:用来指定表的列名;
注意:使用自定义
resultMap
时,即使属性名和列名一致,也是需要显式指定的,不可以省略!
<resultMap id="empResultMap" type="Emp">
<id property="eid" column="eid">id>
<result property="empName" column="emp_name">result>
<result property="age" column="age">result>
<result property="sex" column="sex">result>
<result property="email" column="email">result>
resultMap>
<select id="getAllEmp" resultMap="empResultMap">
select * from t_emp
select>
ofType
:指定集合里的实体类型<resultMap id="meetAttachResultMap" type="com.hjyp.mybatislearning.entity.Meet">
<id property="meetId" column="meet_id">id>
<result property="meetTime" column="meet_time">result>
<result property="meetPlace" column="meet_place">result>
<result property="meetTheme" column="meet_theme">result>
<result property="meetReporter" column="meet_reporter">result>
<result property="meetReporterId" column="meet_reportor_id">result>
<result property="meetBelongRole" column="meet_belong_role">result>
<result property="lastUpdatetime" column="last_updatetime">result>
<collection property="attachs" ofType="com.hjyp.mybatislearning.entity.Attach">
<id property="attachId" column="attach_id">id>
<result property="attachName" column="attach_name">result>
<result property="downloadUrl" column="download_url">result>
<result property="lastUpdatetime" column="last_updatetime">result>
collection>
resultMap>
<select id="queryById" resultMap="meetAttachResultMap">
select * from meettable inner join attachtable on attachtable.meet_id = meettable.meet_id where meettable.meet_id = #{id}
select>
和多对一类似,只不过子标签换成了collection
property
: 对应的属性字段select
:第二个查询语句的mapper所在包和方法column
:第二个查询语句所用到的条件<resultMap id="meetAttachResultMap" type="com.hjyp.mybatislearning.entity.Meet">
<id property="meetId" column="meet_id">id>
<result property="meetTime" column="meet_time">result>
<result property="meetPlace" column="meet_place">result>
<result property="meetTheme" column="meet_theme">result>
<result property="meetReporter" column="meet_reporter">result>
<result property="meetReporterId" column="meet_reportor_id">result>
<result property="meetBelongRole" column="meet_belong_role">result>
<result property="lastUpdatetime" column="last_updatetime">result>
<collection property="attachs"
select="com.hjyp.mybatislearning.mapper.AttachMapper.queryById"
column="meet_id">
collection>
resultMap>
<select id="queryById" resultMap="meetAttachResultMap">
select * from meettable where meet_id = #{id}
select>
<select id="queryById" resultType="com.hjyp.mybatislearning.entity.Attach">
select * from attachtable where meet_id = #{meetId}
select>
使用字段.属性
的方法来指定,还是用result
子标签,property
指定属性名,column
指定列名
<resultMap id="meetAttachResultMap" type="com.hjyp.mybatislearning.entity.Meet">
<id property="meetId" column="meet_id">id>
<result property="meetTime" column="meet_time">result>
<result property="meetPlace" column="meet_place">result>
<result property="meetTheme" column="meet_theme">result>
<result property="meetReporter" column="meet_reporter">result>
<result property="meetReporterId" column="meet_reportor_id">result>
<result property="meetBelongRole" column="meet_belong_role">result>
<result property="lastUpdatetime" column="last_updatetime">result>
<result property="attach.attachName" column="attach_name">result>
<result property="attach.downloadUrl" column="download_url">result>
<result property="attach.lastUpdatetime" column="last_updatetime">result>
resultMap>
<select id="queryById" resultMap="meetAttachResultMap">
select * from meettable inner join attachtable on attachtable.meet_id = meettable.meet_id where meettable.meet_id = #{id}
select>
association
: 子标签专门用来处理多对一关系property
:需要处理的映射关系的实体属性名javaType
:该属性的类型注意:使用
association
需要通过javaType
指定属性的类型
<resultMap id="meetAttachResultMap" type="com.hjyp.mybatislearning.entity.Meet">
<id property="meetId" column="meet_id">id>
<result property="meetTime" column="meet_time">result>
<result property="meetPlace" column="meet_place">result>
<result property="meetTheme" column="meet_theme">result>
<result property="meetReporter" column="meet_reporter">result>
<result property="meetReporterId" column="meet_reportor_id">result>
<result property="meetBelongRole" column="meet_belong_role">result>
<result property="lastUpdatetime" column="last_updatetime">result>
<association property="attach" javaType="com.hjyp.mybatislearning.entity.Attach">
<id property="attachId" column="attach_id">id>
<result property="attachName" column="attach_name">result>
<result property="downloadUrl" column="download_url">result>
<result property="lastUpdatetime" column="last_updatetime">result>
association>
resultMap>
<select id="queryById" resultMap="meetAttachResultMap">
select * from meettable inner join attachtable on attachtable.meet_id = meettable.meet_id where meettable.meet_id = #{id}
select>
先根据会议ID查出会议,再根据附件ID查出附件,其实是两个查询语句
property
: 对应的属性字段select
:第二个查询语句的mapper所在包和方法column
:第二个查询语句所用到的条件<resultMap id="meetAttachResultMap" type="com.hjyp.mybatislearning.entity.Meet">
<id property="meetId" column="meet_id">id>
<result property="meetTime" column="meet_time">result>
<result property="meetPlace" column="meet_place">result>
<result property="meetTheme" column="meet_theme">result>
<result property="meetReporter" column="meet_reporter">result>
<result property="meetReporterId" column="meet_reportor_id">result>
<result property="meetBelongRole" column="meet_belong_role">result>
<result property="lastUpdatetime" column="last_updatetime">result>
<association property="attach"
select="com.hjyp.mybatislearning.mapper.AttachMapper.queryById"
column="meet_id">
association>
resultMap>
<select id="queryById" resultMap="meetAttachResultMap">
select * from meettable where meet_id = #{id}
select>
<select id="queryById" resultType="com.hjyp.mybatislearning.entity.Attach">
select * from attachtable where meet_id = #{meetId}
select>
MybatisPlus
中由于是以实体作为操作单元,所以要使用注解忽略不存在的属性。null
动态SQL
可以根据特定条件动态拼接SQL
语句,比如查询时where
语句后面的各种条件
。常见的标签有if
;where
;trim
;choose、when、otherwise
;foreach
、
if标签
if标签用来判断某个属性是否为空,如果不为空可以拼接相应的语句。
使用if
时可以在where
语句后加上一个恒成立条件,比如1=1
,然后把每条分支语句前加个 and
<select id="getEmpByCondition" resultType="Emp">
select * from t_emp where 1=1
<if test="empName != null and empName !=''">
and emp_name = #{empName}
if>
<if test="age != null and age !=''">
and age = #{age}
if>
<if test="sex != null and sex !=''">
and sex = #{sex}
if>
<if test="email != null and email !=''">
and email = #{email}
if>
select>
where 标签
前面只使用if标签时,我们加了一个恒成立条件,但如果配合使用where标签,就不需要加恒成立的条件了。
如果where标签
的内容为空,那么不会在最后的sql
语句中加where条件
。
若where标签中的if条件满足,则where标签会自动添加where关键字,并将条件最前方多余的and/or
去掉
<select id="getEmpByCondition" resultType="Emp">
select * from t_emp
<where>
<if test="empName != null and empName !=''">
emp_name = #{empName}
if>
<if test="age != null and age !=''">
and age = #{age}
if>
<if test="sex != null and sex !=''">
and sex = #{sex}
if>
<if test="email != null and email !=''">
and email = #{email}
if>
where>
select>
choose、when、otherwise标签
作用和if…else if… else一样,选择一个合适的条件执行
<select id="getEmpByChoose" resultType="Emp">
select * from t_emp
<where>
<choose>
<when test="empName != null and empName != ''">
emp_name = #{empName}
when>
<when test="age != null and age != ''">
age = #{age}
when>
<when test="sex != null and sex != ''">
sex = #{sex}
when>
<when test="email != null and email != ''">
email = #{email}
when>
<otherwise>
did = 1
otherwise>
choose>
where>
select>
foreach标签
foreach
标签中内容的开始符foreach
标签中内容的结束符
<delete id="deleteMoreByArray">
delete from t_emp where eid in
<foreach collection="eids" item="eid" separator="," open="(" close=")">
#{eid}
foreach>
delete>
<insert id="insertMoreByList">
insert into t_emp values
<foreach collection="emps" item="emp" separator=",">
(null,#{emp.empName},#{emp.age},#{emp.sex},#{emp.email},null)
foreach>
insert>
SQL片段