JDBC的使用(一)

一、JDBC 概述

1.1 持久化概述

持久化(persistence): 把内存中的数据保存到可掉电式存储设备 (硬盘、U盘等) 中以供之后使用。

大多数企业级应用,数据持久化是将数据保存到各种关系数据库, 而在 Java中,数据库存取技术只能通过 JDBC 来访问数据库。 JDBC 是 Java 语言访问数据库的基石,其他技术都是对 JDBC 的封装.

1.2 JDBC 概述

JDBC 介绍

 JDBC(Java DataBase Connectivity Java 数据库连接)是一种用于执行 SQL 语句的 Java API,可以为多种关系型数据库提供统一访问,它由一组用 Java 语言编写的类和接口组成。

JDBC 本质

 其实就是Java 官方提供的一套规范(接口),帮助开发人员快速实现不同关系型数据库的连接。

总结 : JDBC 本身是 Java 连接数据库的标准,由 Java 编写的一组接口组成,接口的实现由各个数据库厂商来完成.

二、JDBC 快速入门

2.1 环境准备

  1. 拷贝 MySQL 的 JDBC 驱动,到 Java 项目中: mysql-connector-java-5.1.26-bin.jar

注意: 是 jar 包,不是 zip 包.

        2.选择 jar,把 jar 引用到 classpath 路径. idea 项目中创建一个目录 lib

右键 lib 目录,点 Add as Library...

2.2 JDBC 开发口诀

  1. 加载注册驱动.
  2. 获取连接对象.
  3. 创建/获取语句对象.
  4. 执行SQL语句.
  5. 释放资源.

三、功能类详解

3.1 DriverManager 类

DriverManager : 驱动管理对象,主要用于加载注册关系型数据库的 Driver 类以及获取和关系型数据库的连接对象

  1. 加载注册驱动

注册给定的驱动对象:static void registerDriver(Driver driver);

写法:Class.forName("com.mysql.jdbc.Driver");在 com.mysql.jdbc.Driver 类中存在静态代码快

1. 把 com.mysql.jdbc.Driver 这一份字节码加载进 JVM.

字节码被加载进JVM,就会执行其静态代码块.而其底层的静态代码块在完成注册驱动工作,将驱动注册到DriverManger 中.

注意: Java6 开始,JDBC4.0 有一个新特性-无需加载注册驱动.

在 jar 包中存在一个java.sql.Driver 配置文件。此文件已经包含 com.mysql.jdbc.Driver 驱动名称。 程序会自动从 META-INF/services/java.sql.Driver 去读取当前的驱动类的全限定名,所

以目前写不写加载注册驱动都没问题,但是 web 项目必须写上加载注册驱动代码,否则无法连接数据库。

  1. 获取连接对象

获取连接对象:static Connection getConnection(String url,String username,String password);

 参数

url :指定连接某一个数据库的路径,语法:

url=jdbc:mysql://localhost:3306/jdbcdemo

MySQL url: 如果连接的是本机的 MySQL,并且端口是默认 3306 ,则可以简写:

url=jdbc:mysql:///jdbcdemo

  password :连接数据库的密码

3.2 Connection 类

Connection :关系型数据库连接对象,相当于 Java 程序和数据库的通信桥梁

  1. 获取执行语句对象

获取静态语句执行对象: Statement createStatement();

获取预编译语句执行对象: PreparedStatement prepareStatement(String sql);

  1. 释放资源

关闭连接对象: void close();

  1. 事务

3.3 Statement 类

Statement:静态SQL语句执行对象,用于执行字符串的 SQL 语句

1. 执行 DML / DDL 语句 : int executeUpdate(String sql);

 返回值 : DML 受影响的行数,DDL 则返回 0

参数:insert、update、delete、create语句

2. 执行 DQL 语句:ResuleSet executeQuery(String sql);

 返回值:执行查询之后的结果数据

参数:select 语句

  1. 释放资源

关闭 Statement 对象 :void close();

四、DAO 思想

4.1 DAO 引入

在没有 DAO 的时候,我们的代码存在大量的重复。

4.2 DAO 介绍和方法设计

DAO(Data Access Object) 数据访问对象是一个面向对象的数据库接口. 顾名思义就是与数据库打交道,将所有对数据源的访问操作抽象封装在一个公共 API 中。

