MyBatis
[toc]
介绍
MyBatis 是支持普通 SQL查询, 存储过程和高级映射的优秀持久层框架. MyBatis 消除了几乎所有的JDBC代码和参数的手工设置以及结果集的检索. MyBatis 使用简单的 XML或注解用于配置和原始映射, 将接口和 Java 的POJOs(Plain Ordinary Java Objects, 普通的 Java对象)映射成数据库中的记录.
这种普通java对象, 其实就对应着数据库的字段
DAO -> Service -> View
pojo会和这三层都有联系
1
2
3
4
5
// Spring 三个注解, 注解是一种标识
@Repository // 标识是一个持久层(数据访问层, 又叫DAO)
@Mapper // 也是持久层,不过更具体
@Service // 标识是一个业务层
@Component // 无法划分层次
目前的理解: 在入口类配置扫描, 单元测试中使用@AutoWaired(这个具体解释很复杂, 涉及到自动装配, 以后再说)之后, 就可以直接获取这个对象, 也就直接可以在单元测试里使用了.
1
2
3
4
5
6
7
@SpringBootApplication
@MapperScan(value="com.neuedu.mapper") // 包扫描
public class HisMain {
public static void main(String[] args) {
// something
}
}
配置
FreeMyBatis
在idea中下载插件FreeMyBatis.
配置pom.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<!--jdbc驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.11</version>
</dependency>
<!--jdbc 数据源-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<!--mybatis-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.3</version>
</dependency>
application.properties
添加mapper的路径
1
2
3
#=classpath*:mapper/**/*.xml
mybatis.mapper-locations=classpath*:/mapper/*.xml
mybatis.type-aliases-package=com.xtsz.entity
增删改查
实际上单表查询一般用 MyBatisPlus, 多表查询才使用 MyBatis.
- 新建实体类
- 在接口类中配置函数
- 在xml中填充sql语句
- 在单元测试类中添加语句
实体类
1
2
3
4
5
6
7
8
9
// 实体类 在src/main/java/com.neuedu/entity/User.java
@Data
public class User {
private Integer id;
private String username;
private String birthday;
private String sex;
private String address;
}
包扫描
1
2
3
4
5
6
7
8
@SpringBootApplication
@MapperScan(value="com.neuedu.mapper") // 包扫描,也是后续函数生效的关键,如果在配置类中加了就不用再加了.
public class HisMain {
public static void main(String[] args) {
// jdbc: select * from users
SpringApplication.run(HisMain.class, args);
}
}
接口类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// 接口类 在src/main/java/com.neuedu/mapper/UserMapper.java
@Repository
public interface UserMapper {
List<User> selectAll();
/**
* 1. 定义接口方法
* 2. 编写Mapper.xml
* 3. 编写测试类进行测试
* @param user
* @return
*/
int insert(User user);
int update(User user);
int delete(Integer id);
}
Mapper
首先要安装上文说的FreeMyBatis插件, 否则无法生成. 在上文UserMapper接口类类名(注意, 是类名)上 使用 alt + enter , 就可以弹出框, 其中就有自动生成Mapper的选项, 选中位置之后就可以生成了. 在接口文件移动位置之后, 这个xml也会自动重构 另外接口类函数返回值的变动, 也可以通过alt+enter的方式进行修改 在接口类中的函数, 也可以通过alt+enter的方式在UserMapper.xml中添加
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<!-- src/main/resources/mapper/UserMapper.xml -->
<mapper namespace="com.neuedu.mapper.UserMapper">
<!--查询记录-->
<select id="selectAll" resultType="com.neuedu.entity.User">
select id,username,birthday,sex,address from user
</select>
<!--插入记录-->
<insert id="insert" parameterType="com.neuedu.entity.User">
insert into user (id,username,birthday,sex,address) values
(#{id},#{username},#{birthday},#{sex},#{address})
</insert>
<update id="update" parameterType="com.neuedu.entity.User">
update user set username=#{username}, birthday=#{birthday}, sex=#{sex}, address=#{address}
where id=#{id}
</update>
<delete id="delete" parameterType="java.lang.Integer">
delete from user where id=#{id}
</delete>
</mapper>
单元测试
在类名上 ctrl+shift+T 创建单元测试 在新建的单元测试类上面加入注解@SpringBootTest
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
@SpringBootTest
@Slf4j
class UserMapperTest {
@Autowired
private UserMapper userMapper;
@Test
void selectAll() {
List<User> list = userMapper.selectAll();
for (User user : list) {
log.info(user.getUsername() + "\t" + user.getSex() + "\t" + user.getAddress());
}
// int size=list.size();
// Assert.isTrue(list.size()==4);
// Assert.assertEquals(4,size);
}
/**
* 单元测试方法,返回必须是void ,不能够有任何参数
* 添加一个@Test注解
*/
@Test
public void insert() {
User user = new User();
user.setId(5);
user.setBirthday("2010-01-01");
user.setSex("女");
user.setUsername("张三");
user.setAddress("北京");
int count = userMapper.insert(user);
}
@Test
public void update() {
User user = new User();
user.setId(1);
user.setBirthday("2011-01-01");
user.setSex("女");
user.setUsername("张三");
user.setAddress("天津");
int count = userMapper.update(user);
}
@Test
public void delete() {
userMapper.delete(5);
}
}
常见错误
expected at least 1 bean which qualifies as autowire candidate for this dependency.
这个就是提示依赖无法注入 一般是入口类忘了加包扫描或者包扫描写错了
数据库某些字段返回值是null
这个是因为在数据库的查询语句中, select后面跟的必须是表中存在的子段, 而返回的必须是实体类中存在的字段, 所以如果二者不一样(指用 *
或者逐个写表中的字段), 就会产生矛盾.
解决方案:
采用as, as前面是数据库字段, as后面是实体类字段.
(看来那个说是能把下划线自动替换的也不那么智能呀)
1
2
3
4
<select id="selectAll" resultType="com.neuedu.hosmng.entity.HosMessage">
select id, const_type_code as "constTypeCode", const_type_name as "constTypeName"
from hos_message
</select>