mybatis是一个优秀的基于java的持久层框架,它内部封装了jdbc,使开发者只需要关注sql语句本身,而不需要花费精力去处理加载驱动、创建连接、创建statement等繁杂的过程。
注解使用
1、在 pom.xml 文件中引入Mybatis与mysql相关依赖
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.2.2</version>
</dependency>
2、在 application.yml 文件中添加数据库连接配置
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
username: root
password: 123456
url: jdbc:mysql://localhost:3306/demo?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai&useSSL=false
3、新建数据库表SProvinces.java 实体类
@Data
@Builder
public class SProvinces {
@Tolerate
public SProvinces() {
}
private Integer id;
private String cityName;
private String parentId;
}
这里使用了 lombok 的相关注解:
- @Data 注解自动生成 getter/setter
- @Builder生成链式调用
- 由于 @Data和@Builder配合使用的时候会导致无参构造方法丢失,所以要主动声明无参构造方法,并使用
@Tolerate
注解来告诉 lombok 请允许我们的无参构造方法存在,否则会导致 ORM 映射出错
4、新建 SProvincesMapper.java 接口:
@Mapper
public interface SprovincesMapper {
@Select("SELECT * FROM s_provinces")
List<SProvinces> getAll();
@Select("SELECT * FROM s_provinces WHERE id = #{id}")
SProvinces getOne(Integer id);
@Insert("INSERT INTO s_provinces(id,cityName,parentId) VALUES(#{id}, #{cityName}, #{parentId})")
void insert(SProvinces user);
@Update("UPDATE s_provinces SET cityName=#{cityName},parentId=#{parentId} WHERE id =#{id}")
void update(SProvinces user);
@Delete("DELETE FROM s_provinces WHERE id =#{id}")
void delete(Integer id);
}
- @Mapper 注解目的就是为了不再写mapper映射文件,是注解开发时用的。
- @Select 注解用来查询
- @Insert 注解用来插入
- @Update 注解用来修改
- @Delete 注解用来删除
5、在启动类 DemoApplication上添加 @MapperScan 注解来扫描 mapper
@SpringBootApplication
@MapperScan
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
如果没有指定 @MapperScan 的具体扫描路径,将会从声明该注解的类的包开始进行扫描。
6、在测试类中对 mapper 进行测试
@SpringBootTest
public class SProvincesController {
@Autowired
private SprovincesMapper sprovincesMapper;
@Test
void testInsert() {
SProvinces sProvinces = new SProvinces();
sProvinces.setId(1111);
sProvinces.setCityName("测试1");
sProvinces.setParentId("111");
sprovincesMapper.insert(sProvinces);
System.out.println(sprovincesMapper.getAll().stream().toArray());
}
@Test
void testQuery() {
System.out.println(sprovincesMapper.getOne(1111));
}
@Test
void testUpdate() {
SProvinces sProvinces = new SProvinces();
sProvinces.setId(1111);
sProvinces.setCityName("测试2");
sProvinces.setParentId("2222");
}
@Test
void testDelete() {
System.out.println(sprovincesMapper.getOne(1111));
sprovincesMapper.delete(1111);
System.out.println(sprovincesMapper.getOne(1111));
}
}
xml 使用
1、新建 PostMapper
@Mapper
public interface SprovincesMapper {
List<SProvinces> getAll();
SProvinces getOne(Integer id);
void insert(SProvinces user);
void update(SProvinces user);
void delete(Integer id);
}
2、在 resources 目录下新建 PostMapper.xml 文件
接口中方法对应的 SQL 直接写在 xml 文件中
<?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="com.example.demo2.mybatis.demo.SprovincesMapper">
<resultMap id="Sprovinces" type="com.example.demo2.mybatis.SProvinces">
<id column="id" property="id"/>
<result column="cityName" property="cityName"/>
<result column="parentId" property="parentId"/>
</resultMap>
<sql id="Sprovinces_Column_List">
id,cityName,parentId
</sql>
<select id="getAll" resultMap="Sprovinces">
select
<include refid="Sprovinces_Column_List" />
from s_provinces;
</select>
<select id="getOne" parameterType="integer" resultMap="Sprovinces" >
SELECT
<include refid="Sprovinces_Column_List" />
FROM s_provinces
WHERE id = #{id}
</select>
<insert id="insert" parameterType="com.example.demo2.mybatis.SProvinces">
insert into
s_provinces
(id,cityName,parentId)
values
(#{id},#{cityName},#{parentId});
</insert>
<update id="update" parameterType="com.example.demo2.mybatis.SProvinces">
update
s_provinces
set
<if test="cityName != null">cityName=#{cityName},</if>
parentId=#{parentId}
where id=#{id}
</update>
<delete id="delete">
delete from
s_provinces
where
id=#{id}
</delete>
</mapper>
也可以将xml文件放在和 PostMapper.java 接口同级的目录下,但是这样会带来一个问题,就是 Maven 打包的时候默认会忽略 xml 文件,所以为了避免这种情况发生,我们需要在 pom.xml 文件中添加配置:
<build>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
</resource>
<resource>
<directory>src/main/resources</directory>
</resource>
</resources>
</build>
如果直接放在 resources 目录下,就不用担心打包时被忽略了,但放在 resources 目录下不会被 MyBatis 自动扫描到,所以需要在 application.yml 配置文件中告诉 MyBatis 具体的扫描路径:
mybatis:
mapper-locations: classpath:mapper/*.xml
3、在测试类中添加测试方法:
@SpringBootTest
public class SProvincesController {
@Autowired
private SprovincesMapper sprovincesMapper;
@Test
void testInsert() {
SProvinces sProvinces = new SProvinces();
sProvinces.setId(1111);
sProvinces.setCityName("测试1");
sProvinces.setParentId("111");
sprovincesMapper.insert(sProvinces);
System.out.println(sprovincesMapper.getAll().stream().toArray());
}
@Test
void testQuery() {
System.out.println(sprovincesMapper.getOne(1111));
}
@Test
void testUpdate() {
SProvinces sProvinces = new SProvinces();
sProvinces.setId(1111);
sProvinces.setCityName("测试2");
sProvinces.setParentId("2222");
}
@Test
void testDelete() {
System.out.println(sprovincesMapper.getOne(1111));
sprovincesMapper.delete(1111);
System.out.println(sprovincesMapper.getOne(1111));
}
}
小结
可以看得出,注解版比较适合简单的 SQL 语句,一旦遇到比较复杂的 SQL 查询,比如说多表查询,xml 中写 SQL 语句会容易实现。