JavaEE企业开发新技术5

news2024/12/26 23:40:29

目录

2.18 综合应用-1

2.19 综合应用-2

2.20 综合应用-3

2.21 综合应用-4

2.22 综合应用-5

Synchronized :


2.18 综合应用-1

反射的高级应用

DAO开发中,实体类对应DAO的实现类中有很多方法的代码具有高度相似性,为了提供代码的复用性,降低冗余度,可以通过反射的方式可以定义一个公共的DAO,只要提供实体类名,就可以得到对应数据库表中的所有记录。

用到的知识点:

(1)JDBC的基本操作

(2)单例设计模式

(3)数据库结果集对应的元数据(ResultSetMeteDate)

(4)反射

命名的规范化要求:

(1)实体类类名每个首字母大写,数据库表字段名称要与实体类属性名称一致,数据库表中字段命名的时候每个单词首字母要大写。

(2)数据库表命名以“t_”开头,后面跟对应的实体类名称,首字母小写。

源码:

package cn.edu.xync.myweb.reflect;

import java.lang.reflect.Method;
import java.security.Timestamp;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;

class JDBCUtil{
	private static JDBCUtil util=null;//定义私有的静态成员
	private JDBCUtil() {//加载驱动
		try {
			Class.forName("com.mysql.cj.jdbc.Driver");
		} catch (ClassNotFoundException e) {
			
			e.printStackTrace();
		}
	}
	
	public static JDBCUtil getInstance() {//判断util这个静态成员属性有没有被实例化
		synchronized(JDBCUtil.class) {
			if(util==null) {
				util=new JDBCUtil();//实例化
			}
			return util;
		}	
	}
	
	public Connection getConnection() throws SQLException {//返回链接对象
		return DriverManager.getConnection("jdbc:mysql://localhost:3306/mysqldb?characterEncoding=UTF-8","root","1234567890");
	}
	
	public void close(ResultSet rs, Statement stmt, Connection con) {

		try {
			if (rs != null) // 关闭并释放资源
				rs.close();
			if (stmt != null)
				stmt.close();
			if (con != null)
				con.close();
		} catch (SQLException e) {

			e.printStackTrace();
		}

	}
}

JDBCUtil使用了封装类并使用了单例设计模式

2.19 综合应用-2

class CommonDAO {// 定义公共的DAO
	/*
	 * 根据实体类名将其对应的数据库表中所有的记录封装成实体类集合返回 说明:数据库表字段名称要与实体类属性名称一致,数据库表中字段命名的时候每个单词首字母要大写
	 */
	public List getBeans(String beanName) throws Exception {
		// 得到对应的数据库表名称
		String tableName = this.getTableName(beanName);
		System.out.println(tableName);
		String sql = "select * from " + tableName;// select * from t_account

		List lists = new ArrayList();// 把表里的每一行转换成实体类存放在集合里
		JDBCUtil util = JDBCUtil.getInstance();

		try {
			Connection con = util.getConnection();
			Statement stmt = con.createStatement();
			ResultSet rs = stmt.executeQuery(sql);

			ResultSetMetaData rsmd = rs.getMetaData();// 结果集元数据:通过它能够知道结果集对应的表有几列,
			// 这些列的名称,数据类型等信息都在结果集元数据当中

			// 得到当前表共有几个字段
			int columnCount = rsmd.getColumnCount();

			while (rs.next()) {// 对结果集遍历,每执行一次就要通过反射的方法把对应的实体类的clazz对象创建出来
				// 实体类必须放到cn.xysfxy.sprintboot.entity包中
				Class clazz = Class.forName("cn.edu.xync.myweb.entity." + beanName);// 实例化对象
				Object obj = clazz.newInstance();

//对列进行循环				
for (int i = 1; i <= columnCount; i++) {
					System.out.println(rsmd.getColumnName(i));// 拿到列名
					System.out.println(rsmd.getColumnTypeName(i));// 拿到列对应的数据类型的名称

					// 将数据表字段第一个字母转换成大写,为下边拿到setXXX方法使用
					String methodName = this.firstCharToUppercase(rsmd.getColumnName(i));
					// 根据反射调用setXXX方法给实体类对象属性赋值
					Method method = clazz.getDeclaredMethod("set" + methodName,
							this.getAttributeClassType(rsmd.getColumnTypeName(i)));
//得到setId方法传入的java类型
					// setId




					method.invoke(obj, rs.getObject(i));//传值
				}
				lists.add(obj);// 添加到集合里
			}

		} catch (SQLException e) {
			e.printStackTrace();
		}
		return lists;
	}

