gitee项目地址(觉得有用的道友star一下,谢谢)
一、数据库操作
建立数据库结构
1:新建一个数据库
1:打开 数据库管理软件 navicat/SQLoya
2:创建连接
3:选择连接右键新建数据库
4:展开数据库
5:右键新建表
2:表中数据
唯一的ID:对这个表的标识 类似身份证 唯一。
id:一般我们都会让它作为主键(非空、自增)
3:填充表中数据
新建表的时候: 每个字段都有一个类型
我们填充数据的时候:要根据类型填充数据
int:整数 如:1、2、3、…
varchar:字符串(必须指定长度) 如:‘呆呆’、‘西门吹雪’、…
表结构展示
对数据的基本操作(添加 修改 删除 查询)
现在表中添加数据,然后我们展示列表并查询
1:新增
语法:INSEST INTO + 表名 (字段名1,字段名2,字段3...) VALUES(列表1,列表2,...)
返回值:受影响的行(执行增删改的时候,都会返回受影响的数据)
新增一个学生 由于sid自增 我们每次添加数据不需要添加主键;因为sid 会自动添加。
INSERT INTO student (sname, sage) VALUES("周芷若", 19)
新增多条数据
INSERT INTO student (sname, sage) VALUES('周一', 18),('周二', 19),('周三', 20)
2:修改
语法:UPDATE + 表名 set 列名 = '新的数据' where 条件
把id为1的人名字 改成张三
update student set sname='张三' where sid=1
把周一的名字 改成 周五
update student set sname='周日' where sname='周一'
3:删除
语法:DELETE from 表名 + WHERE 条件
删除学号为1的学生
DELETE FROM student WHERE sid = 1
在真正的开发中,删除并不是物理删除 而是逻辑删除(即用一个变量表示是否被删除)
4:查询 单表、多表的查询
语法:SELECT <要查询的字段 sage/sid/全部(*)> from + 表名 where 条件
查询所有的学生信息(表中所有列)
SELECT * FROM student
查询学生年龄 和 姓名
SELECT sname, sage FROM student
条件查询 查询出来年龄是18 的人的名称
SELECT sname FROM student WHERE sage=18
多个条件 查询年龄是18 而且 姓名是周二的人的所有信息
SELECT * FROM student WHERE sage=18 AND sname='周二'
模糊查询 查询所有名字里带周
SELECT * FROM student WHERE sname LIKE '%周%'
为什么需要创建关联表?
当我们执行班级操作时,如果我们把班级放在学生表中可能会操作不了。
比如:三个2020班级的学生,查询到数据重复,再比如新增2025班级,但是这个时候还没有学生在2025班级,无法操作学生表怎么办。这个时候我们可以考虑:使用关联表,新建一个班级表。
C# WinForm和数据库结合操作
获取数据框的值
// 根据组件的属性name获取 输入框(TextBox)里面的数据
// this:当前窗口使用 name:属性名 Text:文本
string sname = this.sname.Text;
string sage = this.sage.Text;
新增数据(连接数据库+执行SQL语句)
private void button1_Click(object sender, EventArgs e)
{
// 根据组件的属性name获取 输入框(TextBox)里面的数据
// this:当前窗口使用 name:属性名 Text:文本
string sname = this.sname.Text;
string sage = this.sage.Text;
// 连接数据库的操作
// 1: 声明一个数据源 目的:找到我的收据库
/*
* server:服务 localhost/127.0.0.1(本地)
* port:端口号 MySQL数据库的端口号就是3306 所以契合
* database:数据库 声明我要用哪个数据库
* uid:数据库用户名
* pwd:数据库的密码
*/
string url = "server=127.0.0.1; port=3306;database=csharp;uid=root;pwd=root";
// 2:创建 链接
// 注意 : 我们链接数据库的时候需要引用 mysql.data.dll
MySqlConnection con = new MySqlConnection(url);
// 3: 打开数据库
con.Open();
// MessageBox.Show("打开数据库");
//4: 声明一个sql
// 既然 数据库已经打开了 我是不是可以对数据库进行一些操作
// 注意:SQL字符串需要用引号括着
string sql = string.Format("INSERT INTO student (sname,sage) VALUES('{0}', {1})", sname, sage);
// 5:创建一个操作 sql的对象(MySqlCommand)
MySqlCommand com = new MySqlCommand(sql, con);
// 6: 执行结束之后 返回一个结果 整数 int
// ExecuteNonQuery: 执行增删改的 新增 修改 删除
int i= com.ExecuteNonQuery();
if (i > 0) {
//类似于js中的console.log()提示框
MessageBox.Show("新增成功");
} else {
MessageBox.Show("失败");
}
}
工具类——DBhelp封装
private static String connStr = "server=localhost;database=csharp;uid=root;pwd=root;charset=utf8;sslmode=none";
//声明链接
public static MySqlConnection GetConn()
{
MySqlConnection conn = new MySqlConnection(connStr);//
if (conn.State == ConnectionState.Closed) conn.Open();//判断是否关闭 打开链接
return conn;//返回链接
}
public static void CloseAll(MySqlConnection conn)
{
if (conn == null) return;
if (conn.State == ConnectionState.Open || conn.State == ConnectionState.Connecting)
//判断
conn.Close();//关闭链接
}
public static int ExecuteNonQuery(string sql) // 增删改 封装 返回受影响的行
{
MySqlConnection conn = null;
int result; //提前设置一个返回值
try
{
conn = GetConn();//获取链接
MySqlCommand cmd = new MySqlCommand(sql, conn);
result = cmd.ExecuteNonQuery();//执行sql 并返回受影响的行的个数
}
finally
{
CloseAll(conn);
}
return result;
}
public static MySqlDataReader executeQuery(string sql) //查询
{
MySqlDataReader res = null;
MySqlConnection conn = null;
try
{
MySqlConnection conn1 = GetConn();
MySqlCommand cmd = new MySqlCommand(sql, conn1);
res = cmd.ExecuteReader();
}
finally
{
CloseAll(conn);
}
return res;
}
优化新增数据(通过工具类)
private void button1_Click(object sender, EventArgs e)
{
string sname = this.sname.Text;
string sage = this.sage.Text;
string sql = string.Format("INSERT INTO student (sname,sage) VALUES('{0}', {1})", sname, sage);
int i = DBhelp.ExecuteNonQuery(sql);
if (i > 0) {
MessageBox.Show("新增成功");
} else {
MessageBox.Show("失败");
}
}
二、多表操作
1:为什么执行多表操作
如图所示:我进行班级操作的时候,此时是没办法操作,周一、周三两人退学,那么2020这个班级就不复存在了。无法操作班级2020。
2:解决方案(创建关联表,操作多表数据)
3:操作数据
多表操作一般情况下只使用查询操作
多表操作:as(起别名) 此时有问题 没有班级的学生(即gid为NULL)难道 不配被查询嘛?
SELECT * FROM student AS a, grade AS b WHERE a.gid = b.gid
高级多表查询:INNER JOIN 内连接 LEFT JOIN 左连接(以左表为主表查询 如果右表没有与之匹配的数据就用null来代替)
SELECT * FROM student a LEFT JOIN grade b ON a.gid = b.gid
三、登录操作
// 重置按钮:清空输入框里面的值
this.textBox1.Text = "";
this.textBox2.Text = "";
this.radioButton1.Checked = true;
this.radioButton2.Checked = false;
// 点击登录
string password = null;
if (radioButton1.Checked == true)
{
// string.Format格式化字符串
string sql = string.Format(@"SELECT password FROM student WHERE username='{0}'", textBox1.Text);
// 执行sql 返回一个结果集
MySqlDataReader res = DBhelp.executeQuery(sql);
// 一行一行 往下读
while (res.Read())
{
password = res["password"].ToString();
}
if (password.Equals(textBox2.Text))
{
MessageBox.Show("登录成功");
} else
{
MessageBox.Show("账号密码错误");
}
} else
{
string sql = string.Format(@"SELECT password FROM teacher WHERE username='{0}'", textBox1.Text);
MySqlDataReader res = DBhelp.executeQuery(sql);
while (res.Read())
{
password = res["password"].ToString();
}
if (password.Equals(textBox2.Text))
{
MessageBox.Show("登录成功");
}
else
{
MessageBox.Show("账号密码失败");
}
}
四:菜单操作
1:显示菜单
// 创建 学生菜单的实例
StudentMenu stu = new StudentMenu();
// 这个是展示窗口
stu.Show();
// 展示窗体之后,把前一个打开的窗体关闭
this.Hide();
2:ListView控件的使用
选择编辑行
修改ListView框的属性
五:回显数据
string gid = null; //班级号
StuList s = null; //已经打开就不再new了
private void AddStudent_Load(object sender, EventArgs e)
{
string sql = string.Format(@"SELECT * FROM grade");
MySqlDataReader res = DBhelp.executeQuery(sql);
while (res.Read())
{
string gname = res["gname"].ToString();
this.comboBox1.Items.Add(gname);
}
// 设置下拉框初始值
comboBox1.Items.Insert(0, "请选择");
this.comboBox1.SelectedIndex = 0;
}
private void button2_Click(object sender, EventArgs e)
{
string sql = string.Format(@"insert into student (sname, sage, gid, username) values('{0}', {1}, {2}, '{3}')", textBox1.Text, textBox2.Text, gid, textBox4.Text);
int i = DBhelp.ExecuteNonQuery(sql);
if (i > 0)
{
if (s == null)
{
s = new StuList();
s.Show();
}
else
{
s.Reload();
}
DialogResult dialogResult = MessageBox.Show("新增成功,是否需要继续新增", "新增提示", MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation);
if (dialogResult == DialogResult.Yes)
{
this.TopMost = true;
}
else if (dialogResult == DialogResult.No)
{
this.Hide();
}
} else
{
MessageBox.Show("新增失败");
}
}
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
//获取gid
string sql1 = string.Format(@"SELECT * FROM grade where gname = '{0}'", comboBox1.Text);
MySqlDataReader res1 = DBhelp.executeQuery(sql1);
while (res1.Read())
{
gid = res1["gid"].ToString();
}
}
六、修改删除数据
双击图中的事件:
private void listView1_SelectedIndexChanged(object sender, EventArgs e)
{
//判断有没有选中数据,选中后回显数据
if (this.listView1.SelectedItems.Count > 0)
{
// 拿到选中数据 索引值从0开始:因为每次选中一行,所有索引值为0
ListViewItem lis = this.listView1.SelectedItems[0];
string sid = lis.Tag.ToString();
string sname = lis.Text;
// 获取子菜单
string sage = lis.SubItems[1].Text;
string gname = lis.SubItems[2].Text;
string username = lis.SubItems[3].Text;
//把拿到的数据赋值在修改框中
textBox1.Text = sname;
textBox2.Text = sage;
textBox3.Text = gname;
textBox4.Text = username;
}
}
七、页面之间的传值
转载:https://blog.csdn.net/weixin_51333606/article/details/125106720