C# Winform DataGridView 控件和 DataTable

news2024/11/16 21:42:50

目录

一、概述

二、DataTable 的用法

1.创建表和列

2.添加行

3.取值和赋值

4.删除行

5.遍历 DataTable

6.判断 DataTable 列中是否存在某个值

7.设置主键

8.获取 DataRow 所在的行号

9.DataTable 转换为 List

10.将 List 转 DataTable

三、DataGridView 的用法

1.绑定数据

2.获取绑定的数据源

3.获取 / 设置 选中单元格的数据

4.设置单元格的宽高

结束


一、概述

DataGridView 控件提供用于显示数据的可自定义表。 类 DataGridView 允许通过使用属性(如 DefaultCellStyle、 ColumnHeadersDefaultCellStyle、 CellBorderStyle和)自定义单元格、行、列和 GridColor边框。 有关详细信息,请参阅微软 DataGridView 控件中的基本格式设置和样式设置。

可以使用 DataGridView 控件在基础数据源中或不使用基础数据源显示数据。 如果不指定数据源,可以创建包含数据的列和行,并将其直接添加到 DataGridView using Rows and Columns properties。 还可以使用 Rows 集合访问 DataGridViewRow 对象和 DataGridViewRow.Cells 属性来直接读取或写入单元格值。 索引 Item[] 器还提供对单元格的直接访问。

作为手动填充控件的替代方法,可以设置 DataSource 属性 DataMember 以绑定到 DataGridView 数据源并自动填充数据。 有关详细信息,请参阅微软 DataGridView 控件中显示数据。

处理大量数据时,可以将属性设置为 VirtualModetrue 显示可用数据的子集。 虚拟模式需要实现在其中填充控件的数据缓存 DataGridView 。 

二、DataTable 的用法

1.创建表和列

使用 new DataTable() 来创建一个 DataTable 表,创建表可以加上表名,也可以不加

DataTable dt = new DataTable();
DataTable dt1 = new DataTable("Datas");

DataTable 表 和我们常用的 Excel 是一样的,如下图,列就是 A,B,C,D.....   行就是 1,2,3,4..... 

只是 DataTable 在创建后,是空的,既没有自动创建的列,也没有自动创建的行,这些都是要我们通过代码来实现的。

创建列通过 实例化 DataColumn 类,并 DataColumn 类 添加到 DataTable.Columns 中来实现添加一列。

DataTable dt = new DataTable("Datas");
DataColumn dc1 = new DataColumn("商品编号");
DataColumn dc2 = new DataColumn("商品名称");
DataColumn dc3 = new DataColumn("商品重量");
DataColumn dc4 = new DataColumn("商品价格");
DataColumn dc5 = new DataColumn("购买数量");
dt.Columns.Add(dc1);
dt.Columns.Add(dc2);
dt.Columns.Add(dc3);
dt.Columns.Add(dc4);
dt.Columns.Add(dc5);

在添加列的同时,可以给列添加一些设置

DataTable dt = new DataTable("Datas");
DataColumn dc1 = new DataColumn("商品编号");
DataColumn dc2 = new DataColumn("商品名称");
DataColumn dc3 = new DataColumn("商品重量");
DataColumn dc4 = new DataColumn("商品价格");
DataColumn dc5 = new DataColumn("购买数量");

dc1.AutoIncrement = true;//自动增加
dc1.AutoIncrementSeed = 1;//起始为1
dc1.AutoIncrementStep = 1;//步长为1
dc1.AllowDBNull = false;//是否允许空值
			
dt.Columns.Add(dc1);
dt.Columns.Add(dc2);
dt.Columns.Add(dc3);
dt.Columns.Add(dc4);
dt.Columns.Add(dc5);

只是这么做比较繁琐,因此不推荐。

推荐用下面方式去添加列

DataTable dt = new DataTable("Datas");
DataColumn dc = new DataColumn();
dc.AutoIncrement = true;//自动增加
dc.AutoIncrementSeed = 1;//起始为1
dc.AutoIncrementStep = 1;//步长为1
dc.AllowDBNull = false;//是否允许空值

