Mybatis框架
Mybatis框架的主要作用
Mybatis框架主要实现了简化持久层编程的问题。
持久层:实现数据持久化的一系列组件。
数据持久化:通常,在开发领域中,讨论的数据大多是在内存中的,而内存默认特指内存条(RAM:Random Access Memory),RAM的特性包含“一旦断电,数据将全部丢失”,且“正在执行的程序和数据都是在内存中的”,由程序处理的数据最终应该永久的保存下来,则不能将这些数据一直只存储在内存中,通常,会将数据存储到可以永久保存数据的存储介质中,典型的永久存储数据的存储介质有:硬盘、U盘、光盘等,所以,数据持久化就是将内存中的数据存储到硬盘等介质中,而硬盘中的数据是以文件的形式存在的,所以,通常可以将数据存储到文本文件中、XML文件、数据库中,这些存储方案中,只有数据库是便于实现增、删、改、查这4种操作的,所以,一般“数据持久化”默认指的就是将数据存储到数据库中。
在Java语言中,实现数据库编程需要先建立与数据库的连接,然后准备SQL语句,然后执行,然后获取执行结果并处理结果,最后,关闭或归还数据库连接,这是一套非常固定的流程,无论对哪个数据表执行哪种操作,其流程大致是固定的,所以,就产生了一些框架,用于简化这部分的编程。
在使用Mybatis时,只需要关注2点:
- 在接口中定义抽象方法
- 配置抽象方法映射的SQL语句
使用Mybatis的前期准备
LOMBOK
LOMBOK是一款可以在编译期在类中自动生成某些代码的工具,通常用于自动生成:
- Setters & Getters
hashCode()
andequals()
toString()
- 无参数构造方法
- 全参数构造方法
在使用时,需要添加依赖项:
<!-- Lombok -->
<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.20</version>
<scope>provided</scope>
</dependency>
在POJO类的声明上,添加@Data
注解,此注解可以帮助生成所有属性对应的Setters & Getters、规范的hashCode()
和equals()
、toString()
,并且,要求此类的父类中存在无参数构造方法。
package cn.tedu.csmall.product.pojo.entity;
import lombok.Data;
import java.io.Serializable;
import java.time.LocalDateTime;
@Data
public class Album implements Serializable {
private Long id;
private String name;
private String description;
private Integer sort;
private LocalDateTime gmtCreate;
private LocalDateTime gmtModified;
}
注意:Lombok是在**编译期(将Java源代码文件.java编译成目标文件.class)**添加各方法,所以,在IntelliJ IDEA或其它开发工具中,默认情况下,直接调用以上各属性对应的Setter或Getter方法,在开发工具将无法提示这些方法,并且,已经写出来的调用这些方法的代码会报错,为了解决此问题,需要在开发工具中安装Lombok插件。
另外,Lombok还提供了以下注解:
-
@Data
-
@Setter
-
@Getter
-
@EqualsAndHashCode
-
@ToString
-
@NoArgsConstructor
-
@AllArgsConstructor
-
@Accessors
- 配置为
@Accessors(chain = true)
时,将支持链式调用方法
- 配置为
-
@Slf4j
- 用于日志,将在后续补充说明
使用Mybatis的前期准备
在Spring Boot项目中,当需要使用Mybatis时,需要添加相关的依赖:
<!-- MySQL依赖项,仅运行时需要 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<!-- Mybatis整合Spring Boot的框架 -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.2.2</version>
</dependency>
当添加以上依赖项后,如果启动项目,会提示以下错误:
***************************
APPLICATION FAILED TO START
***************************
Description:
Failed to configure a DataSource: 'url' attribute is not specified and no embedded datasource could be configured.
Reason: Failed to determine a suitable driver class
因为Spring Boot启动时,如果检测到当前已经添加数据库编程的依赖项,会自动读取连接数据库的配置信息,由于目前尚未配置这些信息,所以,启动会报错!
所以,需要在application.properties
中添加配置:
# 连接数据库的参数
spring.datasource.url=jdbc:mysql://localhost:3306/mall_pms?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai
spring.datasource.username=root
spring.datasource.password=root
由于Spring Boot在启动项目时只会读取以上配置并应用,并不会实际的连接数据库,所以,即使以上配置值是错误的,启动项目时并不会报告错误!
可以在src/test/java
的根包下的测试类中进行测试连接:
@SpringBootTest
class CsmallProductApplicationTests {
@Test
void contextLoads() {
}
@Autowired
DataSource dataSource;
@Test
void testConnection() throws Exception {
dataSource.getConnection();
}
}
当配置的URL错误(含主机名错误、端口号错误),或MySQL未启动时,将出现以下错误:
com.mysql.cj.jdbc.exceptions.CommunicationsException: Communications link failure
The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.
如果数据库名称错误,或无此数据库,将出现以下错误:
java.sql.SQLSyntaxErrorException: Unknown database 'mall_pmsxzxxxxx'
如果用户或密码错误,将出现以下错误:
java.sql.SQLException: Access denied for user 'rootx'@'localhost' (using password: YES)
java.sql.SQLException: Access denied for user 'root'@'localhost' (using password: YES)
java.sql.SQLException: Access denied for user 'root'@'localhost' (using password: NO)
使用Mybatis插入数据
Mybatis要求抽象方法必须存在于接口中(因为其实现原理是基于接口的代理模式的),所以,在项目的根包下创建mapper.AlbumMapper
接口。
提示:可以在接口上添加@Repository
注解,避免在自动装配时IntelliJ IDEA误判而提示错误。
关于接口中的抽象方法:
- 返回值类型:如果需要执行的SQL是增、删、改类型的,使用
int
作为返回值类型,表示“受影响的行数”,不建议使用void
- 方法名称 :自定义,不要使用重载
- 获取单个对象的方法用
get
做前缀 - 获取多个对象的方法用
list
做前缀 - 获取统计值的方法用
count
做前缀 - 插入的方法用
save/insert
做前缀 - 删除的方法用
remove/delete
做前缀 - 修改的方法用
update
做前缀
- 获取单个对象的方法用
- 参数列表:如果需要执行的SQL语句有多个参数,应该将这些参数封装到自定义的数据类型中,并使用自定义的数据类型作为抽象方法的参数
则,插入相册时需要执行的SQL语句大致是:
insert into pms_album (name, description, sort, gmt_create, gmt_modified) values (?, ?, ?, ?, ?);
则抽象方法为:
int insert(Album album);
在首次使用时,需要让Mybatis知道哪些接口是Mapper接口,可以(二选一):
- 在每个接口上添加
@Mapper
注解 - 在配置类上添加
@MapperScan
并指定Mapper接口所在的包- 在根包下的任何类,添加了
@Configuration
注解,即是配置类 - 可以在根包下创建
config.MybatisConfiguration
类,同时添加@Configuration
和@MapperScan("cn.tedu.csmall.product.mapper")
即可
- 在根包下的任何类,添加了
另外,在使用Mybatis时,还需要为每个抽象方法配置其映射的SQL语句,可以使用@Insert
等注解来配置SQL语句,但不推荐,因为:
- 不便于配置较长的SQL语句
- 不便于做一些复杂的配置,特别是查询时
- 不便于实现与DBA(Database Administrator)分工合作
建议的做法是使用XML文件来配置SQL语句,可以从 http://doc.canglaoshi.org/config/Mapper.xml.zip 下载得到所需的文件,然后,在项目的src/main/resources
下创建mapper
文件夹,将得下载、解压得到的XML文件复制到此文件夹中。
关于配置SQL的XML文件:
- 根节点必须是
<mapper>
- 在
<mapper>
上必须配置namespace
属性,取值为对应的接口的全限定名 - 在
<mapper>
的子级,根据需要执行的SQL语句,选择使用<insert>
、<delete>
、<update>
、<select>
中的某个节点,准备配置SQL语句,这些节点必须配置id
属性,取值为抽象方法的名称(不包括括号和参数列表),并在这些节点内部配置SQL语句
提示:在本项目中,当插入数据时,不需要关注
gmtCreate
、gmtModified
这2个字段的值的插入,后续将使用Xxx自动完成。
例如:
<?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="cn.tedu.csmall.product.mapper.AlbumMapper">
<!-- int insert(Album album); -->
<insert id="insert">
INSERT INTO pms_album (
name, description, sort
) VALUES (
#{name}, #{description}, #{sort}
)
</insert>
</mapper>
在首次使用时,需要在application.properties
中配置以上XML文件的位置:
# Mybatis的配置SQL的XML文件的位置
mybatis.mapper-locations=classpath:mapper/*.xml
至此,“插入相册数据”的功能开发完成!
然后,应该及时测试以上功能是否正确,可以在src/test/java
下的根包下创建mapper.AlbumMapperTests
测试类,
package cn.tedu.csmall.product.mapper;
import cn.tedu.csmall.product.pojo.entity.Album;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
public class AlbumMapperTests {
@Autowired
AlbumMapper mapper;
@Test
void testInsert() {
Album album = new Album();
album.setName("某电视的相册");
album.setDescription("某电视的相册的描述");
album.setSort(63);
int rows = mapper.insert(album);
System.out.println("rows = " + rows);
}
}
在执行测试时,如果此前配置的@MapperScan
有误,会出现如下错误:
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'cn.tedu.csmall.product.mapper.AlbumMapperTests': Unsatisfied dependency expressed through field 'mapper'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'cn.tedu.csmall.product.mapper.AlbumMapper' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
如果在XML文件中,<mapper>
的namespace
属性值配置有误,或者<insert>
节点的id
属性值配置有误,或者在application.properties
中没有正确的配置mybatis.mapper-locations
属性,都将出现以下错误:
org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): cn.tedu.csmall.product.mapper.AlbumMapper.insert
插入数据时获取自动编号的id
在配置<insert>
节点时,配置useGeneratedKeys
和keyProperty
这2个属性,就可以得到自动编号的id,例如:
<!-- int insert(Album album); -->
<insert id="insert" useGeneratedKeys="true" keyProperty="id">
<!-- 省略后续代码 -->
其中,useGeneratedKeys="true"
表示“需要获取自动编号的键的值”,keyProperty="id"
表示将得到的自动编号的id值放回到参数对象的id
属性中去!
开发规范上,对于自动编号的表进行插入数据时,都应该配置这2个属性!
使用Mybatis删除数据
需求:根据id删除相册数据
需要执行的SQL语句大致是:
delete from pms_album where id=?
在AlbumMapper
接口中添加抽象方法:
int deleteById(Long id);
在AlbumMapper.xml
中配置以上抽象方法映射的SQL:
<delete id="deleteById">
DELETE FROM pms_album WHERE id=#{id}
</delete>
完成后,在AlbumMapperTests
中添加新的测试方法:
@Test
void testDeleteById() {
Long id = 1L;
int rows = mapper.deleteById(id);
System.out.println("rows = " + rows);
}
Spring Boot框架
关于启动类
每个创建好的Spring Boot项目的src/main/java
下都有一个默认的包,且包下有一个带main()
方法的类,此类就是整个项目的启动类,执行此类的main()
方法将启动整个项目。
关于配置文件
在Spring Boot项目中,在src/main/resources
下,默认就存在application.properties
文件,此文件是Spring Boot会自动读取的配置文件。
Spring Boot使用了许多自动配置的机制,以至于我们只需要按照规定的名称去填写配置值,这些配置就会生效!
MyBatis的动态SQL–foreach
动态SQL:根据参数值的不同,将生成不同的SQL语句。
假设存在需求:根据若干个id删除相册数据,即批量删除。
需要执行的SQL语句大致是:
delete from pms_album where id=? or id=? or id=? ...
或者:
delete from pms_album where id in (?, ?, ?, ... ?);
当实现以上功能时,关于抽象方法,可以设计为:
int deleteByIds(Long[] ids);
或者:
int deleteByIds(Long... ids);
或者:
int deleteByIds(List<Long> ids);
在配置SQL时,需要使用到<foreach>
节点对参数进行遍历:
<!-- int deleteByIds(Long[] ids); -->
<delete id="deleteByIds">
DELETE FROM pms_album
WHERE id IN (
<foreach collection="array" item="id" separator=",">
#{id}
</foreach>
)
</delete>
关于<foreach>
节点的配置:
collection
属性:当抽象方法的参数只有1个且没有添加@Param
注解时,当参数是数组类型时(包括类型为可变参数时),此属性取值为array
,当参数是List
集合类型时,此属性取值为list
item
属性:遍历过程中的每个元素的变量名,是自定义的名称separator
属性:遍历过程中各元素之间的分隔符号
练习:批量插入相册数据
需要执行的SQL语句大致是:
insert into pms_album (name,description,sort) values (?,?,?), (?,?,?), (?,?,?)
在AlbumMapper
中添加抽象方法:
int insertBatch(List<Album> albums);
在AlbumMapper.xml
中配置SQL语句:
<!-- int insertBatch(List<Album> albums); -->
<insert id="insertBatch" useGeneratedKeys="true" keyProperty="id">
INSERT INTO pms_album (
name, description, sort
) values
<foreach collection="list" item="album" separator=",">
(#{album.name}, #{album.description}, #{album.sort})
</foreach>
</insert>
使用Mybaits修改数据
通常,修改数据时,也会使用到动态SQL的机制,当传入某个字段对应的值时,SQL中才会包含修改此字段的部分,反之,如果没有传入某个字段对应的值,则SQL语句不会包含修改此字段的部分!
这样的功能可以通过动态SQL的<if>
标签来实现!
假设需要实现修改相册数据,传入的参数中包含哪些数据,就修改哪些数据,不包含的部分将不会被修改。
在AlbumMapper
接口中添加抽象方法:
int update(Album album);
在AlbumMapper.xml
中配置SQL语句:
<!-- int update(Album album); -->
<update id="update">
UPDATE pms_album
<set>
<if test="name != null">
name=#{name},
</if>
<if test="description != null">
description=#{description},
</if>
<if test="sort != null">
sort=#{sort},
</if>
</set>
WHERE id=#{id}
</update>
使用Mybatis查询–统计
假设需要实现:统计相册表中的数据的数量
需要执行的SQL语句大致是:
select count(*) from pms_album
关于抽象方法:在查询时,方法的返回值类型只要求能够存入查询结果即可。
则在AlbumMapper
中添加抽象方法:
int count();
然后,在AlbumMapper.xml
中配置SQL语句,将使用<select>
节点,此节点必须配置resultType
或resultMap
这2个属性中的某1个,当使用resultType
时,此属性的值取决于抽象方法的返回值类型,如果是基本数据类型(例如int
等),则resultType
属性的值就是类型名,如果是引用数据类型(例如String
、Album
等),则resultType
属性的值就是类型的全限定名(在java.lang
包下的可以省略包名)。
<!-- int count(); -->
<select id="count" resultType="int">
SELECT count(*) FROM pms_album
</select>
如果既没有配置resultType
又没有配置resultMap
,将会出现以下错误:
org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.executor.ExecutorException: A query was run and no Result Maps were found for the Mapped Statement 'cn.tedu.csmall.product.mapper.AlbumMapper.count'. It's likely that neither a Result Type nor a Result Map was specified.
使用Mybatis查询–根据id查询
假设需要实现:根据id查询相册详情
需要执行的SQL语句大致是:
select id, name, description, sort from pms_album where id=?
关于抽象方法的返回值类型,原则上,只需要能够“放得下”就行,所以,可以使用Album
作为此次查询的返回值类型,但是,并不建议这样处理!通常,建议另创建类型,用于封装查询结果!另外创建的类型,通常并不会称之为实体类,并且,这种类型会添加一些后缀,关于后缀的使用,阿里的文档的参考:
- 数据对象:xxxDO,xxx 即为数据表名
- 数据传输对象:xxxDTO,xxx 为业务领域相关的名称
- 展示对象:xxxVO,xxx 一般为网页名称
- POJO 是 DO/DTO/BO/VO 的统称,禁止命名成 xxxPOJO
关于以上后缀:
- DO:Data Object
- DTO:Data Transfer Object
- VO:View Object / Value Object
对于本次查询,可以使用VO
作为类型的后缀,完整的类名可以使用AlbumStandardVO
,此类应该放在项目的根包的pojo.vo
包下:
@Data
public class AlbumStandardVO implements Serializable {
// 除了gmtCreate和gmtModified以外的所有属性
}
提示:此前涉及的“实体类编写规范”本质上是POJO的规范!
接下来,在AlbumMapper
接口中添加抽象方法:
AlbumStandardVO getStandardById(Long id);
在AlbumMapper.xml
中配置SQL:
<!-- AlbumStandardVO getStandardById(Long id); -->
<select id="getStandardById" resultType="xx.xx.xx.AlbumStandardVO">
select id, name, description, sort from pms_album where id=#{id}
</select>
Mybatis在封装查询结果时,会自动的将**列名(Column)与属性名(Property)**匹配的结果进行封装,例如查询结果中的name
值将封装到返回值对象的name
属性中去,对于名称不匹配的,将放弃。
可以在配置SQL时,为查询的字段自定义列名,使得“查询结果中的列名”与“封装结果的类型中的属性名”是一致的,例如:
<!-- BrandStandardVO getStandardById(Long id); -->
<select id="getStandardById" resultType="cn.tedu.csmall.product.pojo.vo.BrandStandardVO">
SELECT
id, name, pinyin, logo, description,
keywords, sort, sales,
product_count AS productCount,
comment_count AS commentCount,
positive_comment_count AS positiveCommentCount,
enable
FROM pms_brand
WHERE id=#{id}
</select>
提示:在SQL语句中,自定义别名时,
AS
关键字并不是必须的,只需要有1个空格即可。
除了以上做法以外,还可以在application.properties
中添加配置,使得Mybatis能自动处理“全小写且使用下划线分隔的字段名对应的列名”与“驼峰命名法的属性名”之间的对应关系(例如此做法时,不必在查询时自定义别名):
mybatis.configuration.map-underscore-to-camel-case=true
或者,还可以选择自定义ResultMap,用于指导Mybatis如何封装查询结果,其基本方式是:
<resultMap id="自定义的ResultMap名称" type="封装查询结果的类型的全限定名">
<!-- 配置 -->
</resultMap>
<select id="xxx" resultMap="自定义的ResultMap名称">
</select>
在<resultMap>
内部,使用<result>
节点,配置其column
与property
属性,用于指定列名与属性名的对应关系,例如:
<resultMap id="自定义的ResultMap名称" type="封装查询结果的类型的全限定名">
<result column="product_count" property="productCount" />
<result column="comment_count" property="commentCount" />
<result column="positive_comment_count" property="positiveCommentCount" />
</resultMap>
提示:在普通的单表查询中,列名与属性名本身就对应的部分,并不需要在<resultMap>
中配置。
另外,在开发实践中,建议将查询的字段列表使用<sql>
节点进行封装,然后,在配置的SQL语句中,使用<include>
节点进行调用即可:
<!-- BrandStandardVO getStandardById(Long id); -->
<select id="getStandardById" resultMap="StandardResultMap">
SELECT
<include refid="StandardQueryFields"/>
FROM pms_brand
WHERE id=#{id}
</select>
<sql id="StandardQueryFields">
id, name, pinyin, logo, description,
keywords, sort, sales, product_count, comment_count,
positive_comment_count, enable
</sql>
<resultMap id="StandardResultMap"
type="cn.tedu.csmall.product.pojo.vo.BrandStandardVO">
<result column="product_count" property="productCount" />
<result column="comment_count" property="commentCount" />
<result column="positive_comment_count" property="positiveCommentCount" />
</resultMap>
当在<select>
上使用resultType
属性,取值却是<resultMap>
的id时,将出现以下错误:
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sqlSessionFactory' defined in class path resource [org/mybatis/spring/boot/autoconfigure/MybatisAutoConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.apache.ibatis.session.SqlSessionFactory]: Factory method 'sqlSessionFactory' threw exception; nested exception is org.springframework.core.NestedIOException: Failed to parse mapping resource: 'file [C:\Users\pc\IdeaProjects\jsd2204-csmall-product-teacher\target\classes\mapper\BrandMapper.xml]'; nested exception is org.apache.ibatis.builder.BuilderException: Error parsing Mapper XML. The XML location is 'file [C:\Users\pc\IdeaProjects\jsd2204-csmall-product-teacher\target\classes\mapper\BrandMapper.xml]'. Cause: org.apache.ibatis.builder.BuilderException: Error resolving class. Cause: org.apache.ibatis.type.TypeException: Could not resolve type alias 'StandardResultMap'. Cause: java.lang.ClassNotFoundException: Cannot find class: StandardResultMap
当在<select>
上使用了resultMap
,取值错误时(例如取值为类型的全限定名),将出现以下错误:
java.lang.IllegalArgumentException: Result Maps collection does not contain value for cn.tedu.csmall.product.pojo.vo.BrandStandardVO
使用Mybatis查询数据列表
查询列表与查询某1个数据的开发过程相差不大,主要区别在于:
- 查询列表时,需要查询的字段通常更少
- Mybatis会自动使用
List
集合来封装查询到的多个数据,所以,抽象方法的返回值类型必须是List
类型的
假设需要实现:查询品牌列表(不考虑分页问题)
需要执行的SQL语句大致是:
select * from pms_brand order by sort desc, pinyin, id desc
注意:如果执行的查询的结果可能超过1条(即2条或以上),必须显式的指定order by
进行排序!
在vo
包中创建BrandListItemVO
类:
@Data
public class BrandListItemVO implements Serializable {
// id, name, logo
}
然后,在BrandMapper
接口中添加抽象方法:
List<BrandListItemVO> list();
在BrandMapper.xml
中配置SQL:
<!-- List<BrandListItemVO> list(); -->
<select id="list" resultMap="ListItemResultMap">
SELECT
<include refid="ListItemQueryFields"/>
FROM pms_brand
ORDER BY sort DESC, pinyin, id DESC
</select>
<sql id="ListItemQueryFields">
id, name, logo
</sql>
<resultMap id="ListItemResultMap" type="cn.tedu.csmall.product.pojo.vo.BrandListItemVO">
</resultMap>
注意:即使是查询列表,无论使用resultType
,还是配置<resultMap>
,关于数据类型,都只需要指定为List
中的元素类型即可!
关于Mybatis小结
- 【理解】Mybatis主要解决了:简化数据库编程
- 【了解】使用Mybatis时需要添加依赖:
mysql-connector-java
、mybatis-spring-boot-starter
(mybatis
+mybatis-spring
+spring-context
+spring-jdbc
+ 数据库连接池) - 【掌握】在配置类上使用
@MapperScan
配置接口所在的包,并在application.properties
中配置XML文件的位置 - 【了解】在
application.properties
配置连接数据库的参数 - 【掌握】POJO的规范:属性私有化,实现
Serializable
,全属性的Setters & Getters,hashCode()
、equals()
、存在无参数的构造方法toString()
并不是规范所要求的
- 【掌握】抽象方法的设计原则
- 返回值类型:增删改使用
int
,查询使用可以装得下结果的类型即可 - 方法名称:自定义,不要重载,最好参考规范
- 参数列表:取决于需要执行的SQL语句中的参数,当参数较多时,应该封装
- 返回值类型:增删改使用
- 【掌握】在XML中配置SQL
- 此XML文件不是凭空创建的,应该从别处复制粘贴得到(此XML顶部的声明不易于手动编写)
- 每个XML文件都必须使用
<mapper>
作为根节点,且配置namespace
属性,此属性的值是对应的接口的全限定名 - 区分使用
<insert>
、<delete>
、<update>
、<select>
节点<delete>
和<update>
可以浑为一谈- 在不考虑获取自动编号的值的情况,
<insert>
、<delete>
、<update>
都可以浑为一谈
<insert>
、<delete>
、<update>
、<select>
这些节点都必须配置id
属性,取值为对应的抽象方法的名称<insert>
可以配置useGeneratedKeys
和keyProperty
属性,用于获取自动编号的id<select>
必须配置resultType
或resultMap
其中的某1个(二选一)- 使用
<foreach>
可以实现对参数的遍历,可以实现批量删除、批量插入、批量修改…… - 使用
<set>
结合<if>
实现按需更新数据 - 使用
<sql>
封装SQL语句片段,并使用<include>
调用 - 使用
<resultMap>
指导Mybatis封装查询结果
以上为自己学习时做的笔记。