	// 根据数据库表中某个列的数据类型返回对应的Java数据类型的Class对象
	private Class getAttributeClassType(String columnType) {
		Class clazz = null;
		if ("VARCHAR".equalsIgnoreCase(columnType))
			clazz = String.class;
		if ("INT".equalsIgnoreCase(columnType))
			clazz = Integer.class;
		if ("Float".equalsIgnoreCase(columnType))
			clazz = Float.class;
		if ("DATETIME".equalsIgnoreCase(columnType))
			clazz = Timestamp.class;
		return clazz;
	}

	// 将数据表列名第一个字母转换成大写
	private String firstCharToUppercase(String columnName) {
		String uppercaseString = columnName.toUpperCase();
		char firstChar = uppercaseString.charAt(0);
		String firstCharString = String.valueOf(firstChar);
		return firstCharString.concat(columnName.substring(1, columnName.length()));
	}

	/*
	 * 根据实体类名称得到对应的数据表名称 命名必须遵守的规范 例如Account,对应的表名称为t_account
	 */

	private String getTableName(String beanName) {
		char oldFirstChar = beanName.charAt(0);
		// 实体类名首字母先转换成字符串形式,再转换成小写
		String newFirstChar = String.valueOf(oldFirstChar).toLowerCase();
		// 拼接字符串
		String tableName = "t_" + beanName.replaceFirst(String.valueOf(oldFirstChar), newFirstChar);//替换字符
		return tableName;// 把Account-->t_account
	}
}

2.20 综合应用-3

2.21 综合应用-4