//添加列
dt.Columns.Add("姓名", typeof(string));
dt.Columns.Add("年龄", typeof(int));
dt.Columns.Add("身高", typeof(float));
dt.Columns.Add("体重", typeof(float));

dataGridView1.DataSource = dt;

在 Winform 中的运行效果

此时表格的行还没有数据,下面看看怎么添加行数据吧 

2.添加行

通过添加 DataRow 类来添加行,如下:

DataTable dt = new DataTable("Datas");
DataColumn dc = new DataColumn();
dc.AutoIncrement = true;//自动增加
dc.AutoIncrementSeed = 1;//起始为1
dc.AutoIncrementStep = 1;//步长为1
dc.AllowDBNull = false;//是否允许空值

//添加列
dt.Columns.Add("姓名", typeof(string));
dt.Columns.Add("年龄", typeof(int));
dt.Columns.Add("身高", typeof(float));
dt.Columns.Add("体重", typeof(float));

//添加行
DataRow newRow = dt.NewRow();
newRow["姓名"] = "1号";
newRow["年龄"] = "17";
newRow["身高"] = "155";
newRow["体重"] = "220";
dt.Rows.Add(newRow);

dataGridView1.DataSource = dt;

运行:

这么写虽然可以实现添加行,但用起来很繁琐, 当然也有简洁的写法

DataTable dt = new DataTable("Datas");
DataColumn dc = new DataColumn();
dc.AutoIncrement = true;//自动增加
dc.AutoIncrementSeed = 1;//起始为1
dc.AutoIncrementStep = 1;//步长为1
dc.AllowDBNull = false;//是否允许空值

//添加列
dt.Columns.Add("姓名", typeof(string));
dt.Columns.Add("年龄", typeof(int));
dt.Columns.Add("身高", typeof(float));
dt.Columns.Add("体重", typeof(float));

//添加行
dt.Rows.Add("2号", 12, 220, 300);

dataGridView1.DataSource = dt;

运行:

这里添加行的写法,也可以换成下面的写法,效果是一样的

dt.Rows.Add(new object[] { "2号", 12, 220, 300 });

 

3.取值和赋值

在获取和设置这些数据之前,先添加一些数据

DataTable dt = new DataTable("Datas");
DataColumn dc = new DataColumn();
dc.AutoIncrement = true;//自动增加
dc.AutoIncrementSeed = 1;//起始为1
dc.AutoIncrementStep = 1;//步长为1
dc.AllowDBNull = false;//是否允许空值

//添加列
dc = dt.Columns.Add("姓名", typeof(string));
dc = dt.Columns.Add("年龄", typeof(int));
dc = dt.Columns.Add("身高", typeof(float));
dc = dt.Columns.Add("体重", typeof(float));

//添加行
dt.Rows.Add("1号", 17, 155, 220);
dt.Rows.Add("2号", 12, 220, 300);
dt.Rows.Add("3号", 45, 170, 132);

dataGridView1.DataSource = dt;

运行:

 

1)赋值

通过索引号赋值

DataTable dt = new DataTable("Datas");
DataColumn dc = new DataColumn();
dc.AutoIncrement = true;//自动增加
dc.AutoIncrementSeed = 1;//起始为1
dc.AutoIncrementStep = 1;//步长为1
dc.AllowDBNull = false;//是否允许空值

//添加列
dt.Columns.Add("姓名", typeof(string));
dt.Columns.Add("年龄", typeof(int));
dt.Columns.Add("身高", typeof(float));
dt.Columns.Add("体重", typeof(float));

//添加行
dt.Rows.Add("1号", 17, 155, 220);
dt.Rows.Add("2号", 12, 220, 300);
dt.Rows.Add("3号", 45, 170, 132);

dataGridView1.DataSource = dt;

//1)赋值
dt.Rows[0][0] = "张三";

运行:

注意这里,dt.Rows[0] 是指第几行, 第二个 0 才是指第几列,如果将 dt.Rows[0] 改为 dt.Rows[1] 效果如下:

 

通过列名赋值

dt.Rows[0] 里面的行号的定义只能用数字去定义,但是后面的列可以用列名去获取

