手撸Mybatis(二)—— 配置项的获取

本专栏的源码:https://gitee.com/dhi-chen-xiaoyang/yang-mybatis。

配置项解析

在mybatis中,一般我们会定义一个mapper-config.xml文件,来配置数据库连接的相关信息,以及我们的mapperxml文件存放目录。在本章,我们会读取这些文件,将其配置信息进行解析。
因为涉及到xml的解析,因此,我们先添加dom4j的依赖,以方便后续解析xml

<dependency><groupId>org.dom4j</groupId><artifactId>dom4j</artifactId><version>2.1.3</version></dependency>

mybatis-config.xml的内容如下,对于每一个环境,都有对应的数据源信息,此外,mappers标签存储的是mapper.xml文件的位置。

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration><environments default="development"><environment id="development"><transactionManager type="JDBC"/><dataSource type="POOLED"><property name="driver" value="com.mysql.jdbc.Driver"/><property name="url" value="jdbc:mysql://192.168.102.128:3306/test"/><property name="username" value="root"/><property name="password" value="123456"/></dataSource></environment></environments><mappers><mapper resource="mapper/UserMapper.xml"/></mappers>
</configuration>

首先,我们添加MybatisDataSource,用来记录数据源信息

package com.yang.mybatis.config;import java.io.Serializable;public class MybatisDataSource implements Serializable {private String driver;private String url;private String username;private String password;public String getDriver() {return driver;}public String getUrl() {return url;}public String getUsername() {return username;}public String getPassword() {return password;}public void setDriver(String driver) {this.driver = driver;}public void setUrl(String url) {this.url = url;}public void setUsername(String username) {this.username = username;}public void setPassword(String password) {this.password = password;}
}

然后添加一个MybatisEnvironment,用来存储环境信息

package com.yang.mybatis.config;import java.io.Serializable;public class MybatisEnvironment implements Serializable {private String id;private MybatisDataSource mybatisDataSource;public String getId() {return id;}public void setId(String id) {this.id = id;}public MybatisDataSource getMybatisDataSource() {return mybatisDataSource;}public void setMybatisDataSource(MybatisDataSource mybatisDataSource) {this.mybatisDataSource = mybatisDataSource;}
}

然后是MybatisConfiguration,我们读取mybatis-config.xml配置文件后,配置信息就存储在这个类中。

package com.yang.mybatis.config;import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;public class MybatisConfiguration implements Serializable {private Map<String, MybatisEnvironment> id2EnvironmentMap = new HashMap<>();private MybatisEnvironment defaultMybatisEnvironment;private List<String> mapperPaths = new ArrayList<>();public void addEnvironment(String id, MybatisEnvironment mybatisEnvironment) {this.id2EnvironmentMap.put(id, mybatisEnvironment);}public MybatisEnvironment getEnvironment(String id) {return id2EnvironmentMap.get(id);}public MybatisEnvironment getDefaultMybatisEnvironment() {return defaultMybatisEnvironment;}public void setDefaultMybatisEnvironment(MybatisEnvironment defaultMybatisEnvironment) {this.defaultMybatisEnvironment = defaultMybatisEnvironment;}public void addMapperPath(String mapperPath) {this.mapperPaths.add(mapperPath);}public List<String> getMapperPaths() {return this.mapperPaths;}public List<MybatisEnvironment> getEnvironments() {return new ArrayList<>(id2EnvironmentMap.values());}}

对于mybatis-config.xml的解析,我们定义一个IMybatisConfigParser接口

package com.yang.mybatis.config.parser;import com.yang.mybatis.config.MybatisConfiguration;public interface IMybatisConfigurationParser {MybatisConfiguration parser(String path) ;
}

然后定义其实现类:

