概述
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>
标签,必须配置resultType
或resultMap
这2个属性中的其中1个 - 在
<insert>
等标签的内部,编写SQL语句,注意:在<insert>
标签的内容不要写任何注释,因为写在此处的注释都会被视为SQL语句的一部分
插入数据时获取自动编号的id
如果某张表的id被设计为自动编号的,在插入数据时,还可以获取自动编号的id值!
在配置SQL的<insert>
标签上,配置useGeneratedKeys
和keyProperty
属性即可:
<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 ObjectDTO
:Data Transfer ObjectVO
: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的用法所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复