dt.Rows[0]["姓名"] = "张三";

效果:

2)取值

取值和获取值用法和变量的用法差不多,只是返回来的类型是 object 类型,做一下转换就好了

DataTable dt = new DataTable("Datas");
DataColumn dc = new DataColumn();
dc.AutoIncrement = true;//自动增加
dc.AutoIncrementSeed = 1;//起始为1
dc.AutoIncrementStep = 1;//步长为1
dc.AllowDBNull = false;//是否允许空值

//添加列
dt.Columns.Add("姓名", typeof(string));
dt.Columns.Add("年龄", typeof(int));
dt.Columns.Add("身高", typeof(float));
dt.Columns.Add("体重", typeof(float));

//添加行
dt.Rows.Add("1号", 17, 155, 220);
dt.Rows.Add("2号", 12, 220, 300);
dt.Rows.Add("3号", 45, 170, 132);

dataGridView1.DataSource = dt;

//2)取值           
object name = dt.Rows[0]["姓名"];
object age = dt.Rows[0][1];
Console.WriteLine(name);
Console.WriteLine(age);

运行:

 

4.删除行

删除行有多中写法,可以使用 dt.Rows.Remove(dt.Rows[0]);

DataTable dt = new DataTable("Datas");
DataColumn dc = new DataColumn();
dc.AutoIncrement = true;//自动增加
dc.AutoIncrementSeed = 1;//起始为1
dc.AutoIncrementStep = 1;//步长为1
dc.AllowDBNull = false;//是否允许空值

//添加列
dt.Columns.Add("姓名", typeof(string));
dt.Columns.Add("年龄", typeof(int));
dt.Columns.Add("身高", typeof(float));
dt.Columns.Add("体重", typeof(float));

//添加行
dt.Rows.Add("1号", 17, 155, 220);
dt.Rows.Add("2号", 12, 220, 300);
dt.Rows.Add("3号", 45, 170, 132);

//删除行
dt.Rows.Remove(dt.Rows[0]);

dataGridView1.DataSource = dt;

也可以使用 dt.Rows.RemoveAt(0)  效果是一样的

dt.Rows.RemoveAt(0);

运行:

 

5.遍历 DataTable

列名,和表格的内容遍历是分开的

DataTable dt = new DataTable("Datas");
DataColumn dc = new DataColumn();
dc.AutoIncrement = true;//自动增加
dc.AutoIncrementSeed = 1;//起始为1
dc.AutoIncrementStep = 1;//步长为1
dc.AllowDBNull = false;//是否允许空值

//添加列
dt.Columns.Add("姓名", typeof(string));
dt.Columns.Add("年龄", typeof(int));
dt.Columns.Add("身高", typeof(float));
dt.Columns.Add("体重", typeof(float));

//添加行
dt.Rows.Add("1号", 17, 155, 220);
dt.Rows.Add("2号", 12, 220, 300);
dt.Rows.Add("3号", 45, 170, 132);

//打印所有列名
string columnName = string.Empty;
for (int i = 0; i < dt.Columns.Count; i++)
{
    columnName += string.Format("{0}({1}) | ", dt.Columns[i].ColumnName, i);
}
Console.WriteLine(columnName);

//打印每一行的数据
foreach (DataRow row in dt.Rows)
{
    string columnStr = string.Empty;
    foreach (DataColumn column in dt.Columns)
    {
        columnStr += row[column] + " | ";
    }
    Console.WriteLine(columnStr);
}

dataGridView1.DataSource = dt;

打印每一行的数据,不想用 foreach ,使用 for 循环也是可以的。


for (int i = 0; i < dt.Rows.Count; i++)
{
    string columnStr = string.Empty;
    for (int j = 0; j < dt.Columns.Count; j++)
    {
        columnStr += dt.Rows[i][j] + " | ";
    }
    Console.WriteLine(columnStr);
}

运行效果,Winform 和 控制台:

 

6.判断 DataTable 列中是否存在某个值

使用 DataTable.Select 来查询表格中的数据

