您当前的位置: 首页 >  sql

white camel

暂无认证

  • 0浏览

    0关注

    442博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

MyBatis拓展知识 :批量执行SQL语句、自定义TypeHandler来处理枚举类型

white camel 发布时间:2021-04-22 18:34:04 ,浏览量:0

一、批量执行SQL语句 (BatchExecutor)
  • 之前学习使用mybatis的foreach标签来, 批量查询sql, 这样的操作实际对MySQL数据库存在瓶颈问题,且效率很低

非批量的方式: 发一条sql, 预编译一次, 设置参数; 效率低

  • 发送SQL10000次, 预编译10000次, 设置参数1000次, 数据库执行10000次 在这里插入图片描述

批量的方式: 将sql语句先预编译好, 给该sql设置参数即可

  • 只发送SQL一次, 预编译一次, 设置参数1000次, 数据库执行一次 在这里插入图片描述
二、自定义TypeHandler来处理枚举类型 1、MyBatis中对枚举类型的处理
  • EnumTypeHandler(默认处理) : 通过枚举name来给预编译参数?设置值; 在这里插入图片描述

  • EnumOrdinalTypeHandler : 通过枚举的索引来给预编译参数?设置值; 在这里插入图片描述

测试 在这里插入图片描述 在这里插入图片描述

在这里插入图片描述 在这里插入图片描述

2、如果想要使用EnumOrdinalTypeHandler这种方式来处理

需要在mybatis-config.xml中来配置


     
    

此时再保存: 在这里插入图片描述

3、使用自定义的类型处理器来处理枚举类型

1、枚举类UserStatus

/**
 * Description: 希望数据库保存的是100, 200这些状态码, 而不是枚举的名字/索引
 *
 * @author guizy
 * @date 2021/4/22 17:37
 */
public enum UserStatus {
    LOGIN(100, "用户登录"), LOGOUT(200, "用户登出"), REMOVE(300, "用户不存在");

    private Integer code;
    private String msg;

    UserStatus(Integer code, String msg) {
        this.code = code;
        this.msg = msg;
    }

    public Integer getCode() {
        return code;
    }

    public void setCode(Integer code) {
        this.code = code;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }

    // 根据状态码返回枚举对象
    public static UserStatus getUserStatusByCode(Integer code) {
        switch (code) {
            case 100:
                return LOGIN;
            case 200:
                return LOGOUT;
            case 300:
                return REMOVE;
            default:
                return LOGOUT;
        }
    }
}

2、自定义枚举处理器

/**
 * Description: 自定义的枚举处理器, 保存枚举的状态码
 *
 * @author guizy
 * @date 2021/4/22 18:01
 */
public class MyEnumUserStatusTypeHandler implements TypeHandler {
    @Override
    public void setParameter(PreparedStatement ps, int i, UserStatus parameter, JdbcType jdbcType) throws SQLException {
        System.out.println("要保存的状态码:" + parameter.getCode());
        ps.setString(i, parameter.getCode().toString());
    }

    @Override
    public UserStatus getResult(ResultSet rs, String columnName) throws SQLException {
        // 需要根据从数据库中拿到的枚举状态码, 返回一个UserStatus枚举对象
        int code = rs.getInt(columnName);
        System.out.println("从数据库中获取的状态码:" + code);
        return UserStatus.getUserStatusByCode(code);
    }

    @Override
    public UserStatus getResult(ResultSet rs, int columnIndex) throws SQLException {
        int code = rs.getInt(columnIndex); // 根据索引来拿
        System.out.println("从数据库中获取的状态码:" + code);
        return UserStatus.getUserStatusByCode(code);
    }

    @Override
    public UserStatus getResult(CallableStatement cs, int columnIndex) throws SQLException {
        int code = cs.getInt(columnIndex);
        System.out.println("从数据库中获取的状态码:" + code);
        return UserStatus.getUserStatusByCode(code);
    }
}

3、在mybatis-config.xml中配置


    
    

除了在上面全局配置之外, 也可以在处理某个字段的时候告诉MyBatis用什么类型处理器

  • 保存操作: #{empStatus,typeHandler=xxxx}


    INSERT INTO user (id, name, pwd, userStatus)
    VALUES (null, #{name}, #{pwd}, #{userStatus, typeHandler=com.sunny.handler.MyEnumUserStatusTypeHandler});

  • 查询操作: 可以在resultMap的列标签中来配置, 如下

	
	

注意: 如果在参数位置修改TypeHandler,应该保证保存数据和查询数据用的TypeHandler是一样的。

4、测试

    @Test
    public void testEnum() {
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        User user = new User("TestEnum", "1234");
        mapper.insertUser(user);
        System.out.println("保存成功: " + user.getId());
        sqlSession.commit();
        sqlSession.close();
    }
DEBUG [main] - ==>  Preparing: INSERT INTO user (id, name, pwd, userStatus) VALUES (null, ?, ?, ?); 
要保存的状态码:200
DEBUG [main] - ==> Parameters: TestEnum(String), 1234(String), 200(String)
DEBUG [main] -             
关注
打赏
1661428283
查看更多评论
0.0411s