package com.yang.mybatis.config.parser;import com.yang.mybatis.config.MybatisConfiguration;
import com.yang.mybatis.config.MybatisDataSource;
import com.yang.mybatis.config.MybatisEnvironment;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;public class XmlMybatisConfigurationParser implements IMybatisConfigurationParser {@Overridepublic MybatisConfiguration parser(String path) {MybatisConfiguration mybatisConfiguration = new MybatisConfiguration();try {InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream(path);SAXReader saxReader = new SAXReader();// 1. 读取文档Document document = saxReader.read(inputStream);Element root = document.getRootElement();parseEnvironments(mybatisConfiguration, root.element("environments"));parseMappers(mybatisConfiguration, root.element("mappers"));} catch (Exception e) {e.printStackTrace();}return mybatisConfiguration;}private void parseMappers(MybatisConfiguration mybatisConfiguration, Element mappers) {List<Element> mapperList = mappers.elements("mapper");for (Element mapper : mapperList) {String resource = mapper.attributeValue("resource");mybatisConfiguration.addMapperPath(resource);}}private void parseEnvironments(MybatisConfiguration mybatisConfiguration, Element environments) {String defaultId = environments.attributeValue("default");for (Element element : environments.elements()) {String id = element.attributeValue("id");Element dataSource = element.element("dataSource");List<Element> properties = dataSource.elements("property");Map<String, String> propertyMap = new HashMap<>();for (Element property : properties) {propertyMap.put(property.attributeValue("name"), property.attributeValue("value"));}String driver = propertyMap.get("driver");String url = propertyMap.get("url");String username = propertyMap.get("username");String password = propertyMap.get("password");MybatisDataSource mybatisDataSource = new MybatisDataSource();mybatisDataSource.setDriver(driver);mybatisDataSource.setUrl(url);mybatisDataSource.setUsername(username);mybatisDataSource.setPassword(password);MybatisEnvironment mybatisEnvironment = new MybatisEnvironment();mybatisEnvironment.setId(id);mybatisEnvironment.setMybatisDataSource(mybatisDataSource);mybatisConfiguration.addEnvironment(id, mybatisEnvironment);if (id.equals(defaultId)) {mybatisConfiguration.setDefaultMybatisEnvironment(mybatisEnvironment);}}}
}

然后添加测试代码进行测试:

 IMybatisConfigurationParser mybatisConfigurationParser = new XmlMybatisConfigurationParser();MybatisConfiguration mybatisConfiguration = mybatisConfigurationParser.parser("mybatis-config.xml");System.out.println("mapperPaths==========");for (String mapperPath : mybatisConfiguration.getMapperPaths()) {System.out.println(mapperPath);}System.out.println("environments========");for (MybatisEnvironment environment : mybatisConfiguration.getEnvironments()) {MybatisDataSource mybatisDataSource = environment.getMybatisDataSource();System.out.println("id:" + environment.getId()+ ",driver:" + mybatisDataSource.getDriver()+ ",url:" + mybatisDataSource.getUrl()+ ",username:" + mybatisDataSource.getUsername()+ ",password:" + mybatisDataSource.getPassword());}System.out.println("defaultEnvironment=======");MybatisEnvironment defaultMybatisEnvironment = mybatisConfiguration.getDefaultMybatisEnvironment();MybatisDataSource mybatisDataSource = defaultMybatisEnvironment.getMybatisDataSource();System.out.println("id:" + defaultMybatisEnvironment.getId()+ ",driver:" + mybatisDataSource.getDriver()+ ",url:" + mybatisDataSource.getUrl()+ ",username:" + mybatisDataSource.getUsername()+ ",password:" + mybatisDataSource.getPassword());

结果如下:
image.png

mapperXml的解析

首先添加一个MybatisSqlStatement

package com.yang.mybatis.config;import java.io.Serializable;public class MybatisSqlStatement implements Serializable {private String namespace;private String id;private String sql;public String getNamespace() {return namespace;}public void setNamespace(String namespace) {this.namespace = namespace;}public String getId() {return id;}public void setId(String id) {this.id = id;}public String getSql() {return sql;}public void setSql(String sql) {this.sql = sql;}
}

添加解析mapper文件的接口

package com.yang.mybatis.config.parser;import com.yang.mybatis.config.MybatisSqlStatement;import java.util.List;public interface IMybatisMapperParser {List<MybatisSqlStatement> parseMapper(String path);
}

具体实现:

package com.yang.mybatis.config.parser;import com.yang.mybatis.config.MybatisSqlStatement;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;public class XmlMybatisMapperParser implements IMybatisMapperParser {private final static Set<String> tagSet = new HashSet<>();static {tagSet.add("select");tagSet.add("insert");tagSet.add("update");tagSet.add("delete");tagSet.add("SELECT");tagSet.add("INSERT");tagSet.add("UPDATE");tagSet.add("DELETE");}@Overridepublic List<MybatisSqlStatement> parseMapper(String path) {List<MybatisSqlStatement> mybatisSqlStatements = new ArrayList<>();try {InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream(path);SAXReader saxReader = new SAXReader();Document document = saxReader.read(inputStream);Element root = document.getRootElement();for (String tag : tagSet) {List<Element> elements = root.elements(tag);parseStatement(mybatisSqlStatements, elements, root);}} catch (DocumentException e) {e.printStackTrace();}return mybatisSqlStatements;}private void parseStatement(List<MybatisSqlStatement> mybatisSqlStatements, List<Element> elements, Element root) {if (elements == null || elements.isEmpty()) {return;}String namespace = root.attributeValue("namespace");for (Element element : elements) {String id = element.attributeValue("id");String sql = element.getText().trim();MybatisSqlStatement mybatisSqlStatement = new MybatisSqlStatement();mybatisSqlStatement.setNamespace(namespace);mybatisSqlStatement.setId(id);mybatisSqlStatement.setSql(sql);mybatisSqlStatements.add(mybatisSqlStatement);}}
}

然后,我们创建一个UserMapper.xml,用于测试,该文件内容如下:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="com.yang.mybatis.test.IUserMapper"><select id="queryUserName">select user_name from user where id = #{id}</select><select id="queryUserAge">select age from user where id = #{id}</select>
</mapper>

添加测试代码,进行测试:

    public static void main(String[] args) {IMybatisMapperParser mybatisMapperParser = new XmlMybatisMapperParser();List<MybatisSqlStatement> mybatisSqlStatements = mybatisMapperParser.parseMapper("mapper/UserMapper.xml");for (MybatisSqlStatement mybatisSqlStatement : mybatisSqlStatements) {System.out.println("=================");System.out.println("namespace:" + mybatisSqlStatement.getNamespace());System.out.println("id:" + mybatisSqlStatement.getId());System.out.println("sql:" + mybatisSqlStatement.getSql());}}

结果如下:
image.png

MapperProxyFactory注册Mapper

这里再修改一些MybatisConfiguration,因为mapperXML里的内容,其实我认为也属于配置项,因此收敛到MybatisConfiguration,方便后续统一管理

package com.yang.mybatis.config;import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;public class MybatisConfiguration implements Serializable {private Map<String, MybatisEnvironment> id2EnvironmentMap = new HashMap<>();private MybatisEnvironment defaultMybatisEnvironment;private List<String> mapperPaths = new ArrayList<>();private Map<String, List<MybatisSqlStatement>> mapper2SqlStatementsMap = new HashMap<>();public void putMybatisSqlStatementList(String mapperName, List<MybatisSqlStatement> mybatisSqlStatementList) {if (mapper2SqlStatementsMap.containsKey(mapperName)) {mapper2SqlStatementsMap.get(mapperName).addAll(mybatisSqlStatementList);} else {mapper2SqlStatementsMap.put(mapperName, mybatisSqlStatementList);}}public Map<String, List<MybatisSqlStatement>> getMapper2SqlStatementsMap() {return this.mapper2SqlStatementsMap;}public void addEnvironment(String id, MybatisEnvironment mybatisEnvironment) {this.id2EnvironmentMap.put(id, mybatisEnvironment);}public MybatisEnvironment getEnvironment(String id) {return id2EnvironmentMap.get(id);}public MybatisEnvironment getDefaultMybatisEnvironment() {return defaultMybatisEnvironment;}public void setDefaultMybatisEnvironment(MybatisEnvironment defaultMybatisEnvironment) {this.defaultMybatisEnvironment = defaultMybatisEnvironment;}public void addMapperPath(String mapperPath) {this.mapperPaths.add(mapperPath);}public List<String> getMapperPaths() {return this.mapperPaths;}public List<MybatisEnvironment> getEnvironments() {return new ArrayList<>(id2EnvironmentMap.values());}}

然后修改MapperProxy,接收MybatisSqlStatement数组,在执行的时候,根据执行方法,找到对应的MybatisSqlStatement,获取mapper Xml对应的sql语句,并打印出来

package com.yang.mybatis.mapper;import com.yang.mybatis.config.MybatisSqlStatement;import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.List;
import java.util.Map;public class MapperProxy<T> implements InvocationHandler {private Map<String, MybatisSqlStatement> sqlSessionMap = new HashMap<>();private Class<T> mapperInterface;public MapperProxy(Class<T> mapperInterface, List<MybatisSqlStatement> mybatisSqlStatementList) {this.mapperInterface = mapperInterface;for (MybatisSqlStatement mybatisSqlStatement : mybatisSqlStatementList) {String mapperName = mybatisSqlStatement.getNamespace();String id = mybatisSqlStatement.getId();String key = mapperName + "." + id;sqlSessionMap.put(key, mybatisSqlStatement);}}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {if (Object.class.equals(method.getDeclaringClass())) {return method.invoke(this, args);}String key = this.mapperInterface.getName() + "." + method.getName();return "你的被代理了!" + sqlSessionMap.get(key).getSql();}
}

接着修改MybatisProxyFactory,通过配置信息,加载对应的mapper.xml文件并进行解析

package com.yang.mybatis.mapper;import com.yang.mybatis.config.MybatisConfiguration;
import com.yang.mybatis.config.MybatisSqlStatement;import java.lang.reflect.Proxy;
import java.util.HashMap;
import java.util.List;
import java.util.Map;public class MapperProxyFactory {private Map<Class, MapperProxy> mapperProxyMap = new HashMap<>();public MapperProxyFactory(MybatisConfiguration mybatisConfiguration) {Map<String, List<MybatisSqlStatement>> mapperName2SqlStatementsMap = mybatisConfiguration.getMapper2SqlStatementsMap();mapperName2SqlStatementsMap.forEach((mapperName, sqlStatementList) -> {try {Class<?> type = Class.forName(mapperName);mapperProxyMap.put(type, new MapperProxy(type, sqlStatementList));} catch (ClassNotFoundException e) {throw new RuntimeException(e);}});}public Object newInstance(Class mapperType) {MapperProxy mapperProxy = mapperProxyMap.get(mapperType);return Proxy.newProxyInstance(mapperType.getClassLoader(),new Class[]{mapperType},mapperProxy);}}

添加测试方法,进行测试:

public static void main(String[] args) {IMybatisConfigurationParser iMybatisConfigurationParser = new XmlMybatisConfigurationParser();MybatisConfiguration mybatisConfiguration = iMybatisConfigurationParser.parser("mybatis-config.xml");IMybatisMapperParser iMybatisMapperParser = new XmlMybatisMapperParser();List<String> mapperPaths = mybatisConfiguration.getMapperPaths();for (String mapperPath : mapperPaths) {List<MybatisSqlStatement> mybatisSqlStatements = iMybatisMapperParser.parseMapper(mapperPath);Map<String, List<MybatisSqlStatement>> mapperNameGroupMap = mybatisSqlStatements.stream().collect(Collectors.groupingBy(MybatisSqlStatement::getNamespace));for (Map.Entry<String, List<MybatisSqlStatement>> entry : mapperNameGroupMap.entrySet()) {String mapperName = entry.getKey();List<MybatisSqlStatement> sqlSessionList = entry.getValue();mybatisConfiguration.putMybatisSqlStatementList(mapperName, sqlSessionList);}}MapperProxyFactory mapperProxyFactory = new MapperProxyFactory(mybatisConfiguration);IUserMapper userMapper = (IUserMapper) mapperProxyFactory.newInstance(IUserMapper.class);System.out.println(userMapper.queryUserName(1));}

测试结果如下:
image.png

参考文章

https://zhuanlan.zhihu.com/p/338300626

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

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

相关文章

docker-compose启动mysql5.7报错

描述一下问题经过&#xff1a; 使用docker compose 部署mysql5.7 文件如下: 使用命名卷的情况下&#xff0c;匿名卷不存在该问题 services:mysql:restart: alwaysimage: mysql:5.7container_name: mysql-devports:- 3306:3306environment:- MYSQL_DATABASEdev- MYSQL_ROOT_PAS…

团队经理口才训练教案(3篇)

团队经理口才训练教案&#xff08;3篇&#xff09; **篇&#xff1a;基础口才训练 一、教学目标 让团队经理了解口才在团队管理中的重要性。 教授基础口才技巧&#xff0c;如发音、语速、语调等。 二、教学内容 口才的重要性 强调团队经理的口才能力对团队凝聚力、沟通…

详细介绍ARM-ORACLE Database 19c数据库下载

目录 1. 前言 2. 获取方式 2.1 ORACLE专栏 2.2 ORACLE下载站点 1. 前言 现有网络上已有非常多关于ORACLE数据库机下载的介绍&#xff0c;但对于ARM平台的介绍不多&#xff0c;借此机会我将该版的下载步骤做如下说明&#xff0c;希望能够一些不明之人提供帮助和参考 2. 获…

分享一篇关于AGI的短文:苦涩的教训

学习强化学习之父、加拿大计算机科学家理查德萨顿&#xff08; Richard S. Sutton &#xff09;2019年的经典文章《The Bitter Lesson&#xff08;苦涩的教训&#xff09;》。 文章指出&#xff0c;过去70年来AI研究走过的最大弯路&#xff0c;就是过于重视人类既有经验和知识&…

Flutter笔记:美工设计.导出视频到RIVE

Flutter笔记 美工设计.导出视频到RIVE - 文章信息 - Author: 李俊才 (jcLee95) Visit me at CSDN: https://jclee95.blog.csdn.netMy WebSite&#xff1a;http://thispage.tech/Email: 291148484163.com. Shenzhen ChinaAddress of this article:https://blog.csdn.net/qq_28…

目标跟踪—卡尔曼滤波

目标跟踪—卡尔曼滤波 卡尔曼滤波引入 滤波是将信号中特定波段频率滤除的操作&#xff0c;是抑制和防止干扰的一项重要措施。是根据观察某一随机过程的结果&#xff0c;对另一与之有关的随机过程进行估计的概率理论与方法。 历史上最早考虑的是维纳滤波&#xff0c;后来R.E.卡…

原生IP和住宅IP有什么区别?

原生IP和住宅IP在多个方面存在显著的区别。 从定义和来源来看&#xff0c;原生IP是指未经NAT&#xff08;网络地址转换&#xff09;处理的真实、公网可路由的IP地址&#xff0c;它直接从互联网服务提供商&#xff08;ISP&#xff09;获得&#xff0c;而不是通过代理服务器或VP…

【MATLAB】解决不同版本MATLAB出现中文乱码的问题

解决不同版本MATLAB出现中文乱码的问题 方法1&#xff1a;更改保存类型为GBK方法2&#xff1a;记事本打开方法3&#xff1a;Notepad参考 低版本matlab打开高版本Matlab的.m文件时&#xff0c;出现中文乱码问题。比如下图&#xff1a; 出现原因为&#xff1a; 编码格式不统一问…

批量抓取某电影网站的下载链接

思路&#xff1a; 进入电影天堂首页&#xff0c;提取到主页面中的每一个电影的背后的那个urL地址 a. 拿到“2024必看热片”那一块的HTML代码 b. 从刚才拿到的HTML代码中提取到href的值访问子页面&#xff0c;提取到电影的名称以及下载地址 a. 拿到子页面的页面源代码 b. 数据提…

Ansys Speos|进行智能手机镜头杂散光分析

本例的目的是研究智能手机Camera系统的杂散光。杂散光是指光向相机传感器不需要的散光光或镜面光&#xff0c;是在光学设计中无意产生的&#xff0c;会降低相机系统的光学性能。 在本例中&#xff0c;光学透镜系统使用Ansys Zemax OpticStudio (ZOS)进行设计&#xff0c;并使用…

A Bug‘s Life (并查集)

//新生训练 #include <iostream> #include <algorithm> using namespace std; const int N 5000; int p[N], sz[N]; int n, m; int find(int x) {if (p[x] ! x)p[x] find(p[x]);return p[x]; } int main() {int T;scanf("%d", &T);for (int k 1; …

RabbitMQ之顺序消费

什么是顺序消费 例如&#xff1a;业务上产生者发送三条消息&#xff0c; 分别是对同一条数据的增加、修改、删除操作&#xff0c; 如果没有保证顺序消费&#xff0c;执行顺序可能变成删除、修改、增加&#xff0c;这就乱了。 如何保证顺序性 一般我们讨论如何保证消息的顺序性&…

Flask教程3:jinja2模板引擎

文章目录 模板的导入与使用 模板的导入与使用 Flask通过render_template来实现模板的渲染&#xff0c;要使用这个方法&#xff0c;我们需要导入from flask import rander_template&#xff0c;模板中注释需放在{# #}中 模板的第一个参数为指定的模板文件名称&#xff0c;如自定…

gige工业相机突破(一,准备资源)

gige相机能不能绕开相机生产商提供的sdk&#xff0c;而直接取到像&#xff1f; 两种办法&#xff0c;第一&#xff0c;gige vision2.0说明书&#xff0c;第二&#xff0c;genicam 首先你会去干什么事&#xff1f; 好几年&#xff0c;我都没有突破&#xff0c;老虎吃天&#x…

鸿蒙开发仿咸鱼TabBar

鸿蒙开发自定义TabBar&#xff0c;实现tabBar 上中间按钮凸起效果 第一步、定义数据模型 export default class TabItemData{defaultIcon: ResourceselectedIcon: Resourcetitle: stringisMiddle: booleanconstructor(defaultIcon:Resource, selectedIcon:Resource, title:st…

5分钟速通大语言模型(LLM)的发展与基础知识

✍️ 作者&#xff1a;哈哥撩编程&#xff08;视频号同名&#xff09; 博客专家全国博客之星第四名超级个体COC上海社区主理人特约讲师谷歌亚马逊演讲嘉宾科技博主极星会首批签约作者 &#x1f3c6; 推荐专栏&#xff1a; &#x1f3c5; 程序员&#xff1a;职场关键角色通识宝…

Rust web简单实战

一、使用async搭建简单的web服务 1、修改cargo.toml文件添加依赖 [dependencies] futures "0.3" tokio { version "1", features ["full"] } [dependencies.async-std] version "1.6" features ["attributes"]2、搭…

Java发送请求-http+https的

第一步&#xff1a;建议ssl连接对象&#xff0c;信任所有证书 第二步&#xff1a;代码同时支持httphttps 引入源码类 是一个注册器 引入这个类&#xff0c;和它的方法create 注册器&#xff0c;所以对http和https都进行注册&#xff0c;参数为id和item&#xff0c;其中http的…

WebAssembly 入门教程 c++、python编译wasm

WebAssembly 入门 了解 wasm 使用场景&#xff0c;复杂对象传递和经验法则。 简介 WebAssembly 是一种新的编码方式&#xff0c;可以在现代的网络浏览器中运行。它是一种低级的类汇编语言&#xff0c;具有紧凑的二进制格式&#xff0c;可以接近原生的性能运行&#xff0c;并…

c#学习基础1

一、复杂数据类型 1&#xff09;概述 2&#xff09;枚举 1.基本概念 枚举是一个比较特别的存在&#xff0c;它是一个被命名的整形常量的集合&#xff0c;一般用它来表示状态&#xff0c;类型等 1.1申明枚举和申明枚举变量 1.2申明枚举语法 2.在哪里申明枚举 3.枚举的使用 4…