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 INTO
          t_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来注入,否则失败
    @Autowired
	protected BaseMapper<T> baseMapper;

    // 插入
    int insert(T entity) {

        int count = 0;
        try {
            count = baseMapper.insert(entity);
        } catch (Exception ex) {
            // 模拟打印log
            System.out.println("程序异常,异常的原因是: " + ex.getMessage());
        }

        return count;
	}

    // 更新
    int update(T entity) {

        int count = 0;
        try {
            count = baseMapper.updateByPrimaryKey(entity);
        } catch (Exception ex) {
            // 模拟打印log
            System.out.println("程序异常,异常的原因是: " + ex.getMessage());
        }

        return count;
	}

    // 删除
    int delete(T entity) {

        int count = 0;
        try {
            count = baseMapper.deleteByPrimaryKey(entity);
        } catch (Exception ex) {
            // 模拟打印log
            System.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 {

    @Resource
    private TagGenericMapper mapper;
	
	@Override
    public 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
    }
}

⏹ 流程示意图

在这里插入图片描述

二. session和bean的获取

在这里插入图片描述

⏹ 定义一个基类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对象
    @Autowired
    private HttpSession session;

    @Override
    public 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获取bean
    protected <T> T getBean(Class<T> clazz) throws BeansException {
        return applicationContext.getBean(clazz);
    }

    // 设置session
    protected 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();
    }
}

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/8085.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Python 进阶指南(编程轻松进阶):五、发现代码异味

原文&#xff1a;http://inventwithpython.com/beyond/chapter5.html 导致程序崩溃的代码显然是错误的&#xff0c;但是崩溃并不是发现程序问题的唯一手段。其他迹象可能表明程序存在更微妙的错误或不可读的代码。就像气体的味道可以指示气体泄漏或者烟雾的味道可以指示火灾一样…

[国产化]arm架构的服务器虚拟机软件---Qemu虚拟机

项目场景&#xff1a; 架构&#xff1a;arm 服务器型号&#xff1a;昆泰r522 操作系统&#xff1a;欧拉22.3arm 问题描述 对应需要有arm架构的虚拟机&#xff0c;vmware没有arm版本。寻找替代品。 之前有人介绍可以用zstack。但是需要改变操作系统。所以就放弃了。选择了&…

Github采用Http Push失败

Github采用Http Push失败 Github的密码凭证从2021年起开始就不能用了&#xff0c;现在采用http去push代码时候提示输入的密码要换成令牌&#xff08;token&#xff09;才可以。 如何在Github上生成自己的令牌呢&#xff1f; &#xff08;1&#xff09;简单来说就是将原来输入…

Spring AOP及事务说明

目录 1.事务管理 1.1 事务说明 1.2 Spring事务管理 1.3 事务进阶 (1)Transactional属性说明 (2)rollbackFor属性 (3)propagation属性 1.4 总结 2.AOP 2.1 AOP概述 2.2 AOP核心概念 2.3 AOP进阶 (1) 通知类型 (2)切点表达式 (3) 通知顺序 (4)连接点 1.事务管理 …

电容笔和触控笔有什么区别?第三方电容笔了解下

实际上&#xff0c;这两种不同类型笔&#xff0c;电容笔是适用于电容性屏幕&#xff0c;而触控笔是适用于电阻性屏幕。如果你想买一支带电容笔来搭配IPAD平板&#xff0c;那么苹果的Pencil就会超出你的预算。事实上&#xff0c;平替的电容笔也有很好的表现&#xff0c;并且其的…

【SpringMVC】3—RESTFul风格

⭐⭐⭐⭐⭐⭐ Github主页&#x1f449;https://github.com/A-BigTree 笔记链接&#x1f449;https://github.com/A-BigTree/Code_Learning ⭐⭐⭐⭐⭐⭐ 如果可以&#xff0c;麻烦各位看官顺手点个star~&#x1f60a; 如果文章对你有所帮助&#xff0c;可以点赞&#x1f44d;…

机器学习 01

目录 一、机器学习 二、机器学习工作流程 2.1 获取数据 2.2 数据集 2.2.1 数据类型构成 2.2.2 数据分割 2.3 数据基本处理 2.4 特征工程 2.4.1什么是特征工程 2.4.2 为什么需要特征工程(Feature Engineering) 2.4.3 特征工程内容 2.5 机器学习 2.6 模型评估 2.7 …

Java代理之jdk动态代理+应用场景实战

本文将先介绍jdk动态代理的基本用法&#xff0c;并对其原理和注意事项予以说明。之后将以两个最常见的应用场景为例&#xff0c;进行代码实操。这两个应用场景分别是拦截器和声明性接口&#xff0c;它们在许多开发框架中广泛使用。比如在spring和mybatis中均使用了拦截器模式&a…

【计算机架构】如何计算 CPU 时间