DAO 中的主要操作: 增删改查(CRUD). 引入 DAO 之后,此时设计如下图。

DAO 作为组件,主要的是方法的设计,而方法设计需要注意什么呢?

  1. 在保存功能中,调用者需要传递多个参数进来,然后把这些数据保存到数据库中
  2. 在查询功能中,结果集的每行数据有多个列的值,然后把这些数据返回给调用者

意识: 在开发过程中,如果遇到需要传递的数据有多个的时候,通常需要使用 JavaBean 对其进行封装最终方法设计如下:

  • //调用者将需要保存的数据封装到Student对象中,然后传递进来

2   void save(Student stu)

3   //在查询之后,将每行数据封装到Student对象中,再返回给调用者

4   Student selectOne(long id);

4.3 DAO层开发规范

DAO 其实是一个组件(可以重复使用),包括:

分包规范: 域名倒写.项目模块名.组件; cn.wolfcode.pss.util; // 存放工具类 StringUtil cn.wolfcode.pss.domain; //装pss模块的domain类,模型对象.(Student) cn.wolfcode.pss.dao; //装pss模块的dao接口. cn.wolfcode.pss.dao.impl; //装pss模块的dao接口的实现类. cn.wolfcode.pss.test; // 暂时存储DAO的测试类,以后的测试类不应该放这里.

命名规范:

以下的 Xxx 表示一个模型对象,比如 Employee,Department,Student

DAO 接口 : 表示对某个模型的 CRUD 操作做规范,以 I 开头,interface

例: IEmployeeDAO/IStudentDAO

  DAO 实现类: 表示对某个 DAO 接口的实现

标准:XxxDAOImpl

例:EmployeeDAOImpl/StudentDAOImpl

  DAO 测试类: 测试 DAO 组件中的所有方法

标准:XxxDAOTest: XxxDAO 组件的测试类,

例:EmployeeDAOTest,StudentDAOTest

开发建议: 面向接口编程,声明 DAO 对象 传统的做法 : EmployeeDAOImpl dao = new

EmployeeDAOImpl(); 面向接口编程 : IEmployeeDAO dao = new EmployeeDAOImpl();

把实现类赋给接口类型,体现多态的特性:可以屏蔽不同子类之间实现的差异.

4.4 根据 DAO 规范搭建项目

4.4.1 步骤

  1. 创建项目
  2. 导入数据库驱动包
  3. 创建表和模型包以及模型对象 (domain/Student)
  4. 创建 DAO 包和 DAO 接口,设计 DAO 接口方法 (dao/IStudentDAO)
  5. 创建 DAO 实现包,实现 DAO 接口(dao.impl/StudentDAOImpl)
  6. 创建测试目录,生成测试类和方法(test/StudentDAOTest)
  7. 书写实现,实现一个方法测试一个方法并且测试通过

4.4.2 测试先行

public class StudentDAOTest {

private IStudentDAO studetDAO = new StudentDAOImpl();

@Test

public void insert() {

Student stu = new Student(null,"小明","ming@",18);

studetDAO.insert(stu);

}

@Test

public void delete() {

studetDAO.delete(2L);

}

@Test

public void update() {

Student stu = new Student(1L,"小明","ming@",19);

studetDAO.update(stu);

}

@Test

public void selectOne() {

Student stu = studetDAO.selectOne(1L);

System.out.println(stu);

}

@Test

public void selectList() {

List<Student> list = studetDAO.selectList();

for (Student stu:list) {

}

}

}

4.4.3 DAO 之保存操作

public void insert(Student stu) {

String sql = "INSERT INTO t_student(name,email,age) VALUES('" + stu.getName() + "','"

+ stu.getEmail() + "',"

+ stu.getAge() + ")";

System.out.println(sql);

Connection conn = null;

Statement st = null;

try {

// 1 加载注册驱动

Class.forName("com.mysql.jdbc.Driver");

// 2 获取连接对象

conn = DriverManager.getConnection("jdbc:mysql:///jdbcdemo", "root", "admin");// 3 获取语句对象

st = conn.createStatement();

// 4 执行sql 语句

st.executeUpdate(sql);

} catch (Exception e) {

e.printStackTrace();

} finally {

try {

if (st != null) {

st.close();

}

} catch (SQLException e) {

e.printStackTrace();

}

try {

if (conn != null) {

conn.close();

}

} catch (SQLException e) {

e.printStackTrace();

}

}

}

