Java 枚举类使用实践

涉及知识点

  • 前台Thymeleaf下拉列表使用枚举类
  • 后台实体类使用枚举类接收前台传值
  • 自定义Mybatis枚举类转换器,插入枚举类数据和查询数据封装为枚举类
  • EnumMap,使用枚举类作为Key的Map

目录

  • 前台
  • 枚举类
  • 实体类
  • 数据库
  • Mybatis自定义枚举类转换器
  • Mapper
  • 插入后查询
  • 效果
    • 枚举类数据通过自定义转换器处理,插入数据库成功
    • 对数据查询,通过自定义转换器封装为枚举类
    • 将数据封装为EnumMap这种枚举类为key的数据格式
    • 前台接收到后台返回值

前台

DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Titletitle>
head>
<body>
<div>
    <select id="test">
        
        <option th:each="enmu:${enums}" th:value="${enmu.code}" th:text="${enmu.name}">option>
    select>
    <button onclick="submitData()">提交请求button>
div>
body>
<script th:src="@{/js/jquery.min.js}">script>
<script th:inline="javascript" type="text/javascript">
	// 获取项目根路径
    const ctxPath = [[${#httpServletRequest.getContextPath()}]];

    async function submitData() {
		
		// 属性名需要和后台用来接收的实体类的属性名保持一致
        const data = {
            name: '贾飞天',
            sexTypes: $("#test").val()
        };
		
		// 使用fetch发送请求,提交前台json数据
        const result = await fetch(ctxPath + '/enum/getValue', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json;charset=utf-8'
            },
            body: JSON.stringify(data)
        })
        
        // 获取后台返回的json数据
        const json = await result.json();
        console.log(json);
    }
script>
html>

枚举类

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonFormat;

import java.util.Arrays;

/*
	SexTypes被组合到Teacher实体类中,当SpingBoot接收到前台的数据进行封装的时候
	需要使用jackson中的注解指定封装到枚举类中
*/ 
@JsonFormat(shape = JsonFormat.Shape.OBJECT)
public enum SexTypes {

    男性("1"),
    女性("2"),
    保密("3");
    
    private String code;

    SexTypes(String code) {
        this.code = code;
    }

    public String getCode() {
        return code;
    }

    /*
    	根据code获取枚举类对象
    	SpringBoot在将前台数据封装的时候,通过@JsonCreator注解对应的方法
    	指定前台的性别code转换为对应的枚举类
	*/ 
    @JsonCreator
    public static SexTypes fromCode(String code) {
        return Arrays.stream(SexTypes.values())
                .filter(item -> item.code.equals(code)).findAny().orElse(null);

    }

    public static SexTypes fromName(String name) {

        return Arrays.stream(SexTypes.values())
                .filter(item -> item.name().equals(name)).findAny().orElse(null);
    }
}

实体类

public class Teacher {

    private String name;
    private SexTypes sexTypes;

    public Teacher(String name, SexTypes sexTypes) {
        this.name = name;
        this.sexTypes = sexTypes;
    }

    // 省略get,set,toString...
}

数据库

Java 枚举类使用实践_第1张图片

Mybatis自定义枚举类转换器

import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.MappedJdbcTypes;
import org.apache.ibatis.type.MappedTypes;

// 数据库字段所对应的类型
@MappedJdbcTypes({JdbcType.VARCHAR})
// 需要转换为JAVA侧的类型
@MappedTypes(value = SexTypes.class)
// 进行类型转换需要继承Mybatis的BaseTypeHandler类
public class CustomEnumTypeHandler extends BaseTypeHandler<SexTypes> {
    
    // 重写BaseTypeHandler中的方法
    @Override
    public void setNonNullParameter(PreparedStatement preparedStatement, int i, SexTypes parameter, JdbcType jdbcType) throws SQLException {
    	/*
    		当插入数据的时候(#{参数名}),会调用此方法,将枚举类中的code当做参数插入
    		因为数据库中的sex为varchar类型,因此设置参数类型为string
		*/ 
        preparedStatement.setString(i, parameter.getCode());
    }
	
	// 当进行查询的时候,会通过code获取到对应的枚举类
    @Override
    public SexTypes getNullableResult(ResultSet resultSet, String s) throws SQLException {
        String code = resultSet.getString(s);
        return SexTypes.fromCode(code);
    }

    @Override
    public SexTypes getNullableResult(ResultSet resultSet, int i) throws SQLException {
        String code = resultSet.getString(i);
        return SexTypes.fromCode(code);
    }

    @Override
    public SexTypes getNullableResult(CallableStatement callableStatement, int i) throws SQLException {
        String code = callableStatement.getString(i);
        return SexTypes.fromCode(code);
    }
}

将自定义枚举类转换器添加到全局配置文件application.properties

# 指定转换器包所在的路径
mybatis.type-handlers-package=com.example.demo.EnumPack

Mapper


DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.demo.mapper.TestEnumInsert">
    <select id="insertEnumData" parameterType="com.example.demo.form.EnumTestFrom">
      INSERT
        INTO myblog.enumuser(name, sex)
        
        VALUES (#{name}, #{sexTypes})
    select>

    <select id="selectAllData" resultType="com.example.demo.mybatisTest.Teacher">
    	
        SELECT * from myblog.enumuser
    select>
mapper>
public interface TestEnumInsert {
	
	// 插入枚举类数据
    void insertEnumData(EnumTestFrom form);
	
	// 查询所有的数据
    List<Teacher> selectAllData();
}

插入后查询

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

import java.util.EnumMap;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

@Controller
@RequestMapping("/enum")
public class EnumTestController {

    @Autowired
    private TestEnumInsert mapper;

    @GetMapping("/init")
    public ModelAndView init() {
    
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("enum");
        // 将枚举类数组传给前台下拉列表使用
        modelAndView.addObject("enums", SexTypes.values());
        return modelAndView;
    }

    @PostMapping("/getValue")
    @ResponseBody
    public ResultInfo getValueFromView(@RequestBody EnumTestFrom form) {
		
		// 先将前台的数据插入数据库
        mapper.insertEnumData(form);
		
		// 插入完成之后查询所有的Teacher数据
        List<Teacher> teachers = mapper.selectAllData();

        // 教师按照性别枚举类进行分组
        EnumMap<SexTypes, Set<Teacher>> collect = teachers.stream().collect(
                Collectors.groupingBy(
                        // 参数一: 分组按照什么进行分类,此处按照教师性别进行分类
                        Teacher::getSexTypes,
                        // 参数二: 分组最后用什么容器保存返回,默认是HashMap::new.此处我们指定使用EnumMap
                        () -> new EnumMap<>(SexTypes.class),
                        // 参数三: 按照第一个参数分类之后,对应的分类的结果如何收集,默认是Collectors.toList
                        Collectors.toSet()
                )
        );
        System.out.println(collect);
		
		// 将封装好的EnumMap数据封装到自定义实体类中返回前台
        return new ResultInfo("成功", collect);
    }
}

效果

枚举类数据通过自定义转换器处理,插入数据库成功

Java 枚举类使用实践_第2张图片

Java 枚举类使用实践_第3张图片

对数据查询,通过自定义转换器封装为枚举类

Java 枚举类使用实践_第4张图片

将数据封装为EnumMap这种枚举类为key的数据格式

Java 枚举类使用实践_第5张图片

前台接收到后台返回值

Java 枚举类使用实践_第6张图片

你可能感兴趣的:(Java,枚举类,java)