практическая. Клиент. Этап 1
Скачать 69.01 Kb.
|
Клиент-серверное приложение с базой данных MySQL Этап 1 – настройка среды Visual Studio. создайте обычное приложение с одной формой, в обозревателе решений нажмите правой клавишей мыши по опции «Ссылки», в в открывшемся слева окне перейдите на вкладку «Обзор» после поиска выберите версию MySql.data, и нажмите «Установить». Когда вы проделаете подключение библиотеки, то в «Обозревателе решений» вы увидите новую строчку – MySql.Data. Однако для использования классов из этой библиотеки в тексте кода (в самом верху) каждого создаваемого модуля к формам Вашего приложения ещё нужно будет добавить строчку: using MySql.Data.MySqlClient; Этап первичной подготовки приложения на этом закончен. Этап 2 – подсоединимся к БД После подключения библиотеки можно уже приступать работать с са- мой базой данных MySQL. Для реализации этой задачи у Вас есть база данных – off_ВашаФамилия. Возьмем для примера две связанные таблицы отделы – k_dept, сотрудники – k_staft, связанных отношением «один-ко-многим» (statf_num – dept_num): Чтобы подключить программу на C# к сетевой базе данных, нужны такие па- раметры: адрес (хостинг) БД в сети, идентификатор (имя) БД, имя пользователя, пароль пользователя кодировка (это необязательно). Разместите на форме кнопку, сгенерируйте для неё обработчик события «клик мышкой» и в нём создайте объект подключения к БД с такими пара- метрами: MySqlConnectionStringBuilder db; db = new MySqlConnectionStringBuilder(); db.Server = "localhost"; // хостинг БД db.Database = "off_ВашаФамилия"; // Имя БД db.UserID = "root"; // Имя пользователя БД db.Password = "galina43"; // Пароль пользователя БД db.CharacterSet = "utf8"; // Кодировка Базы Данных и сгенерируйте строку подключения: MySqlConnection conn; conn = new MySqlConnection(db.ConnectionString); Чтобы убедиться в корректности подключения, попытаемся открыть БД и уведомим пользователя о результатах. try { conn.Open(); MessageBox.Show("Подключение к БД установлено"); } catch (Exception ex) { MessageBox.Show("Проблемы с подключением к БД \n\r" + ex.ToString()); } Все эти строчки следует разместить в обработчике события клик мыши по клавише: private void button1_Click(object sender, EventArgs e) Апробируйте работу программы по подключению. Обратите внимание, что должно быть в наличии подключение к сети интернет и, после нажатия на клавишу Button1, подключение проходит не мгновенно, а занимает пару секунд. Если удалось установить подключение, то можно подумать уже о начале работы с данными. Если не удалось подключиться, сохраните результат Вашего неудачного подключения. Далее проверьте правильность заполнения Вашей программы. Код первой части программы представлен в Приложении 1. Этап 3. Считываем данные и отображаем их на форме. Вспомните, что некоторые переменные следует объявлять, как глобальные, чтобы они были доступны в каждой из функций модуля, поэтому две ранее объявленные переменные (db и conn) перенесите и две новые напишите в самом начале объявления класса формы, а процесс настройки параметров подключения БД перенесите в обработчик загрузки формы: public partial class Form1 : Form { MySqlConnectionStringBuilder db; MySqlConnection conn; MySqlCommand cmd; string sql; public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { db = new MySqlConnectionStringBuilder(); db.Server = "mysql95.1gb.ru"; // хостинг БД db.Database = "gb_psis"; // Имя БД db.UserID = "gb_psis"; // Имя пользователя БД db.Password = "ca8484adc89a"; // Пароль пользователя БД db.CharacterSet = "utf8"; // Кодировка Базы Данных conn = new MySqlConnection(db.ConnectionString); } Далее создайте на форме вторую кнопку и сгенерируйте для неё обра- ботчик (клик мышкой). Давайте пока в качестве первой пробы просто в тек- стовое поле (не забудьте установить MultiLine=True) выведем список отделов: private void button2_Click(object sender, EventArgs e) { sql = "SELECT dept_full_name FROM k_dept”; cmd = new MySqlCommand(sql, conn); MySqlDataReader reader = cmd.ExecuteReader(); textBox1.Clear(); while (reader.Read()) { textBox1.Text += reader[0].ToString() + Environment.NewLine; } reader.Close(); } В этом обработчике сначала мы создаём строку с SQL-командой, затем формируем из неё объект cmd для трансляции команды в БД и, с помощью метода ExecuteReader запускаем её на исполнение, результаты возвращаем в пе- ременную reader. Далее очищаем текстовое поле и в цикле читаем все записи, полученные по команде SELECT. В каждой записи может быть несколько полей (это как в одной строке таблицы), нумерация полей начинается с нуля. Какие именно поля, их количество и названия Вы сами определили в запросе: sql = "SELECT dept_full_name FROM k_dept”; Итак, у нас есть только одно поле – dept_full_name, к нему можно обратиться как по порядковому номеру, так и по имени: textBox1.Text += reader["dept_full_name "].ToString() + Environment.NewLine; Попробуйте оба варианта. В исследуемой таблице (k_dept) есть ещё один столбец – dept_num, он нужен для того, чтобы в связной таблице хранить не полное наименование отделов, а только ссылки на них. Но сейчас Вы можете попробовать немного доработать свою программу и вывести в текстовое поле оба столбца таблицы, для чего в запросе нужны изменения: sql = "SELECT dept_num, dept_full_name FROM k_dept"; и в организации вывода, например, так: while (reader.Read()) { textBox1.Text += reader["dept_num"].ToString() + '\t' + reader["dept_full_name"].ToString() + Environment.NewLine; } Если, в дальнейшем, Вы захотите организовать вывод сотрудников из определённой группы по выбору пользователя, то имеет смысл список отделов загружать в подходящий для этой цели визуальный компонент, например, в ComboBox (добавьте его на форму). Перепишите обработчик второй клавиши следующим образом: sql = "SELECT dept_full_name FROM k_dept"; cmd = new MySqlCommand(sql, conn); MySqlDataReader reader = cmd.ExecuteReader(); comboBox1.Items.Clear(); while (reader.Read()) { comboBox1.Items.Add(reader["dept_full_name"].ToString()); } reader.Close(); comboBox1.Text = "Список отделов"; Теперь уже можно сделать обработчик выбора опции в выпадающем списке (comboBox1), который и будет в текстовое поле textBox1 выводить список фамилий (staff_name) из выбраннго отдела (пока номер отдела равен 1): private void comboBox1_SelectedIndexChanged(object sender, EventArgs e) { sql = "SELECT staff_name FROM k_staft WHERE staff_num = 1"; cmd = new MySqlCommand(sql, conn); MySqlDataReader reader = cmd.ExecuteReader(); textBox1.Clear(); while (reader.Read()) { textBox1.Text += reader["staff_name "].ToString() + Environment.NewLine; } reader.Close(); } Проверьте работоспособность этого кода – вполне возможно, что в текстовое поле не будет загружено ни одной фамилии, так как пользователи этой открытой БД (такие же студенты, как и Вы) могли удалить все записи из неё. Проследить это обстоятельство совсем несложно. Если программа не за- висает, работает корректно, но в текстовом поле нет записей, то внесите в программу следующие изменения – добавьте функцию получения количества записей в таблице и всамобработчик добавьтенесколькострочек: int getCount(string nameTable) { sql = "SELECT COUNT(*) FROM " + nameTable; cmd = new MySqlCommand(sql, conn); return Convert.ToInt32(cmd.ExecuteScalar().ToString()); } private void comboBox1_SelectedIndexChanged(object sender, EventArgs e) { sql = "SELECT staff_name FROM k_staft WHERE staff_num = 1"; cmd = new MySqlCommand(sql, conn); MySqlDataReader reader = cmd.ExecuteReader(); textBox1.Clear(); // тут добавка textBox1.Text += "Список отделов " + comboBox1.SelectedItem + ":"+ Environment.NewLine; // while (reader.Read()) { textBox1.Text += reader["staff_name"].ToString() + Environment.NewLine; } reader.Close(); // тут добавка: textBox1.Text += "- - -" + Environment.NewLine + "Общее кол-во сотрудников во всех отделах = " + getCount("*").ToString() + Environment.NewLine; } } Переработаем обработчик (я использую первый, более короткий вариант, но Вы можете оставить более полный вариант), вернув сначала первым запросом номер отдела по его имени, а уже затем список сотрудников выбранного отдела: private void comboBox1_SelectedIndexChanged(object sender, EventArgs e) { MySqlDataReader reader; sql = "SELECT dept_num FROM k_dept WHERE dept_full_name = " + "'" + comboBox1.SelectedItem + "'"; cmd = new MySqlCommand(sql, conn); reader = cmd.ExecuteReader(); reader.Read(); int numId = Convert.ToInt32(reader[0]); // номер отдела reader.Close(); sql = "SELECT staf_name FROM k_staff WHERE dept_num = " + numId.ToString(); cmd = new MySqlCommand(sql, conn); reader = cmd.ExecuteReader(); textBox1.Clear(); while (reader.Read()) { textBox1.Text += reader["staf_name"].ToString() + Environment.NewLine; } reader.Close(); } Это, конечно, не самое лучшее решение, но оно сделано по аналогии с предыдущими решениями и интуитивно понятно, что достаточно для первой работоспособной программы. Возможные варианты доработки таковы: когда Вы ранее загружали список отделов, то нужно вместе с ними загружать и №№ отделов, хранить их в какой-то структуре и, при необходимости, использовать (это сможете сделать и сами); можно просто сделать вложенный запрос вместо двух запросов, как было в нашем последнем обработчике, и выглядит это так: private void comboBox1_SelectedIndexChanged(object sender, EventArgs e) { MySqlDataReader reader; sql = "SELECT staf_name FROM k_staff WHERE staff = " + "(SELECT dept_num FROM k_dept WHERE dept_full_name = " + "'" + comboBox1.SelectedItem + "')"; cmd = new MySqlCommand(sql, conn); reader = cmd.ExecuteReader(); textBox1.Clear(); while (reader.Read()) { textBox1.Text += reader["staf_name"].ToString() + Environment.NewLine; } reader.Close(); } Может сложиться такая ситуация (в другой БД), при которой внутрен- ний подзапрос вернёт не одно, а несколько значений, в этом случае необхо- димо внести изменения в Ваш запрос, заменив символ сравнения (“=”) на ко- манду проверки вхождения в множество («IN»): sql = "SELECT staf_name FROM k_staff WHERE staf_num IN " + "(SELECT dept_num FROM k_dept WHERE dept_full_name = " + "'" + comboBox1.SelectedItem + "')"; Проверьте, что и для нашей БД это работает корректно, ведь множество может состоять и из одного элемента. Приложения Теперь я приведу пример всех уже готовых функций и скриншот экрана программы во время выполнения запроса, чтобы вы смогли сравнить результаты: using System; using System.Data; using System.Windows.Forms; using MySql.Data.MySqlClient; namespace beginMySQL { public partial class Form1 : Form { MySqlConnectionStringBuilder db; MySqlConnection conn; MySqlCommand cmd; string sql; public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { db = new MySqlConnectionStringBuilder(); db.Server = "mysql95.1gb.ru"; // хостинг БД db.Database = "gb_psis"; // Имя БД db.UserID = "gb_psis"; // Имя пользователя БД db.Password = "ca8484adc89a"; // Пароль пользователя БД db.CharacterSet = "utf8"; // Кодировка Базы Данных conn = new MySqlConnection(db.ConnectionString); } private void button1_Click(object sender, EventArgs e) { try { if (conn.State == ConnectionState.Closed) { conn.Open(); } MessageBox.Show("Подключение к БД установлено"); } catch (Exception ex) { MessageBox.Show("Проблемы с подключением к БД \n\r" + ex.ToString()); } } private void button2_Click(object sender, EventArgs e) { sql = "SELECT name_group FROM groups"; cmd = new MySqlCommand(sql, conn); MySqlDataReader reader = cmd.ExecuteReader(); comboBox1.Items.Clear(); while (reader.Read()) { comboBox1.Items.Add(reader["name_group"].ToString()); } reader.Close(); comboBox1.Text = "Список групп"; } int getCount(string nameTable) { sql = "SELECT COUNT(*) FROM " + nameTable; cmd = new MySqlCommand(sql, conn); return Convert.ToInt32(cmd.ExecuteScalar().ToString()); } private void comboBox1_SelectedIndexChanged(object sender, EventArgs e) { MySqlDataReader reader; sql = "SELECT name1 FROM students WHERE group_num IN " + "(SELECT id_group FROM groups WHERE name_group = " + "'" + comboBox1.SelectedItem + "')"; cmd = new MySqlCommand(sql, conn); reader = cmd.ExecuteReader(); textBox1.Clear(); textBox1.Text += "Список группы " + comboBox1.SelectedItem + ":"+ Environment.NewLine; while (reader.Read()) { textBox1.Text += reader["name1"].ToString() + Environment.NewLine; } reader.Close(); textBox1.Text += "- - -" + Environment.NewLine + "Общее кол-во студентов во всех группах = " + getCount("students").ToString() + Environment.NewLine; } private void button3_Click(object sender, EventArgs e) { sql = "INSERT INTO students (name1, name2, name3, group_num) "; sql += "VALUES(NULL, '" + textBox1.Text + "')"; cmd = new MySqlCommand(sql, conn); cmd.ExecuteNonQuery(); } } } |