在完成保存的过程中,执行 SQL 需要的参数是调用者传递进来的,所以需要将其拼接到 SQL 里面

String sql = "INSERT INTO t_student(name,email,age) VALUES('" + stu.getName() + "','"

  • stu.getEmail() + "',"
  • stu.getAge() + ")";

System.out.println(sql);

可以看出,这里的拼接操作极其恶心, 容易错,还不容易发现,拼接多了语义很不清晰,所以这里需要优化(PreparedStatement)

伍、预编译语句对象

5.1 预编译语句对象简介

PreparedStatement 接口: 是 Statement 接口的子接口, 享有 Statement 中的方法.

使用的预编译语句对象,sql 语句中使用 ? 来作为值的占位符.

5.2 API 详解

Connection API:

PreparedStatement conn对象的.prepareStatement(String sql)

PreparedStatement API:

// 常用方法:

void setXxx(int parameterIndex,Xxx value); //设置第几个占位符的真正参数值.

// Xxx 表示数据类型,比如 String,int,long,Date等.

 void setObject(int parameterIndex, Object x); //设置第几个占位符的真正参数值. 5

  int executeUpdate(); //执行DDL/DML语句. 注意:没有参数

// 若当前 SQL是 DDL语句,则返回 0.

// 若当前 SQL是 DML语句,则返回受影响的行数.

   ResultSet executeQuery(); //执行DQL语句,返回结果集.

close(); //释放资源

有了 PreparedStatement 就可以使用占位符 ? 来代替拼接,这样语义更加清晰,数据设置也很清晰,所以以后都使用 PreparedStatement 预编译语句对象。

5.3 插入功能优化

调整之后的插入操作:

public void insert(Student stu) {

String sql = "INSERT INTO t_student(name,email,age) VALUES(?,?,?)";

System.out.println(sql);

// 贾琏欲执事

Connection conn = null;

PreparedStatement pst = null;

try {

// 1 加载注册驱动

Class.forName("com.mysql.jdbc.Driver");

// 2 获取连接对象

conn = DriverManager.getConnection("jdbc:mysql:///jdbcdemo", "root", "admin");

// 3 获取预编译语句对象

pst = conn.prepareStatement(sql);

// 给sql 的? 设置数据

pst.setObject(1,stu.getName());

pst.setObject(2,stu.getEmail());

pst.setObject(3,stu.getAge());

// 4 执行sql 语句

pst.executeUpdate();

} catch (Exception e) {

e.printStackTrace();

} finally {

try {

if (pst != null) {

pst.close();

}

} catch (SQLException e) {

 e.printStackTrace();

}

try {

if (conn != null) {

conn.close();

}

} catch (SQLException e) {

 e.printStackTrace();

}

}

}

六、基于 JDBC 的 DAO 案例

6.1 DAO 之更新、删除

更新和删除都属于 DML 操作,它们和插入的不同仅仅就 SQL 语句不同而已,其他的都是相同的。

DML 操作模板:

//String sql = "INSERT INTO t_student(name,email,age) VALUES(?,?,?)"; //String sql = "DELETE FROM t_student WHERE id=?";

String sql = "UPDATE t student SET name=?,email=?,age=? WHERE id=?";

Connection conn = null;

PreparedStatement pst = null;

try {

//1 加载注册驱动

Class.forName("com.mysql.jdbc.Driver");

//2 获取连接对象

conn = DriverManager.getConnection("jdbc:mysql:///jdbcdemo", "root", "admin");

//3 获取预编译语句对象

pst = conn.prepareStatement(sql);

//给sql 的? 设置数据

pst.setString(1, stu.getName());

pst.setString(2, stu.getEmail());

pst.setInt(3, stu.getAge());

pst.setLong(1,id);

pst.setString(1,stu.getName());

pst.setString(2,stu.getEmail());

pst.setInt(3,stu.getAge());

pst.setLong(4,stu.getId());

// 4 执行sql 语句

pst.executeUpdate();

} catch (Exception e) { e.printStackTrace();

} finally {

try {

if (pst != null) {

pst.close();

}

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

}

try {

if (conn != null) {

conn.close();

}

} catch (SQLException e) {

e.printStackTrace();

}

}

