当前位置: 首页 > news >正文

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}
}

⏹ 流程示意图

在这里插入图片描述

二. 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对象@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 泛型 使用案例

参考资料 Java 基础 - 泛型机制详解路人甲-Java泛型专题 目录一. 通用Mapper1.1 实体类1.2 Mapper基类1.3 自定义接口1.4 抽象基类Service1.5 调用二. session和bean的获取一. 通用Mapper 1.1 实体类 ⏹ Accessors(chain true): 允许链式调用 import lombok.Data; import …...

进程与线程

文章目录什么是线程线程与进程的关系线程与进程的区别什么是线程 上一篇文章中我们介绍了什么进程&#xff0c;我们把进程比作一个工厂&#xff0c;那么线程就是工厂中的流水线。引入进程的目的就是为了实现多个任务并发执行&#xff0c;但是如果频繁的创建销毁进程&#xff0…...

骑友,怎么挑选适合自己的赛事

骑友&#xff0c;怎么挑选适合自己的赛事一、从场地、路况、天气&#xff0c;各个方面了解赛事的要求。二、看完赛事&#xff0c;要知道自己适合参加什么样的比赛。三、通过比赛成绩&#xff0c;对比自己的实力。四、综合考虑自己的经济能力&#xff0c;根据自己的经济能力选择…...

【Java 数据结构与算法】-遍历Map和Set的方式

作者&#xff1a;学Java的冬瓜 博客主页&#xff1a;☀冬瓜的主页&#x1f319; 专栏&#xff1a;【Java 数据结构与算法】 文章目录一、遍历Map法一 先获取Map集合的全部key的set集合&#xff0c;遍历map的key的Set集合法二 把map的key和value打包成Set的key后的这个Set集合法…...

组件、套件、 中间件、插件

组件、套件、 中间件、插件 组件 位于框架最底层&#xff0c;是由重复的代码提取出来合并而成。组件的本质&#xff0c;是一件产品&#xff0c;独立性很强&#xff0c;组件的核心&#xff0c;是复用&#xff0c;与其它功能又有强依赖关系。 模块 在中台产品和非中台产品中&…...

自动化工具 pytest 内核测试平台落地初体验

测试平台&#xff0c;有人说它鸡肋&#xff0c;有人说它有用&#xff0c;有人说它轮子&#xff0c;众说纷纭&#xff0c;不如从自身出发&#xff0c;考虑是否要做测试平台&#xff1a; 第 1 阶段&#xff0c;用 Pythonrequests 写接口自动化。 第 2 阶段&#xff0c;选择 unit…...

Python 自动化指南(繁琐工作自动化)第二版:四、列表

原文&#xff1a;https://automatetheboringstuff.com/2e/chapter4/ 在开始认真编写程序之前&#xff0c;您需要理解的另一个主题是列表数据类型及其表亲元组。列表和元组可以包含多个值&#xff0c;这使得编写处理大量数据的程序更加容易。由于列表本身可以包含其他列表&#…...

大数据领域的发展及其对现实世界的价值

大数据已经成为全球各行业领域不可或缺的一部分&#xff0c;并且其应用不断涌现。尽管很多人最初对“大数据”这一术语表示怀疑和不信任&#xff0c;但大数据技术已经确立了稳定的发展方向。根据调研机构的预测&#xff0c;到2027年&#xff0c;全球大数据市场规模将达到1090亿…...

几种常见的架构模式

本文已经收录到Github仓库&#xff0c;该仓库包含计算机基础、Java基础、多线程、JVM、数据库、Redis、Spring、Mybatis、SpringMVC、SpringBoot、分布式、微服务、设计模式、架构、校招社招分享等核心知识点&#xff0c;欢迎star~ Github地址 如果访问不了Github&#xff0c…...

flutter安装各种问题汇总

C:\Users\Administrator>flutter doctor -v Flutter assets will be downloaded from https://storage.flutter-io.cn. Make sure you trust this source! [√] Flutter (Channel stable, 3.7.0, on Microsoft Windows [版本 10.0.19044.1826], locale zh-CN) • Flutte…...

网络传输层

