zoukankan      html  css  js  c++  java
  • 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不能登录,以后再说

  • 相关阅读:
    利用dockerfile定制镜像
    发布Docker 镜像到dockerhub
    Docker 停止容器
    133. Clone Graph
    132. Palindrome Partitioning II
    131. Palindrome Partitioning
    130. Surrounded Regions
    129. Sum Root to Leaf Numbers
    128. Longest Consecutive Sequence
    127. Word Ladder
  • 原文地址:https://www.cnblogs.com/myboat/p/11496997.html
Copyright © 2011-2022 走看看