DataTable dt = new DataTable("Datas");
DataColumn dc = new DataColumn();
dc.AutoIncrement = true;//自动增加
dc.AutoIncrementSeed = 1;//起始为1
dc.AutoIncrementStep = 1;//步长为1
dc.AllowDBNull = false;//是否允许空值

//添加列
dt.Columns.Add("姓名", typeof(string));
dt.Columns.Add("年龄", typeof(int));
dt.Columns.Add("身高", typeof(float));
dt.Columns.Add("体重", typeof(float));

//添加行
dt.Rows.Add("1号", 17, 155, 220);
dt.Rows.Add("2号", 12, 220, 300);
dt.Rows.Add("3号", 45, 170, 132);

//判断 DataTable 列中是否存在某个值
DataRow[] seleRes = dt.Select(string.Format("{0}='{1}'", "姓名", "2号"));
Console.WriteLine("寻找结果:{0}", seleRes.Length > 0);

运行:

将代码作一下更改

DataRow[] seleRes = dt.Select(string.Format("{0}='{1}'", "姓名", "2"));
Console.WriteLine("寻找结果:{0}", seleRes.Length > 0);

运行:

 

7.设置主键

表的主键必须是唯一的,才能标识表中的记录。 还可以使用由两列或更多列组成的主键的表。 当单个列不能包含足够的唯一值时,将发生这种情况。 例如,两列主键可能包含“OrderNumber”和“ProductID”列。 由于主键可以由多个列组成,因此 PrimaryKey 该属性由对象数组 DataColumn 组成。

DataTable dt = new DataTable("Datas");
DataColumn dc = new DataColumn();
dc.AutoIncrement = true;//自动增加
dc.AutoIncrementSeed = 1;//起始为1
dc.AutoIncrementStep = 1;//步长为1
dc.AllowDBNull = false;//是否允许空值

//添加列
dt.Columns.Add("姓名", typeof(string));
dt.Columns.Add("年龄", typeof(int));
dt.Columns.Add("身高", typeof(float));
dt.Columns.Add("体重", typeof(float));

//添加行
dt.Rows.Add("1号", 17, 155, 220);
dt.Rows.Add("2号", 12, 220, 300);
dt.Rows.Add("3号", 45, 170, 132);

//设置主键
DataColumn[] PrimaryKeyColumns = new DataColumn[2];
//添加主键,必须是已经在DataTable里有的列名
PrimaryKeyColumns[0] = dt.Columns["姓名"];
PrimaryKeyColumns[1] = dt.Columns["年龄"];
//配置主键
dt.PrimaryKey = PrimaryKeyColumns;

8.获取 DataRow 所在的行号

一个主键的获取方法

DataTable dt = new DataTable("Datas");
DataColumn dc = new DataColumn();
dc.AutoIncrement = true;//自动增加
dc.AutoIncrementSeed = 1;//起始为1
dc.AutoIncrementStep = 1;//步长为1
dc.AllowDBNull = false;//是否允许空值

//添加列
dt.Columns.Add("姓名", typeof(string));
dt.Columns.Add("年龄", typeof(int));
dt.Columns.Add("身高", typeof(float));
dt.Columns.Add("体重", typeof(float));

//添加行
dt.Rows.Add("1号", 17, 155, 220);
dt.Rows.Add("2号", 12, 220, 300);
dt.Rows.Add("3号", 45, 170, 132);

//设置主键
DataColumn[] PrimaryKeyColumns = new DataColumn[1];
//添加主键,必须是已经在DataTable里有的列名
PrimaryKeyColumns[0] = dt.Columns["姓名"];
//配置主键
dt.PrimaryKey = PrimaryKeyColumns;

//获取行号
DataRow dataRow = dt.Rows.Find("3号");
int index = dataRow.Table.Rows.IndexOf(dataRow);
Console.WriteLine("行号:{0}", index);

运行:

如果是两个主键,要这么写

//设置主键
DataColumn[] PrimaryKeyColumns = new DataColumn[2];
//添加主键,必须是已经在DataTable里有的列名
PrimaryKeyColumns[0] = dt.Columns["姓名"];
PrimaryKeyColumns[1] = dt.Columns["年龄"];
//配置主键
dt.PrimaryKey = PrimaryKeyColumns;

