一、配置

相关依赖

  1. <!-- MySQL数据库驱动 -->
  2. <dependency>
  3. <groupId>mysql</groupId>
  4. <artifactId>mysql-connector-java</artifactId>
  5. </dependency>
  6. <!-- MyBatis -->
  7. <dependency>
  8. <groupId>org.mybatis.spring.boot</groupId>
  9. <artifactId>mybatis-spring-boot-starter</artifactId>
  10. <version>2.0.0</version>
  11. </dependency>

配置文件

server:
  port: 10010
spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/test?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&useSSL=true
    username: root
    password: root

mybatis:
  mapper-locations:
    - classpath:mapper/*.xml

添加Mapper包扫描

@Configuration
@MapperScan({"com.example.test.dao"})
public class MyBatisConfig {
}

下划线转驼峰

配置 mybatis.configuration.map-underscore-to-camel-case=true 以开启下划线转驼峰

mybatis:
  mapper-locations:
    - classpath:mapper/*.xml
  configuration:
    map-underscore-to-camel-case: true # 开启下划线转驼峰

开启缓存

Mybatis的一级缓存的作用域是session,如果执行相同的SQL(相同语句和参数),Mybatis不进行执行SQL,而是从缓存中命中返回。

原理:Mybatis执行查询时首先去缓存区命中,如果命中直接返回,没有命中则执行SQL,从数据库中查询。

配置 mybatis.configuration.cacheEnabled=true 以开启缓存

mybatis:
  mapper-locations:
    - classpath:mapper/*.xml
  configuration:
    cacheEnabled: true # 开启缓存

注意:执行update、insert、delete的时候,会清空缓存

MyBatis配置文件

可以在项目配置中使用 config-location 指定MyBatis配置所在路径,将 configuration 下的配置都迁移到此配置中:
项目配置:

mybatis:
  type-aliases-package: com.example.mybatisxml.entity
  config-location: classpath:mybatis/mybatis-config.xml
  mapper-locations: classpath:mybatis/mapper/*.xml

MyBatis配置文件:mybatis-config.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <settings>
        <setting name="mapUnderscoreToCamelCase" value="true"/>
        <setting name="cacheEnabled" value="true"/>
    </settings>
</configuration>

二、使用步骤

基本步骤:

  1. 创建模型的实体类结构
  2. 创建数据访问层(DAO),用于定义操作数据库的接口
  3. 创建DAO的实现,可以是XML形式的Mapper,也可以是在接口中添加注解
  4. 创建服务的接口及其实现,用于方便地进行数据操作
  5. 在控制器中调用服务以完成数据操作

创建以下目录结构:
001.png

创建模型

使用MyBatis,首先需要创建模型映射,假设我们有如下一张表:

CREATE TABLE `user` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `username` varchar(64) DEFAULT NULL COMMENT '用户名',
  `password` varchar(64) DEFAULT NULL COMMENT '密码',
  `nickname` varchar(64) DEFAULT NULL COMMENT '昵称',
  `phone` varchar(64) DEFAULT NULL COMMENT '手机号码',
  `status` int(1) DEFAULT NULL COMMENT '帐号启用状态:0->禁用;1->启用',
  `create_time` datetime DEFAULT NULL COMMENT '注册时间',
  `icon` varchar(500) DEFAULT NULL COMMENT '头像',
  `gender` int(1) DEFAULT NULL COMMENT '性别:0->未知;1->男;2->女',
  `birthday` date DEFAULT NULL COMMENT '生日',
  PRIMARY KEY (`id`),
  UNIQUE KEY `idx_username` (`username`),
  UNIQUE KEY `idx_phone` (`phone`)
) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8 COMMENT='用户表';

我们为其创建一个model:

@Data
@AllArgsConstructor
@NoArgsConstructor
public class User implements Serializable {
    private Long id;
    private String username;
    private String password;
    private String nickname;
    private String phone;
    private Integer status;
    private Date createTime;
    private String icon;
    private Integer gender;
    private Date birthday;
    private static final long serialVersionUID = 1L;
}

创建数据访问层

DAO设计模式简介

  1. DAO全称是(Data Access Objects) ,数据库访问对象,主要的功能就是用于进行数据操作的,在程序的标准开发架构中属于数据访问层的操作。在MyBatis中也可称之为Mapper。
  2. DAO层一般有接口和该接口的实现类! 接口用于规范实现类! 实现类一般用于用于操作数据库! 一般操作修改,添加,删除数据库操作的步骤很相似,就写了一个公共类DAO类 ,修改,添加,删除数据库操作时 直接调用公共类DAO类!
  3. DAO其实一般没有这个类,这一般是指java中MVC架构中的model的概念,主要是访问数据库的一些方法。一般的java MVC架构中最外层是view也就是页面,control是一些控制后台和页面访问的类,model其实是dao层,但大部分人,会再增加一层service层来提供更为方便的应用。

我们为上面的模型添加一个Dao,现在只加入一个接口:统计成员数

@Mapper
public interface UserDao {
    int count();
}

DAO层接口可以为其指定 @Mapper@Repository 注解,以告诉spring容器这是一个DAO。不同的是,使用@Repository 注解需要在Spring启动类中添加 @MapperScan 包扫描路径。参考:
📃 依赖注入

为之创建对应的mapper:

<?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:命名空间,一般保证命名空间唯一 ,为了使用接口动态代理,这里必须是接口的全路径名 -->
<mapper namespace="com.example.test.dao.UserDao">
    <select id="count" resultType="java.lang.Integer">
        SELECT count(1) from user;
    </select>
</mapper>

select 中的几个属性说明:

  • id 唯一标识,在同一个命名空间下保持唯一,使用动态代理之后要求和方法名保持一致
  • resultType sql语句查询结果集的封装类型,使用动态代理之后和方法的返回类型一致;resultMap:二选一
  • parameterType 参数的类型,使用动态代理之后和方法的参数类型一致

如果不使用XML的形式的Mapper,可以直接使用注解进行标记:

public interface UserDao {
    @Select("SELECT count(*) FROM user")
    int count();
}

可以看到,查询数据时,在Mapper XML中使用 select 标签和在接口中使用 @Select 注解效果一致。

创建服务

创建一个服务的接口:

public interface UserService {
    int count();
}

实现这个接口:

@Service
public class UserServiceImpl implements UserService {
    @Autowired
    private UserDao userDao;

    @Override
    public int count() {
        return userDao.count();
    }
}

注意,需要在服务的实现类中添加 @Service 注解,以告诉Spring容器这是一个服务。

在控制器中调用

@RestController
@RequestMapping(value="/user")
public class UserController {
    @Autowired
    private UserService userService;

    @GetMapping("/count")
    public int count() {
        return userService.count();
    }
}

访问地址:http://localhost:8080/user/count

三、关于动态代理

使用mapper接口不用写接口实现类即可完成数据库操作,使用非常简单,也是官方所推荐的使用方法。

使用mapper接口的必须具备以几个条件:

  • 1)Mapper的namespace必须和mapper接口的全路径一致。
  • 2)Mapper接口的方法名必须和sql定义的id一致。
  • 3)Mapper接口中方法的输入参数类型必须和sql定义的parameterType一致。
  • 4)Mapper接口中方法的输出参数类型必须和sql定义的resultType一致。

四、类型别名

使用注解配置

首先配置别名扫描的包:

mybatis:
  type-aliases-package: com.example.test

使用 @Alias 为模型添加别名:

@Alias("user")
public class User {
    ...
}

在mapper中使用:

<resultMap id="BaseResultMap" type="user">
    ...
</resultMap>

已经为许多常见的 Java 类型内建了相应的类型别名。它们都是大小写不敏感的,需要注意的是由基本类型名称重复导致的特殊处理。

使用xml中配置

在MyBatis配置文件中添加别名配置了:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <typeAliases>
        <typeAlias alias="Integer" type="java.lang.Integer"/>
        <typeAlias alias="Long" type="java.lang.Long"/>
        <typeAlias alias="HashMap" type="java.util.HashMap"/>
        <typeAlias alias="LinkedHashMap" type="java.util.LinkedHashMap"/>
        <typeAlias alias="ArrayList" type="java.util.ArrayList"/>
        <typeAlias alias="LinkedList" type="java.util.LinkedList"/>
        <typeAlias alias="UserEntity" type="com.example.test.entity.UserEntity"/>
    </typeAliases>
</configuration>

就可以在Mapper中使用别名而非全包名了:

        <resultMap id="BaseResultMap" type="UserEntity">
        <id column="id" property="id" jdbcType="BIGINT"/>
        <result column="user_name" property="userName" jdbcType="VARCHAR"/>
        <result column="pass_word" property="passWord" jdbcType="VARCHAR"/>
        <result column="user_sex" property="userSex" javaType="com.example.test.enums.UserSexEnum"/>
        <result column="nick_name" property="nickName" jdbcType="VARCHAR"/>
    </resultMap>

比如上面的 type="UserEntity" ,如果没有配置别名,则需要写为:

type="com.example.test.entity.UserEntity"

参考:MyBatis XML配置 - typeAliases

五、SQL片段

通过以下两个标签创建和引入sql片段:

<sql id=""></sql>
<include refId="" />

测试:

<sql id="filed">
    username, password, nickname, phone, status, create_time, icon, gender, birthday
</sql>
<select id="list" resultMap="BaseResultMap">
    SELECT <include refid="filed"/> from user
</select>

参考资料