目录传输层再谈端口号端口号范围划分认识知名端口号netstatpidofUDP协议UDP协议端格式UDP的特点面向数据报UDP的缓冲区UDP使用注意事项使用udp协议 的应用层协议其它TCP协议TCP协议段格式如何理解链接如何理解三次握手如何理解四次挥手概念TIME_WAIT/CLOSE_WAITTCP策略确认应答…...

linux内核启动分析(二)

文章目录1. set_task_stack_end_magic2.smp_setup_processor_id3. debug_objects_early_init4. cgroup_init_early4.1 init_cgroup_root4.1.1 init_cgroup_housekeeping4.2 cgroup_init_subsys5. local_irq_disable5.1 raw_irqs_disabled5.2 raw_local_irq_disable5.3 trace_ha…...

『EasyNotice』.NET开源消息通知组件——快速实现邮件/钉钉告警通知

&#x1f4e3;读完这篇文章里你能收获到 傻瓜式扩展方法直接使用如何通过EasyNotice快速实现钉钉/邮件的通知发送感谢点赞收藏&#xff0c;避免下次找不到~ 文章目录一、EasyNotice1. 功能介绍2. 源码地址二、项目接入1. 发送邮件通知Step 1 : 安装包&#xff0c;通过Nuget安装…...

JVM垃圾回收算法

垃圾标记阶段 对象存活判断&#xff1a;在堆里存放着几乎所有的Java对象实例&#xff0c;在GC执行垃圾回收之前&#xff0c;首先需要区分出内存中哪些是存活对象&#xff0c;哪些是已经死亡的对象。只有被标记为己经死亡的对象&#xff0c;GC才会在执行垃圾回收时&#xff0c;…...

怎么看待ChatGPT封号这件事呢?

最近的ChatGPT大量封号&#xff0c;刷爆了全网&#xff0c;我的两个个人账号被封禁了&#xff0c;不知道大家最近有没有遇到相关的报错信息&#xff0c;要么就是检查你当前的浏览器配置&#xff0c;最后来一个access denied&#xff0c;要么直接就给你来一个当前的国家不支持。…...

八、交换技术原理

&#xff08;一&#xff09;交换机 1、交换机介绍 一种用于电&#xff08;光&#xff09;信号转发的网络设备&#xff0c;可以为接入交换机的任意两个网络节点提供独享的电信号通路。 工作于第二层的叫交换机&#xff0c;工作于第三层的叫第三层交换机&#xff0c;最常见的是…...

什么是DHCP?DHCP有什么用?(中科三方)

在IP网络中&#xff0c;每一个连接的设备都需要分配一个唯一的IP地址&#xff0c;才能实现和Internet上其他设备的互联。在一些终端规模较大的网络中&#xff0c;需要为每一个主机手工配置IP地址&#xff0c;以避免IP地址的重复&#xff0c;如果主机发生变更&#xff0c;还要去…...

算法设计-二分

一、有序和单调 ​ 二分本质上是一种更加智能的搜索状态空间的方式&#xff0c;他需要状态空间的状态呈现一种“有序的一维数组”的形式&#xff0c;然后再进行搜索。所以一开始的排序是无法避免的。 ​ 因为二分的写法问题&#xff0c;所以应当怎样排序也是有一定讲究的&…...

隧道技术基础

隧道技术基础基本概念端口转发应用层代理基本概念 攻击者通过边界主机进入内网&#xff0c;往往会利用它当跳板进行横向渗透&#xff0c;但现在的内部网络大多部署了很多安全设备&#xff0c;网络结构错综复杂&#xff0c;对于某些系统的访问会受到各种阻挠&#xff0c;这就需…...

卡尔曼滤波浅析

文章目录前言任务状态预测外部影响因素外部不确定性状态更新利用测量进一步修正状态合并两个高斯分布公式汇总图形化解释总结&#xff08;readme&#xff09;references前言 Kalman Filter算法&#xff0c;是一种递推预测滤波算法&#xff0c;算法中涉及到滤波&#xff0c;也涉…...

利用ngx_stream_return_module构建简易 TCP/UDP 响应网关