在此 DML 操作就完成了,目前就差 DQL 了。

6.2 DAO 之查询操作

DQL 操作和DML 操作的不同之处是 DQL 需要获取返回的数据,而这些数据都被存在一个叫 ResultSet 的对象中

ResultSet Statement对象的 executeQuery(String sql); //执行DQL语句,返回结果集.

ResultSet PreparedStatement对象的 executeQuery(); //执行DQL语句,返回结果集.

6.2.1_查询结果对象

ResultSet 接口: 通过执行 DQL 语句查询之后的结果对象.

ResultSet 对象具有指向其当前数据行的光标。最初,光标被置于第一行之前。next 方法将光标移动到下一行;因为该方法在 ResultSet 对象没有下一行时返回 false,所以可以在 while 循环中使用它来迭代结果集

// 常用方法:select id,name,age

boolean next(); //判断当前光标是否能向下移动,能向下移动返回true,并同时将光标移动到下一行Xxx getXxx(int columnIndex);  //取出当前光标所在行的第columnIndex列的数据(columnIndex 从1开始算).

Xxx getXxx(String columnName);//取出当前光标所在行的列名为columnName列的数据,columnName可以是别名.

// Xxx 表示数据类型,比如String,int,long,Date等. 推荐使用列名来取数据.

 close();// 释放资源

ResultSet 中存的数据则为查询出来的结果,这个结果就是一张表的结果。

id

name

email

age

1

小明

xiao@

18

2

小东

dong@

18

而我们要做的就是从 ResultSet 中来取出这些数据。

操作步骤

先取行: 默认光标在第一行,则为标题行(数据)使用 ResultSet 的 next 方法完成

再取列: id name age

// 取出当前光标所在行的第columnIndex列的数据(columnIndex 从 1 开始算).

Xxx getXxx(int columnIndex);  // 索引可能会变化,所以不建议使用

// 取出当前光标所在行的列名为columnName列的数据,columnName可以是别名.(推荐)

 Xxx getXxx(String columnName);

七、重构设计

在 DAO 的实现过程中,发现释放资源的代码非常恶心,而且还需要反复编写,这种代码我们通常可以抽取到工具类中: JDBCUtil

7.1 抽取 JDBCUtil 工具类

// JDBCUtil.java

  // 释放资源