//获取行号
DataRow dataRow = dt.Rows.Find(new object[] { "3号", 45 });
int index = dataRow.Table.Rows.IndexOf(dataRow);
Console.WriteLine("行号:{0}", index);

运行结果依然是:2

注意,这里的姓名和年龄必须匹配,如果写错了,比如,将 45 改为 46,代码也会报错

 

9.DataTable 转换为 List<T>

代码


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Reflection;
 
/// <summary>
/// 将DataTable数据源转换成实体类
/// </summary>
public static class ConvertTool
{
    /// <summary>
    /// DataTable转换成实体类
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="dt"></param>
    /// <returns></returns>
    public static List<T> TableToEntity<T>(DataTable dt) where T : class, new()
    {
        List<T> list = new List<T>();
        try
        {
            foreach (DataRow row in dt.Rows)
            {
                T entity = new T();
                PropertyInfo[] pArray = entity.GetType().GetProperties();
 
                foreach (PropertyInfo p in pArray)
                {
                    if (dt.Columns.Contains(p.Name))
                    {
                        if (!p.CanWrite) continue;
                        var value = row[p.Name];
                        if (value != DBNull.Value)
                        {
                            Type targetType = p.PropertyType;
                            Type convertType = targetType;
                            if (targetType.IsGenericType && targetType.GetGenericTypeDefinition().Equals(typeof(Nullable<>)))
                            {
                                //可空类型
                                NullableConverter nullableConverter = new NullableConverter(targetType);
                                convertType = nullableConverter.UnderlyingType;
                            }
                            if (!string.IsNullOrEmpty(convertType.FullName) && !string.IsNullOrEmpty(value.ToString()))
                            {
                                value = Convert.ChangeType(value, convertType);
                            }
                            switch (convertType.FullName)
                            {
                                case "System.Decimal":
                                    p.SetValue(entity, Convert.ToDecimal(value), null);
                                    break;
                                case "System.String":
                                    p.SetValue(entity, Convert.ToString(value), null);
                                    break;
                                case "System.Int32":
                                    p.SetValue(entity, Convert.ToInt32(value), null);
                                    break;
                                case "System.Int64":
                                    p.SetValue(entity, Convert.ToInt64(value), null);
                                    break;
                                case "System.Int16":
                                    p.SetValue(entity, Convert.ToInt16(value), null);
                                    break;
                                case "System.Double":
                                    p.SetValue(entity, Convert.ToDouble(value), null);
                                    break;
                                case "System.DateTime":
                                    p.SetValue(entity, Convert.ToDateTime(value), null);
                                    break;
                                default:
                                    p.SetValue(entity, value, null);
                                    break;
                            }
                        }
                    }
                }
                list.Add(entity);
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
        }
 
        if(list.Count > 0)
            return list;
        else
            return null;
    }
}

10.将 List<T> 转 DataTable

这里分不转换标题和转换标题,先看看 List<T> 直接转换为 DataTable,如果 T 的实体类字段为英文,那么 DataTable 的列名也将全是英文显示

/// <summary>
/// 将 List 转换成 DataTable (不转换标题)
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="data"></param>
/// <returns></returns>
public static DataTable ToDataTable<T>(List<T> data)
{
    if(data == null || data.Count == 0) return null;

    PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(typeof(T));
    DataTable dt = new DataTable();
    for (int i = 0; i < properties.Count; i++)
    {
        PropertyDescriptor property = properties[i];
        dt.Columns.Add(property.Name, property.PropertyType);
    }
    object[] values = new object[properties.Count];
    foreach (T item in data)
    {
        for (int i = 0; i < values.Length; i++)
        {
            values[i] = properties[i].GetValue(item);
        }
        dt.Rows.Add(values);
    }
    return dt;
}

将英文的字段转换为中文列名,这需要做一些转换,我建立了一个自定义特性 UserAttribute,如下

using System;

//自定义特性类
[AttributeUsage(AttributeTargets.Property)]
internal class UserAttribute : Attribute
{
    public string ChineseName { get; set; }