一、模块概述 ngx_stream_return_module 提供了一个极简的指令&#xff1a; return <value>;在收到客户端连接后&#xff0c;立即将 <value> 写回并关闭连接。<value> 支持内嵌文本和内置变量&#xff08;如 $time_iso8601、$remote_addr 等&#xff09;&a…...

Opencv中的addweighted函数

一.addweighted函数作用 addweighted&#xff08;&#xff09;是OpenCV库中用于图像处理的函数&#xff0c;主要功能是将两个输入图像&#xff08;尺寸和类型相同&#xff09;按照指定的权重进行加权叠加&#xff08;图像融合&#xff09;&#xff0c;并添加一个标量值&#x…...

MODBUS TCP转CANopen 技术赋能高效协同作业

在现代工业自动化领域&#xff0c;MODBUS TCP和CANopen两种通讯协议因其稳定性和高效性被广泛应用于各种设备和系统中。而随着科技的不断进步&#xff0c;这两种通讯协议也正在被逐步融合&#xff0c;形成了一种新型的通讯方式——开疆智能MODBUS TCP转CANopen网关KJ-TCPC-CANP…...

DIY|Mac 搭建 ESP-IDF 开发环境及编译小智 AI

前一阵子在百度 AI 开发者大会上&#xff0c;看到基于小智 AI DIY 玩具的演示&#xff0c;感觉有点意思&#xff0c;想着自己也来试试。 如果只是想烧录现成的固件&#xff0c;乐鑫官方除了提供了 Windows 版本的 Flash 下载工具 之外&#xff0c;还提供了基于网页版的 ESP LA…...

【单片机期末】单片机系统设计

主要内容&#xff1a;系统状态机&#xff0c;系统时基&#xff0c;系统需求分析&#xff0c;系统构建&#xff0c;系统状态流图 一、题目要求 二、绘制系统状态流图 题目&#xff1a;根据上述描述绘制系统状态流图&#xff0c;注明状态转移条件及方向。 三、利用定时器产生时…...

图表类系列各种样式PPT模版分享

图标图表系列PPT模版&#xff0c;柱状图PPT模版&#xff0c;线状图PPT模版&#xff0c;折线图PPT模版&#xff0c;饼状图PPT模版&#xff0c;雷达图PPT模版&#xff0c;树状图PPT模版 图表类系列各种样式PPT模版分享&#xff1a;图表系列PPT模板https://pan.quark.cn/s/20d40aa…...

技术栈RabbitMq的介绍和使用

目录 1. 什么是消息队列&#xff1f;2. 消息队列的优点3. RabbitMQ 消息队列概述4. RabbitMQ 安装5. Exchange 四种类型5.1 direct 精准匹配5.2 fanout 广播5.3 topic 正则匹配 6. RabbitMQ 队列模式6.1 简单队列模式6.2 工作队列模式6.3 发布/订阅模式6.4 路由模式6.5 主题模式…...

JS设计模式(4):观察者模式

JS设计模式(4):观察者模式 一、引入 在开发中&#xff0c;我们经常会遇到这样的场景&#xff1a;一个对象的状态变化需要自动通知其他对象&#xff0c;比如&#xff1a; 电商平台中&#xff0c;商品库存变化时需要通知所有订阅该商品的用户&#xff1b;新闻网站中&#xff0…...

Linux 内存管理实战精讲:核心原理与面试常考点全解析

Linux 内存管理实战精讲&#xff1a;核心原理与面试常考点全解析 Linux 内核内存管理是系统设计中最复杂但也最核心的模块之一。它不仅支撑着虚拟内存机制、物理内存分配、进程隔离与资源复用&#xff0c;还直接决定系统运行的性能与稳定性。无论你是嵌入式开发者、内核调试工…...

莫兰迪高级灰总结计划简约商务通用PPT模版

莫兰迪高级灰总结计划简约商务通用PPT模版&#xff0c;莫兰迪调色板清新简约工作汇报PPT模版&#xff0c;莫兰迪时尚风极简设计PPT模版&#xff0c;大学生毕业论文答辩PPT模版&#xff0c;莫兰迪配色总结计划简约商务通用PPT模版&#xff0c;莫兰迪商务汇报PPT模版&#xff0c;…...