public class GenericTest {
	public static void main(String[] args) {
		CommonDAO dao = new CommonDAO();
		List lists = null;
		try {
			lists = dao.getBeans("User");
			// lists=dao.getBeans("Goods");
			
			for(int i=0;i<lists.size();i++) {
				System.out.println(lists.get(i));
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

运行结果:

总结:这是通过反射和JDBC结果集元数据相结合的一个例子,目的:减少代码的冗余,提高代码的复用性

2.22 综合应用-5

一般我们不会去传递类的名称,我们都是传递类的Class对象

applicationContext.getBean(XXX.class)

private String getTableName(Class beanType) {
		//String beanNameWithPackage=beanType.getName();//得到的类名包含了package信息
		String beanName=beanType.getSimpleName();//得到Account
		System.out.println(beanName);
//		//cn.xxx.xxx.Account
//		System.out.println(beanNameWithPackage);
//		String subName[] =beanNameWithPackage.split("\\.");//按.转义拆分成字符串数组
//		String beanName=subName[subName.length-1];//拿到最后一个字符串
		
		char oldFirstChar = beanName(0);
		// 实体类名首字母先转换成字符串形式.charAt,再转换成小写
		String newFirstChar = String.valueOf(oldFirstChar).toLowerCase();
		// 拼接字符串
		String tableName = "t_" + beanName.replaceFirst(String.valueOf(oldFirstChar), newFirstChar);
		return tableName;// 把Account-->t_account
	}

//因为我们传递进来的就是Class对象,所以直接调用newInstance()方法就行

运行结果:

Synchronized :

当多个并发线程(thread1和thread2)访问同一个对象(ThreadSyn)中的synchronized代码块时,就相当于对这个代码块加了锁,在同一时刻只能有一个线程得到执行,其他线程受阻塞,必须等待当前线程执行完这个代码块以后才能执行该代码块。

当多个线程访问 不同对象 的同步代码块,线程访问各自同步代码块,线程不会阻塞,互不干扰。

总结

1、无论synchronized关键字加在方法上还是对象上,如果它作用的对象是非静态的,则它取得的锁是对象;如果synchronized作用的对象是一个静态方法或一个类,则它取得的锁是对类,该类所有的对象同一把锁。

2、每个对象只有一个锁(lock)与之相关联,谁拿到这个锁谁就可以运行它所控制的那段代码。

3、实现同步是要很大的系统开销作为代价的,甚至可能造成死锁,所以尽量避免无谓的同步控制。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Zookeeper与Kafka消息队列

目录 一、Zookeeper 1、zookeeper简介 2、zookeeper的特点 3、zookeeper的工作模式跟工作机制 3.1 工作模式&#xff1a; 3.2工作机制&#xff1a;​编辑 4、zookeeper应用场景及选举机制 4.1 应用场景&#xff1a; 4.2 选举机制&#xff1a; 4.2.1第一次启动选举机制…

<计算机网络自顶向下> CDN

视频服务挑战 规模性异构性&#xff1a;不同用户有不同的能力&#xff08;比如有线接入和移动用户&#xff1b;贷款丰富和受限用户&#xff09;解决方法是&#xff1a;分布式的应用层面的基础设施CDN 多媒体&#xff1a;视频 视频是固定速度显示的一系列图像的序列&#xff…

MySQL 使用C语言

一般使用MySQL很少用命令行&#xff0c;一般都是通过程序内部使用&#xff0c;MySQL也为不同的语言定制了不同的头文件和库函数&#xff0c;可以在自己的程序中通过包含头文件和编译时候链接库函数来使用MySQL。 现在一般安装MySQL的时候就会自动给你安装库函数和头文件。 可…

python爬虫------- Selenium下篇(二十三天)

&#x1f388;&#x1f388;作者主页&#xff1a; 喔的嘛呀&#x1f388;&#x1f388; &#x1f388;&#x1f388;所属专栏&#xff1a;python爬虫学习&#x1f388;&#x1f388; ✨✨谢谢大家捧场&#xff0c;祝屏幕前的小伙伴们每天都有好运相伴左右&#xff0c;一定要天天…

11.哀家要长脑子了!

目录 1.453. 最小操作次数使数组元素相等 - 力扣&#xff08;LeetCode&#xff09; 2.665. 非递减数列 - 力扣&#xff08;LeetCode&#xff09; 3. 283. 移动零 - 力扣&#xff08;LeetCode&#xff09; 4. 3114. 替换字符可以得到的最晚时间 - 力扣&#xff08;LeetCode…

构建第一个ArkTS用的资源分类与访问

应用开发过程中&#xff0c;经常需要用到颜色、字体、间距、图片等资源&#xff0c;在不同的设备或配置中&#xff0c;这些资源的值可能不同。 应用资源&#xff1a;借助资源文件能力&#xff0c;开发者在应用中自定义资源&#xff0c;自行管理这些资源在不同的设备或配置中的表…

Redis实现延迟任务的几种方案

&#x1f3f7;️个人主页&#xff1a;牵着猫散步的鼠鼠 &#x1f3f7;️系列专栏&#xff1a;Java全栈-专栏 &#x1f3f7;️个人学习笔记&#xff0c;若有缺误&#xff0c;欢迎评论区指正 目录 1.前言 2.Redis如何实现延迟任务&#xff1f; 3.代码实现 3.1. 过期键通知事…

【Java】maven的生命周期和概念图

maven的生命周期&#xff1a; 在maven中存在三套"生命周期"&#xff0c;每一套生命周期,相互独立,互不影响的,但是中同一套生命周期里,执行后面的命令会自动先执行前面的命令 CleanLifeCycle&#xff1a;清理的生命周期 clean defaultLifeCycle&#xff1a;默认的…

智能物联网远传冷水表管理系统

智能物联网远传冷水表管理系统是一种基于物联网技术的先进系统&#xff0c;旨在实现对冷水表的远程监测、数据传输和智能化管理。本文将从系统特点、构成以及带来的效益三个方面展开介绍。 系统特点 1.远程监测&#xff1a;系统可以实现对冷水表数据的远程监测&#xff0c;无…

趣话最大割问题:花果山之群猴博弈

内容来源&#xff1a;量子前哨&#xff08;ID&#xff1a;Qforepost&#xff09; 编辑丨浪味仙 排版丨 沛贤 深度好文&#xff1a;3000字丨15分钟阅读 趋利避害&#xff0c;是所有生物遵循的自然法则&#xff0c;人类也不例外。 举个例子&#xff0c;假如你是某生鲜平台的配…

【Entity Framework】你要知道EF中功能序列与值转换

【Entity Framework】你要知道EF中功能序列与值转换 文章目录 【Entity Framework】你要知道EF中功能序列与值转换一、序列1.1 基本用法1.2 配置序列设置 二、值转换2.1 配置值转换器2.2 批量配置值转换器2.3 预定义的转换2.4 ValueConverter类2.5 内置转换器 三、应用3.1 简单…

Vue3基础笔记(3)高级绑定

一.Class绑定 数据绑定的一个常见需求场景师操纵元素的CSS class列表&#xff0c;因为class是attribute&#xff0c;我们可以和其他attribute一样使用v-bind将他们和动态的字符串绑定&#xff0c;但是在处理较为复杂的绑定时&#xff0c;拼接字符串容易出现错误。因此Vue专门为…

Python开源工具库使用之词云Wordcloud

文章目录 前言一、基本使用1.1 文本生成词云1.2 配置项 二、进阶用法2.1 自定义形状2.2 自定义着色2.3 自定义词频2.4 中文 三、实际案例3.1 工作报告词云3.2 周杰伦歌词词云 四、总结4.1 优点和局限性4.2 展望未来发展 参考 前言 当我们需要将大量文本数据可视化展示时&#…

为了执行SQL语句,MySQL的架构是怎样设计的

1. 把MySQL当个黑盒子一样执行SQL语句 上一讲我们已经说到&#xff0c;我们的系统采用数据库连接池的方式去并发访问数据库&#xff0c;然后数据库自己其实也会维护一个连 接池&#xff0c;其中管理了各种系统跟这台数据库服务器建立的所有连接 我们先看下图回顾一下 当我们的…

【PostmanJMeter】使用Postman和JMeter进行signature签名

一、前言 ​ 有些接口的请求会带上sign&#xff08;签名&#xff09;进行请求&#xff0c;各接口对sign的签名内容、方式可能不一样&#xff0c;但一般都是从接口的入参中选择部分内容组成一个字符串&#xff0c;然后再进行签名操作, 将结果赋值给sign; 完整规范的接口文档都会…

使用深度学习集成模型进行乳腺癌组织病理学图像分类

基于预训练的VGG16和VGG19架构训练了四种不同的模型&#xff08;即完全训练的 VGG16、微调的 VGG16、完全训练的 VGG19 和微调的 VGG19 模型&#xff09;。最初&#xff0c;我们对所有单独的模型进行了5倍交叉验证操作。然后&#xff0c;我们采用集成策略&#xff0c;取预测概率…

(一)C++自制植物大战僵尸集成开发环境安装

植物大战僵尸游戏开发教程专栏地址http://t.csdnimg.cn/uzrnw 1、下载Visual Studio集成开发环境 首先在微软官网下载Visual Studio 2022 Community版本。Community版本是免费的&#xff0c;并且满足个人开发的各种需求。Visual Studio 2022 下载链接&#xff1a;微软官网。选…

maven引入外部jar包

将jar包放入文件夹lib包中 pom文件 <dependency><groupId>com.jyx</groupId><artifactId>Spring-xxl</artifactId><version>1.0-SNAPSHOT</version><scope>system</scope><systemPath>${project.basedir}/lib/Spr…

[lesson33]C++中的字符串类

C中的字符串类 历史遗留问题 C语言不支持真正意义上的字符串C语言用字符数组和一组函数实现字符串操作C语言不支持自定义类型&#xff0c;因此无法获得字符串类型 解决方案 从C到C的进化过程引入自定义类型在C中可以通过类完成字符串类型的定义 标准库中的字符串类 C语言直…

蓝桥杯——玩具蛇

题目 小蓝有—条玩具蛇&#xff0c;一共有16节&#xff0c;上面标着数字1至16。每—节都是一个正方形的形状。相邻的两节可以成直线或者成90度角。 小蓝还有一个44的方格盒子&#xff0c;用于存放玩具蛇&#xff0c;盒子的方格上依次标着字母A到Р共16个字母。 小蓝可以折叠自…