我是靠谱客的博主 和谐未来,最近开发中收集的这篇文章主要介绍Mybatis的用法Mybatis的用法,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

Mybatis的用法

使用Mybatis主要需要:

  • 编写处理数据的抽象方法
    • 抽象方法必须声明在接口中,因为Mybatis框架的底层实现是基于接口的代理模式
    • 接口通常以Mapper作为名称的最后一个单词
  • 配置抽象方法对应的SQL语句

关于接口,必须使得Mybatis框架能够明确这些Mapper接口的位置,或者说,使得Mybatis知道有哪些Mapper接口,可以采取的做法有(二选一):

  • 【不推荐】在每一个Mapper接口上添加@Mapper注解
  • 【推荐】在配置类上添加@MapperScan注解,并在此注解中配置参数,参数值就是Mapper接口所在的根包,并且,确保各Mapper接口在此包下
    • 配置类:在项目的根包下(包含根包下的子孙包下),添加了@Configuration注解的类,就是配置类

关于抽象方法的声明原则:

  • 返回值类型:如果要执行的SQL是增、删、改类型的,推荐使用int作为返回值类型,表示“受影响的行数”,其实,也可以使用void,并不推荐这样使用;如果要执行的SQL是查询类型的,只需要保证返回值类型足以封装所需的查询结果即可

  • 方法名称:自定义,但不要重载

    • 阿里巴巴Java开发手册:
      【参考】
      获取单个对象的方法用 get 做前缀
      获取多个对象的方法用 list 做前缀
      获取统计值的方法用 count 做前缀
      插入的方法用 save/insert 做前缀
      删除的方法用 remove/delete 做前缀
      修改的方法用 update 做前缀
      
  • 参数列表:如果需要执行的SQL语句有多个参数,并且具有相关性,则应该将这些参数进行封装,并使用封装的类型作为抽象方法的参数

关于配置抽象方法对应的SQL语句,可以(二选一):

  • 【不推荐】使用@Insert等注解配置SQL语句,并使用相关注解(例如@Result等)完成相关配置
  • 【推荐】使用专门的XML文件配置SQL语句及相关配置
    • SQL语句更加直观,易于阅读
    • 相关配置更加直观,易于复用
    • 易于实现与DBA(Database Administrator)协同工作

关于配置SQL语句的XML文件:

  • 根标签必须是<mapper>
  • 必须配置<mapper>标签的namespace属性,此属性的值是对应的Mapper接口的全限定名
  • <mapper>标签的子级,使用<insert> / <delete> / <update> / <select>标签配置SQL语句
  • 关于<insert>等标签,都必须配置id属性,取值为对应的抽象方法的名称(不包括抽象方法的签名的其它部分,例如,不需要括号等)
  • 关于<select>标签,必须配置resultTyperesultMap这2个属性中的其中1个
  • <insert>等标签的内部,编写SQL语句,注意:在<insert>标签的内容不要写任何注释,因为写在此处的注释都会被视为SQL语句的一部分

插入数据时获取自动编号的id

如果某张表的id被设计为自动编号的,在插入数据时,还可以获取自动编号的id值!

在配置SQL的<insert>标签上,配置useGeneratedKeyskeyProperty属性即可:

<insert id="insert" useGeneratedKeys="true" keyProperty="id">
此处省略插入数据的SQL语句
</insert>

以上配置中,useGeneratedKeys="true"表示“需要获取自动编号的id值”,而keyProperty="id"表示将id值保存到参数对象(调用插入数据的方法时使用的参数)的id属性中。

关于<foreach>标签的属性:

  • collection:表示被遍历的参数对象,当抽象方法的参数只有1个时,如果参数类型是List,则此属性值为list,如果参数类型是数组(或可变参数),则此属性值为array
  • item:遍历过程中的每个元素的名称,是自定义的名称,并且,在<foreach>标签内部,使用#{}时的名称也就是此属性的值(此处自定义的名称)
  • separator:遍历过程中在值之前添加的分隔符号

【需求】根据若干个id删除品牌数据

需要执行的SQL语句大致是:

DELETE FROM pms_brand WHERE id=? OR id=? …… OR id=?;
DELETE FROM pms_brand WHERE id IN (?, ?, .... ?);

在以上SQL中,需要被删除的数据的id的数量是不确定的!

在实现此需求时,抽象方法可以设计为:

int deleteByIds(List<Long> ids);
int deleteByIds(Long[] ids);
int deleteByIds(Long... ids); // deleteByIds(1,2,3,4,5)

在配置SQL时,需要使用到<foreach>标签对参数进行遍历:

<!-- int deleteByIds(List<Long> ids); -->
<delete id="deleteByIds">
DELETE FROM pms_brand WHERE id IN (
<foreach collection="list" item="id" separator=",">
#{id}
</foreach>
)
</delete>

完成后,在BrandMapperTests中编写并执行测试:

@Test
void testDeleteByIds() {
List<Long> ids = new ArrayList<>();
ids.add(2L);
ids.add(6L);
ids.add(7L);
int rows = mapper.deleteByIds(ids);
System.out.println("根据id批量删除品牌完成,受影响的行数=" + rows);
}

关于修改数据库中的数据

【需求】根据id修改品牌的数据,参数中传入了哪些属性,就修改对应的那些字段的值

需要执行的SQL语句大致是:

update pms_brand set name=?, pinyin=?, logo=?, description=? ....(修改其它字段的值) where id=?

则抽象方法可以设计为:

int updateById(Brand brand);