    public UserAttribute(string chineseName)
    {
        ChineseName = chineseName;
    }
}

将要把转换为中文的字段,在特性中添加中文名

internal class UserInfo
{
    [User("用户名")]
    public string UserName { get; set; }

    [User("地址")]
    public string Address { get; set; }

    [User("年龄")]
    public int Age { get; set; }

    [User("重量")]
    public int Weight { get; set; }
}

转换方法:

/// <summary>
/// 将 List 转换为 DataTable (转换标题)
/// </summary>
/// <param name="list">数据实体</param>
/// <returns></returns>
public static DataTable ListToDataTable<T>(List<T> list)
{
    if (list == null || list.Count == 0) return null;

    //创建一个名为"tableName"的空表
    DataTable dt = new DataTable("tableName");

    //key 中文名, value 英文名
    Dictionary<string, string> dic = new Dictionary<string, string>();

    //创建传入对象名称的列
    foreach (var item in list.FirstOrDefault().GetType().GetProperties())
    {
        object[] attrs = item.GetCustomAttributes(true);
        if (attrs.Length > 0 && attrs[0] is UserAttribute)
        {
            UserAttribute user = attrs[0] as UserAttribute;
            dt.Columns.Add(user.ChineseName);
            dic.Add(user.ChineseName, item.Name);
        }
        else
            dt.Columns.Add(item.Name);
    }

    //循环存储
    foreach (var item in list)
    {
        //新加行
        DataRow value = dt.NewRow();

        //根据DataTable中的值,进行对应的赋值
        foreach (DataColumn dtColumn in dt.Columns)
        {
            int i = dt.Columns.IndexOf(dtColumn);
            string cloumnName = dtColumn.ColumnName;
            if (dic.ContainsKey(cloumnName))
            {
                cloumnName = dic[cloumnName];
            }

            //基元元素,直接复制,对象类型等,进行序列化
            if (value.GetType().IsPrimitive)
            {
                value[i] = item.GetType().GetProperty(cloumnName).GetValue(item);
            }
            else
            {
                value[i] = JsonConvert.SerializeObject(item.GetType().GetProperty(cloumnName).GetValue(item));
            }
        }
        dt.Rows.Add(value);
    }

    return dt;
}

三、DataGridView 的用法

1.绑定数据

绑定数据在上面的案例中用了多次,就一句,将控件的 DataSource 绑定 DataTable 即可。

dataGridView1.DataSource = dt;

这里能绑定的不只是  DataTable 类型,DataSet,DataView,ArrayList,Dictionary,List  都是可以的,这里就不一一展示了。

2.获取绑定的数据源

可以将绑定的数据转换为绑定之前的类型,如下