目录 0x00 响应时间和吞吐量&#xff08;Response Time and Throughput&#xff09; 0x01 相对性能&#xff08;Relative Performance&#xff09; 0x02 执行时间测量&#xff08;Measuring Execution Time&#xff09; 0x03 CPU 时钟&#xff08;Clocking&#xff09; 0x…

【数据结构与算法】并查集

文章目录一、并查集的概念二、并查集的实现2.1 find()的实现2.2 路径压缩算法2.3 join()的实现三、并查集的应用3.1 例题&#xff1a;合并集合3.2 例题&#xff1a;连通块中点的数量四、总结一、并查集的概念 并查集是一个树形结构&#xff0c;所谓的并查&#xff0c;就是当我…

关于神经网络的权重信息和特征图的可视化

目录 1. 介绍 2. 隐藏层特征图的可视化 2.1 AlexNet 网络 2.2 forward 2.3 隐藏层特征图可视化 2.4 测试代码 3. 训练参数的可视化 3.1 从网络里面可视化参数 3.1.1 测试代码 3.1.2 参数的字典信息 3.1.3 参数可视化 3.2 从保存的权重参数文件(.pth)里面可视化参数…

汉诺塔与二进制、满二叉树的千丝万缕

汉诺塔(Tower of Hanoi)源于印度传说中&#xff0c;大梵天创造世界时造了三根金钢石柱子&#xff0c;其中一根柱子自底向上叠着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定&#xff0c;在小圆盘上不能放大圆盘&#xff0c;在三…

数据挖掘(2.3)--数据预处理

目录 三、数据集成和转换 1.数据集成 2.数据冗余性 2.1 皮尔森相关系数 2.2卡方检验 3.数据转换 四、数据的规约和变换 1.数据归约 2数据离散化 三、数据集成和转换 1.数据集成 数据集成是将不同来源的数据整合并一致地存储起来的过程。 不同来源的数据可能有不同…

【ESP32+freeRTOS学习笔记之“ESP32环境下使用freeRTOS的特性分析(2-多核环境中的任务)”】

目录1、ESP32的双核对称多处理SMP概念2、涉及任务task的特殊性2.1 创建任务的特殊函数2.2 xTaskCreatePinnedToCore&#xff08;&#xff09;函数的解释3、任务的删除4、总结1、ESP32的双核对称多处理SMP概念 最初的FreeRTOS&#xff08;以下简称Vanilla FreeRTOS&#xff09;…

线性表——顺序表

文章目录一&#xff1a;线性表二&#xff1a;顺序表1&#xff1a;概念与结构1&#xff1a;静态顺序表2&#xff1a;动态顺序表2&#xff1a;动态顺序表的代码实现1&#xff1a;结构2&#xff1a;接口实现1&#xff1a;初始化2&#xff1a;释放内存3&#xff1a;检查容量4&#…

Linux下最小化安装CentOS-7.6(保姆级)

文章目录安装包开始安装一、 新建一个虚拟机二、配置安装CentOS7.6二、开始安装CentOS三、配置CentOS并下载基本信息安装包 链接&#xff1a;https://pan.baidu.com/s/1DodB-kDy1yiNQ7B5IxwYyg 提取码&#xff1a;p19i 开始安装 一、 新建一个虚拟机 1、 打开VMWare&#x…

刷题笔记【5】| 快速刷完67道剑指offer(Java版)

本文已收录于专栏&#x1f33b;《刷题笔记》文章目录前言&#x1f3a8; 1、合并两个有序链表题目描述思路一&#xff08;递归&#xff09;思路二&#xff08;双指针&#xff09;&#x1f3a8; 2、树的子结构题目描述思路一&#xff08;递归&#xff09;&#x1f3a8; 3、二叉树…

Redis分布式锁系列

1.压力测试出的内存泄漏及解决&#xff08;可跳过&#xff09; 使用jmeter对查询产品分类列表接口进行压力测试&#xff0c;出现了堆外内存溢出异常。 我们设置的虚拟机堆内存100m&#xff0c;并不是堆外内存100m 产生堆外内存溢出&#xff1a;OutOfDirectMemoryError 原因是…

某大厂面试题:说一说Java、Spring、Dubbo三者SPI机制的原理和区别

大家好&#xff0c;我是三友~~ 今天来跟大家聊一聊Java、Spring、Dubbo三者SPI机制的原理和区别。 其实我之前写过一篇类似的文章&#xff0c;但是这篇文章主要是剖析dubbo的SPI机制的源码&#xff0c;中间只是简单地介绍了一下Java、Spring的SPI机制&#xff0c;并没有进行深…

SQL——数据查询DQL

基本语句、时间查询&#xff08;当天、本周&#xff0c;本月&#xff0c;上一个月&#xff0c;近半年的数据&#xff09;。 目录 1 查询语句基本结构 2 where 子句 3 条件关系运算符 4 条件逻辑运算符 5 like 子句 6 计算列 7 as 字段取别名 8 distinct 清除重复行 9 …