springboot——typeHandler的使用

  1. 使用场景

typeHandler,类型转换器,就是将数据库中的类型与Java中的类型进行相互转换的处理器。

有时候,我们进行存储时的字段类型和数据库最终存储的字段类型是不一致的:比如我们在springboot传入的是一个list,而在数据库中需要以VARCHAR类型保存;又比如我们在springboot传入一个JSON类型,而数据库中以String类型存储该字段;或者说数据库中是JSON类型,但java无找不到对应的JSON类型(直接使用JSONObject会报错),也可以使用typeHandler。

一般情况,我们可以强转String再存储该字段,但有时候查询数据时会出现问题:较为典型的是String类型的JSON串数据,以String类型返回至前端时,会由于进行两次json解析,导致返回结果反斜杆:

而这会导致前端解析时出错,所以我们需要用typeHandler对其进行转换:

简而言之,typeHandler就是当springboot后端实体类中字段类型和数据库中字段类型不一致时进行使用。

2. mybatis下使用typeHandler

首先,我们需要编写一个typeHandler(以JSON转VARCHAR为例):

@MappedTypes(JSONObject.class)
@MappedJdbcTypes(JdbcType.LONGVARCHAR)
public class JsonObjectTypeHandler extends BaseTypeHandler<JSONObject> {

    /**
     * 插入数据时,将JSONObject转String
     * @param ps
     * @param i
     * @param parameter
     * @param jdbcType
     * @throws SQLException
     */
    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, JSONObject parameter, JdbcType jdbcType) throws SQLException {
        ps.setString(i, JSONObject.toJSONString(parameter));
    }

    /**
     * 根据列名,获取可以为空的结果
     * @param rs
     * @param columnName
     * @return
     * @throws SQLException
     */
    @Override
    public JSONObject getNullableResult(ResultSet rs, String columnName) throws SQLException {
        String sqlJson = rs.getString(columnName);
        if (null != sqlJson){
            return JSONObject.parseObject(sqlJson);
        }
        return null;
    }

    /**
     * 根据列索引,获取可以为空的结果
     * @param rs
     * @param columnIndex
     * @return
     * @throws SQLException
     */
    @Override
    public JSONObject getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
        String sqlJson = rs.getString(columnIndex);
        if (null != sqlJson){
            return JSONObject.parseObject(sqlJson);
        }
        return null;
    }

    @Override
    public JSONObject getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
        String sqlJson = cs.getString(columnIndex);
        if (null != sqlJson){
            return JSONObject.parseObject(sqlJson);
        }
        return null;
    }
}

注意,该typeHandler需要放在mapper文件夹下(即和mapper类放在一起,否则会找不到)

然后,在mapper.xml文件中,编写resultmap映射字段,并指定哪些字段需要使用typeHandler:

<!--字段映射,将数据库中String类型的json串映射为JSONObject,避免返回前段时两次序列化使得返回结果带反斜杠-->
    <resultMap id="illnessMap" type="com.seven.springcloud.dto.IllnessDTO">
        <result column="Weight" property="Weight" javaType="com.alibaba.fastjson.JSONObject" jdbcType="VARCHAR"
                typeHandler="com.seven.springcloud.mapper.JsonObjectTypeHandler"/>
        <result column="Add_date" property="Drug_Date"/>
    </resultMap>
    <!--查询所有病人的信息-->
    <select id="selectUserIllness" resultMap="illnessMap">
        select * from user_illness where Account=#{Account}
    </select>

然后,实体类中,将字段类型设为JSONObject:

@Data
@AllArgsConstructor
@NoArgsConstructor
@JsonInclude(JsonInclude.Include.NON_EMPTY)     //空值不返回
public class IllnessDTO implements Serializable {
    private JSONObject Weight;
    private String Drug_Date;
}

然后,就可以成功映射数据啦。

查看数据库,保存的是一个String类型的JSON串:

3. mybatis plus下使用typeHandler

使用mybatis plus时,我们也可以使用mybatis的方式,xml文件中编写resultMap的形式映射字段;也可以选择以mybatis plus的注解的形式使用。

首先,我们仍然需要编写一个typeHandler类:

@MappedJdbcTypes(JdbcType.VARCHAR)  //数据库类型
@MappedTypes({JSONObject.class})          //java数据类型
public class JsonTypeHandler implements TypeHandler<JSONObject> {
    @Override
    public void setParameter(PreparedStatement ps, int i, JSONObject parameter, JdbcType jdbcType) throws SQLException {
        if (parameter!=null){
            ps.setString(i, JSONObject.toJSONString(parameter));
        }

    }

    @Override
    public JSONObject getResult(ResultSet rs, String columnName) throws SQLException {
        return JSONObject.parseObject(rs.getString(columnName));
    }