 DataTable dataTable = (dataGridView1.DataSource as DataTable);

目前测试 DataTable 类型是没有问题的

3.获取 / 设置 选中单元格的数据

先给 dataGridView1 控件添加一个事件 CellClick 

代码

private void dataGridView1_CellClick(object sender, DataGridViewCellEventArgs e)
{
    //当前的行数
    int selectRowIndex = dataGridView1.CurrentRow.Index;
    //当前的列数
    int selectColumnIndex = dataGridView1.CurrentCell.ColumnIndex;

    DataTable dataTable = (dataGridView1.DataSource as DataTable);
    int rowLen = dataTable.Rows.Count;
    if (selectRowIndex >= rowLen) return;

    Console.WriteLine("当前选中行:{0},选中的列:{1}", selectRowIndex, selectColumnIndex);
}

运行后,点击最后一行,最后一列

控制台输出

 

由于绑定数据后,会自动添加一行,这里点击空白行,就会超出 DataTable 的行数,不加判断的话就会报错,这里需要注意下。

有了行和列的索引,获取值就比较简单了,直接获取 DataTable 的值就好了

object obj = dataTable.Rows[selectRowIndex][selectColumnIndex];
Console.WriteLine("value:{0}", obj);

设置它的值也是通用的道理。

4.设置单元格的宽高

宽高的自适应

//根据数据内容自动调整列宽
dataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCellsExceptHeader;
//根据数据内容自动调整行高
dataGridView1.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.AllCellsExceptHeaders; 

根据第二章的例子,效果

系统自动去掉了空白的部分,这看起来特别拥挤,还不如手动设置宽度。

手动设置列宽的写法,这里的0,1,2,3 是列的索引

dataGridView1.Columns[0].Width = 100;
dataGridView1.Columns[1].Width = 100;
dataGridView1.Columns[2].Width = 200;
dataGridView1.Columns[3].Width = 150;

结束

如果这个帖子对你有所帮助,欢迎 关注 + 点赞 + 留言,谢谢!

end

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

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

相关文章

记录好项目D16

记录好项目 你好呀&#xff0c;这里是我专门记录一下从某些地方收集起来的项目&#xff0c;对项目修改&#xff0c;进行添砖加瓦&#xff0c;变成自己的闪亮项目。修修补补也可以成为毕设哦 本次的项目是个电影购票系统 一、系统介绍 前台 普通用户注册、登录、注销 用户…

Redis哨兵——单机安装部署

Redis哨兵——单机安装部署 目录 主从配置&#xff1a; 部署redis哨兵&#xff1a; 结 果 验 证&#xff1a; 主从配置&#xff1a; 1.安装epel源&#xff1a;yum install epel-release -y 2.安装软件&#xff1a;yum install redis -y 3.新建文件夹便于验证&#xff1a;m…

DAY31:回溯算法(六):子集+子集Ⅱ+递增子序列(经典子集问题)

78.子集 给你一个整数数组 nums &#xff0c;数组中的元素 互不相同 。返回该数组所有可能的子集&#xff08;幂集&#xff09;。 解集 不能 包含重复的子集。你可以按 任意顺序 返回解集。 示例1&#xff1a; 输入&#xff1a;nums [1,2,3] 输出&#xff1a;[[],[1],[2],…

Label,RC,HPA

上面简单说了一下 pod 的基本知识点&#xff0c;待到后面会使用到 pod 的一些高阶知识点的时候&#xff0c;还可以再细细琢磨底层原理 我们接着继续学习 Lable &#xff0c; RC&#xff0c;HPA 的相关知识点 Label 是什么&#xff1f; label 就是标签&#xff0c;例如之前我们…

Redis进阶 - Redis哨兵

原文首更地址&#xff0c;阅读效果更佳&#xff01; Redis进阶 - Redis哨兵 | CoderMast编程桅杆https://www.codermast.com/database/redis/redis-advance-sentinel.html 思考 slave 节点宕机恢复以后可以找 master 节点同步数据&#xff0c;那么 master 节点宕机怎么办&am…

Vue事件捕获和事件冒泡

什么是事件&#xff1f; 当一个HTML元素产生一个事件时 该事件会在元素节点与根节点之间的路径传播&#xff0c; 路径所经过的节点都会收到该事件&#xff0c;这个传播的过程叫做DOM事件流 什么是事件捕获&#xff1f;(网景) 事件捕获&#xff1a;事件捕获会从document开始触…

神经网络如何入门?

推荐《Python神经网络编程》这本入门书。豆瓣评分9.2。 如果你可以进行加、减、乘、除运算&#xff0c;那么你就可以制作自己的神经网络。我们使用的最困难运算是梯度演算&#xff08;gradient calculus&#xff09;&#xff0c;但是&#xff0c;我们会对这一概念加以说明&…

基于Java+Springboot+Vue的校园爱心捐赠互助管理系统设计和实现

博主介绍&#xff1a;擅长Java、微信小程序、Python、Android等&#xff0c;专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;&#x1f3fb; 不然下次找不到哟 Java项目精品实战案例…

Android Studio 找不到 uploadArchives 入口

在4.2之前版本的 Android Studio 中想要module 打包arr&#xff0c;上传Maven 我们只需要 在对应module的build.gradle文件顶部添加 apply plugin: maven然后每一次修改记得要修改版本号&#xff0c;相同版本号提交失败&#xff0c;是不会覆盖的 defaultConfig {......versi…

GitLab+Jenkins实现持续集成自动化测试

一、Jenkins和GitLab互相关联 1、在Jenkins设置gitlab的认证。 1)复制gitlab->clone with HTTP 的URL 如果你想学习接口自动化测试&#xff0c;我这边给你推荐一套视频&#xff0c;这个视频可以说是B站播放全网第一的接口自动化测试教程&#xff0c;同时在线人数到达1000人…