然后,配置SQL语句:

<update id="updateById">
UPDATE
pms_brand
<set>
<if test="name != null">
name=#{name},
</if>
<if test="pinyin != null">
pinyin=#{pinyin},
</if>
<if test="logo != null">
logo=#{logo},
</if>
<if test="description != null">
description=#{description},
</if>
<if test="keywords != null">
keywords=#{keywords},
</if>
<if test="sort != null">
sort=#{sort},
</if>
<if test="sales != null">
sales=#{sales},
</if>
<if test="productCount != null">
product_count=#{productCount},
</if>
<if test="commentCount != null">
comment_count=#{commentCount},
</if>
<if test="positiveCommentCount != null">
positive_comment_count=#{positiveCommentCount},
</if>
<if test="enable != null">
enable=#{enable},
</if>
</set>
WHERE
id=#{id}
</update>

以上代码中,使用到了2个标签:

  • <if>:用于对参数的值进行判断,从而决定SQL语句中是否包含<if>子级的SQL片段
  • <set>:用于取代SET关键字,通常结合若干个<if>一起使用,可以去除更新的SQL语句中的字段列表与值最后多余的逗号

注意:<if>标签并没有匹配的类似else的标签,如果需要实现类似Java代码中的if...else...的效果,可以:

<if test="某条件">
满足条件时的SQL片段
</if>
<if test="与以上完全相反的条件">
满足本if时的SQL片段
</if>

以上示例可以实现类似if...else...的效果,但是,更像是if...与另一个if...,本质上是执行了2次判断的!

另外,还可以使用<choose>系列标签,真正的实现类似if...else...的效果:

<choose>
<when test="判断条件">
满足条件时的SQL片段
</when>
<otherwise>
不满足条件时的SQL片段
</otherwise>
</choose>

关于查询数据库中的数据

【需求】根据id查询品牌详情

需要执行的SQL语句大致是:

SELECT
id, name, pinyin, logo, description,
keywords, sort, sales, product_count, comment_count,
positive_comment_count, enable
FROM
pms_brand
WHERE
id=?

通常,在处理查询时,并不建议使用实体类型作为查询结果,因为绝大部分查询都不需要查询表中所有的字段,如果使用实体类型,必然导致查询结果对象调用某些Getter时得到的结果会是null,并且,这些Getter的返回结果永远会是null

建议使用其它的POJO类型作为封装查询结果的类型!

常见的POJO:

  • DO:Data Object
  • DTO:Data Transfer Object
  • VO:View Object / Value Object

关于POJO的使用:

阿里巴巴Java开发手册
【参考】
领域模型命名规约
1) 数据对象:xxxDO,xxx 即为数据表名。
2) 数据传输对象:xxxDTO,xxx 为业务领域相关的名称。
3) 展示对象:xxxVO,xxx 一般为网页名称。
4) POJO 是 DO/DTO/BO/VO 的统称,禁止命名成 xxxPOJO。

另外:

阿里巴巴Java开发手册
【强制】
类名使用 UpperCamelCase 风格,必须遵从驼峰形式,但以下情形例外:DO / BO / DTO / VO / AO
正例:MarcoPolo / UserDO / XmlService / TcpUdpDeal / TaPromotion
反例:macroPolo / UserDo / XMLService / TCPUDPDeal / TAPromotion

此次查询时,应该在项目的根包下,创建pojo.vo.BrandStandardVO类:

@Data
public class BrandStandardVO implements Serializable {
private Long id;
private String name;
private String pinyin;
private String logo;
private String description;
private String keywords;
private Integer sort;
private Integer sales;
private Integer productCount;
private Integer commentCount;
private Integer positiveCommentCount;
private Integer enable;
}

BrandMapper接口中添加抽象方法:

BrandStandardVO getStandardById(Long id);

Mybatis会自动的将查询到的结果集中的数据封装到定义的返回结果类型中,但是,在默认情况下,只能处理列名(Column)与属性名(Property)一致的情况!在规范的软件开发中,推荐使用<resultMap>来配置列与属性的映射关系:

<resultMap id="StandardResultMap" type="cn.tedu.csmall.product.pojo.vo.BrandStandardVO">
<id column="id" property="id"/>
<result column="name" property="name"/>
<result column="product_count" property="productCount"/>
<result column="comment_count" property="commentCount"/>
<result column="positive_comment_count" property="positiveCommentCount"/>
</resultMap>

关于以上<resultMap>的配置:

  • id属性:是自定义的名称,在<select>标签中的resultMap属性的值就是对应的<resultMap>id
  • type属性:用于封装查询结果的类的全限定名
  • <id>子标签:用于配置主键的列、属性的映射关系
  • <result>子标签:用于配置普通(不是主键,也不是一对多、多对多的关联查询)的列、属性的映射关系

另外,还建议使用<sql>标签封装查询的字段列表,此标签需要与<include>标签配合使用,例如:

<select id="getStandardById" resultMap="StandardResultMap">
SELECT
<include refid="StandardQueryFields"/>
FROM
pms_brand
WHERE
id=#{id}
</select>
<sql id="StandardQueryFields">
<if test="true">
id, name, pinyin, logo, description,
keywords, sort, sales, product_count, comment_count,
positive_comment_count, enable
</if>
</sql>

最后

以上就是和谐未来为你收集整理的Mybatis的用法Mybatis的用法的全部内容,希望文章能够帮你解决Mybatis的用法Mybatis的用法所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(53)

评论列表共有 0 条评论

立即
投稿
返回
顶部