    @Override
    public JSONObject getResult(ResultSet rs, int columnIndex) throws SQLException {
        return JSONObject.parseObject(rs.getString(columnIndex));
    }

    @Override
    public JSONObject getResult(CallableStatement cs, int columnIndex) throws SQLException {
        return JSONObject.parseObject(cs.getString(columnIndex));
    }
}

注:我们需要再application.yml文件中指定该typeHandler所在的包的位置,否则会找不到:

mybatis-plus:
  type-handlers-package: com.seven.demo.typerHandler

然后,我们在实体类进行配置即可:

@TableName(value ="student",autoResultMap = true)    //autoResultMap为true才会自动配置resultMap映射字段
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Student implements Serializable {

    @TableId
    private Long id;

    private String name;

    @TableField(value = "grade", typeHandler = JsonTypeHandler.class)    //指定typeHandler进行转换类型
    private JSONObject grade;

    @TableField(exist = false)
    private static final long serialVersionUID = 1L;
}

然后,我们就可以对类型进行转换了。

下面我们可以编写接口测试一下:

@RestController
public class StudentController {
    @Resource
    private StudentService studentService;

    @PostMapping("/add")
    public boolean add(@RequestBody Student student){
        return studentService.save(student);
    }

    @GetMapping("/get")
    public Student get(@RequestParam("id")int id){
        return studentService.getById(id);
    }
}

测试成功,查看数据库:

成功保存字符类型json串。

### Spring Boot 2 中 WebSocket 集成教程 在 Spring Boot 2 中集成和使用 WebSocket 可以为应用程序提供实时通信功能。以下是关于如何在 Spring Boot 2 中设置并使用 WebSocket 的详细介绍。 #### 1. 添加依赖项 为了启用 WebSocket 支持,在项目的 `pom.xml` 文件中需要添加以下 Maven 依赖项: ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-websocket</artifactId> </dependency> ``` 此依赖项提供了对 WebSocket 协议的支持以及必要的组件来处理消息传递[^1]。 #### 2. 启用 WebSocket 配置 创建一个配置类以注册 WebSocket 处理器和其他相关 Bean。可以通过实现 `WebSocketConfigurer` 接口完成这一过程。 ```java import org.springframework.context.annotation.Configuration; import org.springframework.web.socket.config.annotation.EnableWebSocket; import org.springframework.web.socket.config.annotation.WebSocketConfigurer; import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry; @Configuration @EnableWebSocket public class WebSocketConfig implements WebSocketConfigurer { private final MyWebSocketHandler myWebSocketHandler; public WebSocketConfig(MyWebSocketHandler myWebSocketHandler) { this.myWebSocketHandler = myWebSocketHandler; } @Override public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) { registry.addHandler(myWebSocketHandler, "/ws").setAllowedOrigins("*"); } } ``` 上述代码片段展示了如何通过自定义处理器 (`MyWebSocketHandler`) 来管理 WebSocket 请求,并允许跨域访问。 #### 3. 实现 WebSocket Handler 接下来,需编写具体的逻辑来处理传入的消息。这通常由继承 `TextWebSocketHandler` 或者 `BinaryWebSocketHandler` 类的子类完成。 ```java import org.springframework.stereotype.Component; import org.springframework.web.socket.TextMessage; import org.springframework.web.socket.WebSocketSession; import org.springframework.web.socket.handler.TextWebSocketHandler; @Component public class MyWebSocketHandler extends TextWebSocketHandler { @Override protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception { String payload = message.getPayload(); System.out.println("Received Message: " + payload); // Echo back the received message to client. session.sendMessage(new TextMessage("Echo: " + payload)); } } ``` 这段代码实现了基本的功能——接收来自客户端的消息并将它们回显给发送方。 #### 4. 测试 WebSocket 连接 可以利用 JavaScript 和 HTML 页面测试已建立的服务端点 `/ws` 是否正常工作。下面是一个简单的前端例子: ```html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>WebSocket Test</title> </head> <body> <script type="text/javascript"> var socket = new WebSocket('ws://localhost:8080/ws'); socket.onopen = function() { console.log('Connected'); socket.send('Hello Server!'); }; socket.onmessage = function(event) { console.log('Message from server:', event.data); }; </script> </body> </html> ``` 当页面加载完成后,它会尝试连接到服务器并通过 WebSocket 发送一条问候语。如果一切顺利的话,应该能看到控制台打印出服务端返回的信息。 --- ### 总结 以上就是在 Spring Boot 2 中集成功能强大的 WebSocket 技术的方法概述。借助这些步骤,开发者能够轻松构建具备双向通讯能力的应用场景,从而提升用户体验质量。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值