> 文章列表 > Java 泛型 使用案例

Java 泛型 使用案例

Java 泛型 使用案例

参考资料

  1. Java 基础 - 泛型机制详解
  2. 路人甲-Java泛型专题

目录

  • 一. 通用Mapper
    • 1.1 实体类
    • 1.2 Mapper基类
    • 1.3 自定义接口
    • 1.4 抽象基类Service
    • 1.5 调用
  • 二. session和bean的获取

一. 通用Mapper

1.1 实体类

@Accessors(chain = true): 允许链式调用

import lombok.Data;
import lombok.experimental.Accessors;import java.math.BigDecimal;@Data
@Accessors(chain = true)
public class TagEntity {private BigDecimal id;private String name;
}

1.2 Mapper基类

⏹ 该接口中定义了共通的增删改查方法

  • 因为要保证基类的通用性,使用泛型可以保证能使用任何类型的实体类
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import java.math.BigDecimal;public interface BaseMapper<T> {/* 返回表中的数据量* * @param tableName 表名* @return 总数量*/@Select(" select count(*) from ${tableName} ")BigDecimal getCount(@Param("tableName") String tableName);/* 插入数据* * @param entity entity* @return int 更新件数*/int insert(T entity);/* 更新数据* * @param entity entity* @return int 更新件数*/int updateByPrimaryKey(T entity);/* 删除数据* * @param entity entity* @return int 删除件数*/int deleteByPrimaryKey(T entity);
}

1.3 自定义接口

⏹ 自定义接口继承基类Mapper

  • TagGenericMapper接口继承了BaseMapper接口,也就有了其所有的方法
public interface TagGenericMapper extends BaseMapper<TagEntity> {// 定义独有的,非共通的方法
}

⏹ xml中的insert方法对应着基类Mapper中的insert接口

<?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="com.example.jmw.mapper.TagGenericMapper"><!-- 插入数据 --><insert id="insert" parameterType="java.util.Map">INSERT INTOt_tag(id, name)VALUES (#{id}, #{name})</insert><!-- 更新数据 --><!-- 删除数据 --><!-- 查询数据 -->
</mapper>

1.4 抽象基类Service

import org.springframework.beans.factory.annotation.Autowired;public abstract class BaseServiceAbstract<T> {// ❗❗❗共通的基类Mapper,此处一定不能使用java的@Resource来注入,否则失败@Autowiredprotected BaseMapper<T> baseMapper;// 插入int insert(T entity) {int count = 0;try {count = baseMapper.insert(entity);} catch (Exception ex) {// 模拟打印logSystem.out.println("程序异常,异常的原因是: " + ex.getMessage());}return count;}// 更新int update(T entity) {int count = 0;try {count = baseMapper.updateByPrimaryKey(entity);} catch (Exception ex) {// 模拟打印logSystem.out.println("程序异常,异常的原因是: " + ex.getMessage());}return count;}// 删除int delete(T entity) {int count = 0;try {count = baseMapper.deleteByPrimaryKey(entity);} catch (Exception ex) {// 模拟打印logSystem.out.println("程序异常,异常的原因是: " + ex.getMessage());}return count;}
}

1.5 调用

import org.springframework.stereotype.Service;
import org.springframework.boot.CommandLineRunner;
import javax.annotation.Resource;
import java.math.BigDecimal;@Service
public class TagService extends BaseServiceAbstract<TagEntity> implements CommandLineRunner {@Resourceprivate TagGenericMapper mapper;@Overridepublic void run(String... args) throws Exception {this.init();}public void init() {// 查询指定表中的数据数量BigDecimal count = mapper.getCount("t_tag");System.out.println(count);  // 5// 准备要插入数据TagEntity tagEntity = new TagEntity();tagEntity.setId(BigDecimal.ONE).setName("乌班图");// 通过抽象类中的方法向Tag表中插入数据int result = this.insert(tagEntity);System.out.println(result);  // 1}
}

⏹ 流程示意图

Java 泛型 使用案例

二. session和bean的获取

Java 泛型 使用案例

⏹ 定义一个基类Controller,使用泛型将IOC容器和session中获取到的数据转换为对应的实体类

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.util.ObjectUtils;import javax.servlet.http.HttpSession;public abstract class BaseControllerAbstract implements ApplicationContextAware {private static ApplicationContext applicationContext;// 注入session对象@Autowiredprivate HttpSession session;@Overridepublic void setApplicationContext(ApplicationContext applicationContext) throws BeansException {BaseControllerAbstract.applicationContext = applicationContext;}// 根据名称获取bean@SuppressWarnings("unchecked")protected <T> T getBean(String name) throws BeansException {// 👉直接将Bean转换为对应的类型return (T) applicationContext.getBean(name);}// 根据class获取beanprotected <T> T getBean(Class<T> clazz) throws BeansException {return applicationContext.getBean(clazz);}// 设置sessionprotected void setSession(Object data) {session.setAttribute(data.getClass().getSimpleName(), data);}// 获取session@SuppressWarnings("unchecked")protected <T> T getSession(Class< ? > clazz) {Object sessionINfo = session.getAttribute(clazz.getSimpleName());if (ObjectUtils.isEmpty(sessionINfo)) {return null;}// 👉从session中获取到的数据是一个Object类型的数据,使用泛型将其转换为指定的类型return (T) sessionINfo;}
}

⏹因为使用了泛型,所以获取IOC容器中的Bean和session中数据的时候,无需进行类型转换

import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;import java.math.BigDecimal;@Controller
@RequestMapping("/ztest")
public class ZTestController extends BaseControllerAbstract {@GetMapping("/init")public ModelAndView init() {// 向session中放入数据TagEntity tagEntity = new TagEntity();tagEntity.setId(BigDecimal.ONE).setName("tag");this.setSession(tagEntity);ModelAndView modelAndView = new ModelAndView();modelAndView.setViewName("ZTest");return modelAndView;}@PostMapping("/test")public ResponseEntity<Void> test() throws Exception {// 获取Bean对象TagService tag1 = this.getBean("tagService");System.out.println(tag1);TagService tag2 = this.getBean(TagService.class);System.out.println(tag2);// 从session中获取entity数据TagEntity sessionEntity = this.getSession(TagEntity.class);System.out.println(sessionEntity);return ResponseEntity.noContent().build();}
}

Java 泛型 使用案例