Spring Boot整合MyBatis框架操作MySQL数据库实例

Spring Boot整合MyBatis框架

引入MyBatis的starter

在maven的pom.xml文件中引入如下的mybatis依赖,这里的数据库使用MySQL,所以同时加入MySQL的依赖:

        <!-- 配置MySQL依赖 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.42</version>
        </dependency>
        <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>1.3.2</version>
        </dependency>

创建POJO实例

创建User类如下,@Data注解为使用了lombok库,@Alias注解为使用MyBatis的别名,即将当前的User类别名定义为user,这样在MyBatis的xml文件中进行设置时,可以直接使用这里定义的别名,无需使用User类的全限定名。(如果这里不使用别名,则后续xml中使用该类时,需要使用该类的全限定名)

@Data
@Alias(value = "user")
public class User {

    private Long id;

    @NotNull(message = "用户名不能为空")
    private String userName;

    @NotNull(message = "备注不能为空")
    private String note;

    @NotNull(message = "性别不能为空")
    private SexEnum sex;
}

同时注意这里的sex属性的类型为SexEnum枚举类型,所以需要定义一个typeHandler来进行转换:

// 声明JDBCType为整型
@MappedJdbcTypes(JdbcType.INTEGER)
// 声明JavaType为SexEnum
@MappedTypes(value = SexEnum.class)
public class SexTypeHandler extends BaseTypeHandler<SexEnum> {
    /**
     * 设置非空性别参数
     */
    @Override
    public void setNonNullParameter(PreparedStatement preparedStatement, int i, SexEnum sexEnum, JdbcType jdbcType) throws SQLException {
        preparedStatement.setInt(i, sexEnum.getId());
    }

    /**
     * 通过列名读取性别
     */
    @Override
    public SexEnum getNullableResult(ResultSet resultSet, String s) throws SQLException {
        int sex = resultSet.getInt(s);
        if (sex != 1 && sex != 2) {
            return null;
        }
        return SexEnum.getEnumById(sex);
    }

    /**
     * 通过下标读取性别
     */
    @Override
    public SexEnum getNullableResult(ResultSet resultSet, int i) throws SQLException {
        int sex = resultSet.getInt(i);
        if (sex != 1 && sex != 2) {
            return null;
        }
        return SexEnum.getEnumById(sex);
    }

    /**
     * 通过存储过程读取性别
     */
    @Override
    public SexEnum getNullableResult(CallableStatement callableStatement, int i) throws SQLException {
        int sex = callableStatement.getInt(i);
        if (sex != 1 && sex != 2) {
            return null;
        }
        return SexEnum.getEnumById(sex);
    }
}

这样MyBatis就可以根据这里的设置,自动将sex的枚举类型转换为Integer类型。

创建数据库表结构

根据上述的User类,定义如下的数据库表结构:

create table t_user (
	id int(12) not null auto_increment,
	user_name varchar(60) not null,
	sex int(3) not null default 1 check (sex in(1,2)),
	note varchar(256) null,
	primary key(id)
);

创建MyBatis映射文件

完成上述的步骤后,MyBatis支持使用注解和配置文件的方式来实现SQL和POJO的映射关系,这里使用XML配置文件的方式进行,定义userMapper.xml如下:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org/DTD Mapper 3.0" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.zyt.springbootlearning.dao.UserMapper">
    <select id="getUserById" parameterType="long" resultType="user">
        select id, user_name as userName, sex, note from t_user where id = #{id}
    </select>
</mapper>

该文件的所在路径为:/resources/mapper/userMapper.xml,后面需要该xml所在的路径进行配置。

可以看到,该文件中存在几个关键的配置信息,如下:

  1. namespace:指明用于操作该表的一个接口的全限定名,后续会进行创建。
  2. parameterType:定义select语句中使用的参数的类型,这里的Id为Long类型。
  3. resultType:指明查询语句执行后得到的返回值类型。由于上述User类中使用了MyBatis的别名设置,所以这里可以直接使用上述设置的user别名,如果没有使用别名,则需要使用User类的全限定名:cn.zyt.springbootlearning.domain.User。
  4. select标签内,使用SQL创建需要进行数据库操作的SQL语句,这里的查询列名需要和POJO类中的属性名保持一致,MyBaits会自动启动这种映射。但注意这里的userName列使用了别名将查询后的结果映射到User类的useName属性。针对这种情况,也可以开启驼峰映射,这样就可以不使用别名了(这个在application.properties中进行设置,开启驼峰映射)。或者在userMapper.xml配置文件中,使用ResultMap指明属性名和数据表表列名之间的映射关系。如下:
    <resultMap id="getUserByResultMap" type="cn.zyt.springbootlearning.domain.User">
        <result property="userName" column="user_name"/>
    </resultMap>

    <select id="getUserByMap" parameterType="long" resultMap="getUserByResultMap">
        select id, user_name as userName, sex, note from t_user where id = #{id}
    </select>

resultMap标签中的property为POJO中的属性名,column为表中的列名,通过这种定义就可以将POPO中的属性名和表中的列名映射起来,同时如果使用了resultMap,select标签中的SQL返回时不在使用returnType而是需要指明resultMap(根据resultMap的id指明)。resultMap还有很多有用的功能,这里只是简单的进行使用。

