• STS中MyBatis的基本实现


    本文采用的是《深浅spring boot 2.x》中第5章的例子,用一个接口实现对一个表项的读取。

    数据库:mysql下建立user数据库,表名为t_usr

    1. 数据源设置

    在application.properties文件中加入数据源设置项:

    #数据源设置(user是数据库的名称,一开始没有理解,写成了项目名称)
    spring.datasource.url = jdbc:mysql://localhost:3306/user
    spring.datasource.username = root
    spring.datasource.password = 123456
    spring.datasource.driver-class-name = com.mysql.cj.jdbc.Driver
    spring.datasource.tomcat.max-idle = 10
    spring.datasource.tomcat.max-active = 50
    spring.datasource.tomcat.max-wait = 10000
    spring.datasource.tomcat.initial-size = 5

    这里使用了内置的mysql数据源,也可根据需要设置DBCP2

    2. 相关依赖项的添加

    在pom.xml中添加相关依赖项:

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

    <dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis</artifactId>
    <version>3.4.4</version>
    </dependency>

    3. 建立POJO类及其读取操作服务接口

    3.1 建立一个User类:

    @Alias(value = "user") //基于MyBatis的别名,为映射作准备
    public class User {
    private Long id = null;
    private String userName = null;
    private SexEnum sex = null; //性别枚举,这里需要使用typehandler进行转换(转换较多用于枚举)
    private String note = null;
    //**********setter 和 getter必须有,这里省略*****************************************
    }

    其中SexEnum是一个enum类型:

    public enum SexEnum {
    MALE(1, "男"), FEMALE(2, "女");

    private int id;
    private String name;
    SexEnum(int id, String name){
    this.id = id;
    this.name = name;
    }

    public static SexEnum getEnumById(int id) {
    for(SexEnum sex : SexEnum.values()) {
    if(sex.getId() == id) {
    return sex;
    }
    }
    return null;
    }

    public void setId(int id) {
    this.id = id;
    }

    public int getId() {
    return id;
    }

    public void setName(String name) {
    this.name = name;
    }

    public String getName() {
    return name;
    }
    }

    根据要求enum必须建立类型处理typeHandler

    3.2 建立typeHandler

    由于性别是enum类型,所以必须建立数据库表中数据类型与SexEnum类之间的转换关系:

    //实现JDBC与SexEnum之间的转换关系
    //声明JdbcType为整形
    @MappedJdbcTypes(JdbcType.INTEGER)
    //声明JavaType为SexEnum
    @MappedTypes(value = SexEnum.class)
    public class SexTypeHandler extends BaseTypeHandler<SexEnum> {

    //设置非空性别参数,为存储作准备
    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, SexEnum parameter, JdbcType jdbcType)
    throws SQLException {
    ps.setInt(i, parameter.getId());

    }

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

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

    }

    3.3 建立一个读取user表的接口(MyBatisUserDao ),该接口不实现,其实现交给mybatis的MapperFactoryBean自动生成

    该接口由MapperFactoryBean自动实现。

    这里的@Repository是必须的,但没有明白其具体含义

    @Repository
    public interface MyBatisUserDao {
    public User getUser(Long id);
    }

    3.4 建立调用上面MyBatisUserDao的服务接口并实现之(服务类必须由接口实现)

    (1)接口

    import boat.db.pojo.*;
    public interface MyBatisUserService {
    public User getUser(Long id);
    }

    (2)服务实现

    该服务调用由MapperFactoryBean实现的MyBatisUserDao.getUser(Long id)函数

    @Service
    public class MyBatisUserServiceImp implements MyBatisUserService {

    @Autowired
    private MyBatisUserDao myBatisUserDao = null;
    @Override
    public User getUser(Long id) {
    return myBatisUserDao.getUser(id);
    }

    }

    4. 建立User、MyBatisUserDao 和SQL语句之间的映射关系(即POJO实体、数据操作接口及SQL语句之间的映射关系),以便mybatis进行自动化实现

    建立一个XML(userMapper.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="boat.db.db.MyBatisUserDao">
    <select id="getUser" parameterType="long" resultType="user">
    select id, user_name as userName, sex, note from user.t_user where id = #{id}
    </select>
    </mapper>

    (1)这里的namespace属性对应我们声明的MyBatisUserDao接口,我们将它交给MyBatis实现

    (2)MyBatisUserDao中的函数getUser的映射放在其子节点中,节点的名称为select,说明是一个SELECT语句,对应的函数是id="getUser",函数的输入参数类型parameterType="long",返回类型resultType="user"。

    (3)该子节点的内容为getUser对应的SQL语句。

    5. 配置映射文件和mybatis扫描的包

    在application.properties文件中增加下列内容:

    #MyBatis映射文件通配
    mybatis.mapper-locations = classpath:/boat/db/*.xml
    #MyBatis扫描别名包,与注解@Alias联用
    mybatis.type-aliases-package = boat.db.pojo
    #配置typeHandler的扫描包
    mybatis.type-handlers-package = boat.db.pojo
    #日志配置
    logging.level.root = DEBUG
    logging.level.org.springframework = DEBUG
    logging.level.org.org.mybatis = DEBUG

    (1)将映射文件的位置用classpath属性给出。

    (2)给出POJO类的包名,供mybatis扫描。

    (3)给出typeHandler的包名,供mybatis扫描

    (4)日志配置成DEBUG型

    6. 基于Spring boot集成mybatis

    在主类(带main函数的类)中加入下列代码:

    @Autowired
    SqlSessionFactory sqlSessionFactory = null;

    @Bean
    public MapperFactoryBean<MyBatisUserDao> initMyBatisUserDao() {
    MapperFactoryBean<MyBatisUserDao> bean = new MapperFactoryBean<>();
    bean.setMapperInterface(MyBatisUserDao.class);
    bean.setSqlSessionFactory(sqlSessionFactory);
    return bean;
    }

    (1)自动生成一个SqlSessionFactory ,用于根据前面的POJO、操作接口和SQL之间的映射关系自动实现代码;

    (2)生成一个基于MyBatisUserDao和SqlSessionFactory 的MapperFactoryBean,这个Bean实现了MyBatisUserDao操作接口的自动化;

    7. 运行和调试

    建立一个Controller,用于调用服务

    @Controller
    @RequestMapping("/mybatis")
    public class MyBatisController {
    @Autowired
    private MyBatisUserService myBatisUserService = null;
    @RequestMapping("/getuser")
    @ResponseBody
    public User getUser(Long id) {
    return myBatisUserService.getUser(id);
    }
    }

    @ResponseBody是作用在方法上的,@ResponseBody 表示该方法的返回结果直接写入 HTTP response body 中,一般在异步获取数据时使用【也就是AJAX】,在使用 @RequestMapping后,返回值通常解析为跳转路径,但是加上 @ResponseBody 后返回结果不会被解析为跳转路径,而是直接写入 HTTP response body 中。 比如异步获取 json 数据,加上 @ResponseBody 后,会直接返回 json 数据。@RequestBody 将 HTTP 请求正文插入方法中,使用适合的 HttpMessageConverter 将请求体写入某个对象。

    然后调试运行,出现的两个错误

    一是找不到数据库:提示是没有找到DB_Example 数据库,我发现由于理解错误,在application.properties中将spring.datasource.url 项搞错了,写成了 jdbc:mysql://localhost:3306/DB_Example ,DB_Example 是项目名称,改变数据库名user后通过。

    二是时区错误:第一项改了后,运行时提示“mysql时区错误”。查百度后,认为需要重新配置mysql时区,但在cmd中无论如何登录mysql都失败了,查了很多百度,但也不成功。后来发现my.ini文件中有时区设置项,将原来的:

    [mysqld_safe]
    time-zone='UTC'

    改为:

    [mysqld]
    default-time-zone='+08:00'

    运行成功

    第三未解决问题:mysql不能登录,以后再说

  • 相关阅读:
    Leetcode刷题笔记
    Leetcode刷题笔记
    朋友发来的图片,要制作成身份证复印件,怎么办?
    记录一次MAC连接投影闪屏的问题。
    win10系统 端口查看问题。
    使用Windows命令行reg控制注册表键值
    SVN钩子HOOK设置自动备份,服务本地可以看到所有更新内容。
    报错代码:svn-http status413'requset entity too large
    SVN: Cleanup failed update报错 文件被锁定lock办法,cleanup 失效报错。
    Samba centos7文件共享服务器搭建教程,可以更改任意需求操作配置详解。
  • 原文地址:https://www.cnblogs.com/myboat/p/11496997.html
Copyright © 2020-2023  润新知