Python3.7源码编译

1.下载Python3.7.0源码 git clone https://github.com/python/cpython.git git checkout v3.7.0wget https://www.python.org/ftp/python/3.7.0/Python-3.7.0.tar.xz源码目录结构如下所示&#xff1a; &#xff08;1&#xff09;Include目录&#xff1a;包含Python提供的所有…

反射来命令执行存在的一些问题

一.利用Runtime进行反射 java.lang.Runtime.getRuntime().exec("")若使用该paylaod&#xff0c;比如若依利用点如下&#xff1a; Object bean Class.forName(beanName).newInstance(); invokeMethod(bean, methodName, methodParams)想要通过Class.forName(beanNa…

2023年软考成绩查询方式有变,成绩快出来了!

2023年软考成绩查询方式有变化&#xff0c;准考证不再作为成绩查询凭证使用。以前的成绩查询方式是考生可以凭准考证或者证件号查询&#xff0c;2023年则取消准考证方式&#xff0c;改为考生必须先登录自己的账号&#xff0c;再凭登录账户的注册证件号查询考试成绩。 那为什么…

psd 2

而 P X ( ω ) P_{X}(\omega) PX​(ω)则是随机信号在该&#xff08;角&#xff09;频率处平均具有的能量

《论文阅读》DiaASQ:基于会话方面的情感四重分析的基准 ACL2023

《论文阅读》DiaASQ : A Benchmark of Conversational Aspect-based Sentiment Quadruple Analysis 前言相关知识Aspect-based Sentiment Analysis简介数据集基线模型损失函数总结前言 你是否也对于理解论文存在困惑? 你是否也像我之前搜索论文解读,得到只是中文翻译的解读…

C++学习 运算符

运算符 执行代码的运算。 种类 算数运算符 用于四则运算。 #include <iostream> using namespace std; int main() // 除了cout那行代码外&#xff0c;所有C程序都要写那些默认行 -endl进行换行 // 格式化代码 ctrlk ctrlf {int a 11;int b 3;int c 0;double d 9.17…

绘制原型图xstar简介

文章目录 1. 文章引言2. xstar的安装3. xstar的元件库4. xstar的下载地址 1. 文章引言 最近在学习原型图&#xff0c;针对画原型图的工具&#xff0c;反复对比墨刀、Axure、xiaopiu后&#xff0c;最终选择了Axure。 同时也看到另一款&#xff0c;绘制原型图的工具&#xff0c;…

自学网安学习心得/路线规划

趁着今天下班&#xff0c;我花了几个小时整理了下&#xff0c;非常不易&#xff0c;希望大家可以点赞收藏支持一波&#xff0c;谢谢。 我的经历&#xff1a; 我 19 年毕业&#xff0c;大学专业是物联网工程&#xff0c;我相信很多人在象牙塔里都很迷茫&#xff0c;到了大三大…

你知道奶奶攻击吗?

AIGC内容安全 1. 来自奶奶的溺爱2. 无所不能的奶奶3. 亡羊补牢&#xff0c;为时未晚&#xff1f;4. 运筹帷幄&#xff0c;用魔法打败魔法 1. 来自奶奶的溺爱 ChatGPT本身具有情感吗&#xff0c;这很难判断。但不管本身是否具有真正的情感&#xff0c;但ChatGPT却容易被“情感”…

ubuntu22.04安装使用 protobuf 23.3静态库

https://github.com/protocolbuffers/protobuf/ 下载最新的release版本&#xff0c;23.3 必须需要依赖的第三方库 abseil&#xff0c;utf8_range mkdir build cd build cmake -DCMAKE_BUILD_TYPEDEBUG -DCMAKE_INSTALL_PREFIX/usr/local -Dprotobuf_BUILD_SHARED_LIBSOFF…