public static void close(Connection conn, Statement pst, ResultSet rs) {

try {

if (rs != null) {

rs.close();

}

} catch (Exception e) {

e.printStackTrace();

} finally {

// 释放资源

try {

if (pst != null) {

pst.close();

}

} catch (Exception e) {

e.printStackTrace();

} finally {

try {

if (conn != null) {

conn.close();

}

} catch (Exception e) {

e.printStackTrace();

}

}

}

在获取连接的过程,需要指定连接的信息: 驱动类的全限定名 / url / 用户名 /密码(连接数据库的四要素), 但是每次都需要编写对应的字符串,麻烦,重复,也容易错。

将获取连接对象的操作抽取到工具类中,统一编写连接数据库的信息

//JDBCUtil.java

public static Connection getConnection() throws Exception {

// 加载注册驱动

Class.forName("com.mysql.jdbc.Driver");

//获取连接对象

return DriverManager.getConnection("jdbc:mysql://localhost:3306/javaweb", "root", "admin");

 }

加载注册驱动在整个程序只需要执行一次,所以将加载的代码放到静态代码块中

//JDBCUtil.java

 static {

// 加载注册驱动

// 该操作,在整个程序中只需要执行一次

try {

Class.forName("com.mysql.jdbc.Driver");

} catch (ClassNotFoundException e) {

e.printStackTrace();

}

 }

上面的代码中,我们是将连接数据库的信息编写在 Java 代码中的,这当中包括数据库的用户名和密码Java代码会编译成字节码文件,然后把字节码文件交给用户去使用,当用户需要修改数据库密码时,此时不方便

问题: 硬编码

解决方案: 配置文件 properties(key-value) || xml

由于四要素是key=value 格式,所有选择使用 properties

7.2_抽取db.properties

driverClassName=com.mysql.jdbc.Driver

 url=jdbc:mysql://localhost:3306/javaweb 4 username=root

 password=admin

将文件中的数据加载到内存中的 Properties 对象,然后再从 Properties 中获取数据,设置给 JDBC

// JDBCUtil.java

private JdbcUtil() {}

  private static Properties p;

 static {

// 加载注册驱动

// 该操作,在整个程序中只需要执行一次

try {

// properties配置文件只需要加载一次

InputStream in = Thread.currentThread().getContextClassLoader()

getResourceAsStream("db.properties");

p = new Properties();

p.load(in)

Class.forName(p.getProperty("driverClassName"));

} catch (Exception e) {

e.printStackTrace();

}

}

// 获取连接对象

public static Connection getConnection() throws Exception {

// 获取连接对象

return DriverManager.getConnection(

p.getProperty("url"),

p.getProperty("username"),

p.getProperty("password"));

}

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

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

相关文章

41.HOOK引擎设计原理

上一个内容&#xff1a;41.HOOK引擎设计原理 在一个游戏里通过hook来完成各种各样的功能&#xff0c;比如hook点是a、b、c&#xff0c;然后a点会有它自己所需要的hook逻辑&#xff0c;b、c也是有它们自己的hook逻辑&#xff08;hook逻辑指的是hook之后要做的事&#xff09;&am…

算法设计与分析--近似算法内容整理

文章目录 P、NP、NP-hard 和 NPC多项式时间概念区分NP-hard 的证明例题 1 证明 T S P TSP TSP 问题是 N P − h a r d NP-hard NP−hard 问题 。例题 2 证明最大加权独立集问题是 N P − h a r d NP-hard NP−hard 问题。 扩展 NP-hard 问题3-SAT 问题TSP 旅行商问题 Load B…

c#网络Tcp和udp

TCP 通信 TCP 服务端 Socket tcpServer new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); IPAddress ipAddress new IPAddress(new byte[] { 192, 168, 1, 5 }); IPEndPoint ipEndPoint new IPEndPoint(ipAddress, 7788); tcpServer.Bind(ip…

AI大模型的制造业场景,一文读懂

导读 如何认识这一轮AI技术发展影响的深度和广度&#xff1f;如何判断这一轮AI技术变革的性质&#xff1f; AI大模型是通用人工智能发展的重要里程碑。中央会议关于人工智能发展提出三个第一次&#xff1a;第一次提出“通用人工智能”&#xff0c;第一次提出“产业智能化”&a…

武汉星起航:激发中国卖家潜力,亚马逊减免政策共筑电商辉煌

在全球化电子商务的浪潮中&#xff0c;亚马逊作为全球领先的电商平台&#xff0c;一直致力于为卖家提供卓越的服务和支持。特别是对于中国卖家而言&#xff0c;亚马逊的减免优惠政策无疑是一股强大的助力&#xff0c;帮助他们在不断发展的市场中脱颖而出&#xff0c;实现业务的…

设计模式 - Observer Pattern 观察者模式

文章目录 定义观察者模式的实现构成构成UML图 观察者模式的代码实现场景代码实现 总结优点缺点应用场景 其他设计模式文章&#xff1a; 定义 观察者模式是行为型模式的一种&#xff0c;它定义对象间的一种一对多的依赖关系&#xff0c;使得每当一个对象改变状态&#xff0c;它…

重温react-08(createContext使用方式)

react中的createContext使用方式 简介一下&#xff0c;就是组件之间可以互相通信的比较好用的传值方式&#xff0c;话不多说直接上代码。 以下介绍的是类组件中的方式&#xff0c;在函数组件中不是如此使用的。 定义一个通用的方法 import { createContext } from "react…

MathType7.6专业数学公式编辑器!与Word、PPT等常用软件无缝对接。

MathType&#xff0c;一款专业的数学公式编辑器&#xff0c;以其强大的功能和友好的用户界面&#xff0c;在科研、教学等领域广受欢迎。它支持丰富的数学符号和公式模板&#xff0c;满足不同用户的需求。同时&#xff0c;MathType还提供了多种输出格式&#xff0c;方便与其他文…

基于YOLOv9+pyside的安检仪x光危险物物品检测(有ui)

安全检查在公共场所确保人身安全的关键环节&#xff0c;不可或缺。X光安检机作为必要工具&#xff0c;在此过程中发挥着重要作用。然而&#xff0c;其依赖人工监控和判断成像的特性限制了其应用效能。本文以此为出发点&#xff0c;探索了基于Torch框架的YOLO算法在安检X光图像中…

在linux 下交叉编译gdb 8.1.1 ,生成 windows下的exe程序

在Linux环境下进行交叉编译,生成适用于Windows的可执行程序(.exe),需要使用交叉编译工具链。对于特定的GDB版本(如8.1.1),你需要确保有适用于目标平台(Windows)的交叉编译工具链。以下是一些基本步骤和考虑因素: 获取GDB源码:首先,需要下载GDB 8.1.1的源码包。你可…

《数据结构与算法基础 by王卓老师》学习笔记——类C语言有关操作补充

1.元素类型说明 2.数组定义 3.C语言的内存动态分配 4..C中的参数传递 5.传值方式 6.传地址方式 例子

【计算机网络】期末复习(2)

目录 第一章&#xff1a;概述 第二章&#xff1a;物理层 第三章&#xff1a;数据链路层 第四章&#xff1a;网络层 第五章&#xff1a;传输层 第一章&#xff1a;概述 三大类网络 &#xff08;1&#xff09;电信网络 &#xff08;2&#xff09;有线电视网络 &#xff0…

快速了解GPT-4o和GPT-4区别

GPT-4o简介 在5月14日的OpenAI举行春季发布会上&#xff0c;OpenAI在活动中发布了新旗舰模型“GPT-4o”&#xff01;据OpenAI首席技术官穆里穆拉蒂&#xff08;Muri Murati&#xff09;介绍&#xff0c;GPT-4o在继承GPT-4强大智能的同时&#xff0c;进一步提升了文本、图像及语…

px、em、rem、rpx 作用和用法详解

px px像素&#xff08;Pixel&#xff09;。相对长度单位。像素px是相对于显示器屏幕分辨率而言的。 PX特点 IE无法调整那些使用px作为单位的字体大小&#xff1b; 国外的大部分网站能够调整的原因在于其使用了em或rem作为字体单位&#xff1b; Firefox能够调整px和em&#xff…

JVM原理(四):JVM垃圾收集算法与分代收集理论

从如何判定消亡的角度出发&#xff0c;垃圾收集算法可以划分为“引用计数式垃圾收集”和“追踪式垃圾收集”两大类。 本文主要介绍的是追踪式垃圾收集。 1. 分代收集理论 当代垃圾收集器大多遵循“分代收集”的理论进行设计&#xff0c;它建立在两个假说之上&#xff1a; 弱分…

C++11中如何创建线程

在C11中&#xff0c;创建线程变得非常简单和标准化&#xff0c;因为C11引入了线程库&#xff08;<thread>&#xff09;。这个库提供了std::thread类&#xff0c;使得创建和管理线程变得更加直接和方便。 以下是如何在C11中创建线程的基本步骤&#xff1a; 包含线程库&a…

重建控制文件

----------------------------------------------------以下是单节点--------------------------------------------------- 一、现象 1、某次测试环境数据库重启&#xff0c;报如下错误 ORA-38760: This database instance failed to turn on flashback database 启动到mo…

C# 特性 Attribute 反射 Reflection 元数据 Metadata 未完

在C#中&#xff0c;元数据&#xff08;Metadata&#xff09;是指与程序代码本身相关的数据&#xff0c;这些数据提供了代码的额外信息&#xff0c;但并不直接影响代码的执行。元数据在.NET框架中扮演着重要的角色&#xff0c;以下是一些常见的元数据类型和它们的用途&#xff1…

vue插槽的简单使用

默认插槽 1.在Category中创建插槽 <slot>默认值<slot/> 2.在App中使用 <Category tittle"美食"> <ul ><li v-for"(l,index) in foods" :key"index">{{l}}</li></ul> </Category> 3.运行后的…

【IC验证】UVM实验lab05

1. 寄存器建模的要点和顺序 1.1 寄存器创建 定义单个uvm_reg&#xff0c;各个域的确定&#xff0c;并利用configure函数来配置属性&#xff1b; class ctrl_reg extends uvm_reg;uvm_object_utils(ctrl_reg)/*uvm_reg;uvm_mem;uvm_reg_map;uvm_reg_block都继承于uvm_object类…