定义MyBatis映射接口

上述namespace指明了该select语句对应的接口全限定名,所以需要定义如下对应的结构,来映射到这条select语句:

@Repository
public interface UserMapper {
    User getUserById(Long id);
}

注意这里使用了@Repsitory注解,这样就定义好了select语句相对应的查询方法,接口中的方法名与mapper.xml文件中select标签中的id需一致。

在application.properties配置文件中配置mybatis相关设置

# MySQL配置项
spring.datasource.url=jdbc:mysql://[mysql_server_ip]:3306/dev_springboot
spring.datasource.username=[username]
spring.datasource.password=[password]
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.tomcat.max-idle=10
spring.datasource.tomcat.max-wait=10000
spring.datasource.tomcat.max-active=50
spring.datasource.tomcat.min-idle=5
spring.datasource.tomcat.initial-size=5

# MyBatis配置项
mybatis.mapper-locations=classpath:mapper/*.xml
mybatis.type-aliases-package=cn.zyt.springbootlearning.domain
mybatis.type-handlers-package=cn.zyt.springbootlearning.typehandler
mybatis.configuration.map-underscore-to-camel-case=true
mybatis.configuration.default-fetch-size=100
mybatis.configuration.default-statement-timeout=30

在mybatis的配置项中,有如下几个需要注意:

  • mybatis.mapper-locations:定义了项目中mapper.xml映射文件所在的目录
  • mybatis.type-aliases-packages:定义MyBatis扫描别名的包,与上述@Alias注解联用。
  • mybatis.type-handlers-package:由于上述使用到了typeHandler,这里需要指明typeHandler所在的包
  • mybatis.configuration.map-underscore-to-camel-case=true:开启驼峰映射,这样mybatis可以直接将数据表中的user_name列名映射为userName属性值,无需其他配置

Spring Boot整合MyBatis

在Spring Boot中使用MyBatis中定义的UserMapper接口的getUserById方法时,有几种不同的方式:

  • 使用MapperFactoryBean装配MyBatis接口
  • 使用MapperScannerConfigurer扫描装配MyBatis接口
  • 使用@MapperScan注解扫描装配MyBatis接口

其中,最后一种方式最简单且常用,所以下面使用最后一种方式来扫描并装配MyBatis接口。在Spring Boot项目的启动类中加入如下注解:

@SpringBootApplication(scanBasePackages = {"cn.zyt.springbootlearning.*"})
@MapperScan(basePackages = "cn.zyt.springbootlearning.*", annotationClass = Repository.class)
public class SpringbootLearningApplication {
    ...
}

注意上述的@MapperScan注解,该注解允许我们通过扫描加载MyBatis的mapper。并且这在MyBatis接口中使用了@Respository注解,所以在annotationClass定义为Respository,同时Spring Boot还提供了一个@Mapper注解,其作用于@Respository注解相同,二者选用其一即可。

创建Service和Controller进行测试

通过上述的过程即基本完成了Spring Boot中整合MyBatis的过程,只是在使用MyBatis时需要根据具体的业务逻辑更加深入的使用MyBatis的功能即可。下面使用上述定义的UserMapper接口中的getUserById方法,创建相应的Service和Controller对整合的情况进行测试。

1. 创建如下的UserService接口和UserServiceImpl实现类:

public interface UserService {
    User getUserById(Long id);
}
@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserMapper userMapper;

    @Override
    public User getUserById(Long id) {
        return userMapper.getUserById(id);
    }
}

2. 创建如下的UserController类:

@Controller
@RequestMapping("/user")
public class UserController {

    @Autowired
    private UserService userService;

    @RequestMapping("/getUserById")
    @ResponseBody
    public User getUserById(Long id) {
        User user = userService.getUserById(id);
        return user;
    }
}

3. 完成上述内容后,启动Spring Boot项目,然后在浏览器中输入: http://localhost:8080/user/getUserById来进行测试,即可得到数据库中相应的返回数据(前提是数据库中有数据,上述过程没有进行参数校验和有效性查询)。

通过以上过程即完成了Spring Boot项目整合MyBatis的过程,后续需要更加详细的学习MyBatis的使用。上面仅是简单的使用select语句使用id进行了数据库的查询操作,下面给出一些其他的mapper.xml配置,以供参考:

    <insert id="insertUser" parameterType="cn.zyt.springbootlearning.domain.User" useGeneratedKeys="true" keyProperty="id">
        insert into t_user (user_name, sex, note) values (#{userName}, #{sex}, #{note})
    </insert>

    <select id="getUserList" resultType="cn.zyt.springbootlearning.domain.User">
        select * from t_user
    </select>

    <select id="searchUser" resultType="cn.zyt.springbootlearning.domain.User">
        select * from t_user where id = #{userId} or user_name = #{userName}
    </select>

上述的代码来自自己的springboot-learning项目,感兴趣的可以进行查看:https://github.com/Yitian-Zhang/springboot-learning

发布了296 篇原创文章 · 获赞 35 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/yitian_z/article/details/104156201