Тема: cтворення програмного проекта простої бази даних «Учні» з даними про прізвище, ім'я, успішність, забезпечення виведення даних про учнів за зазначиними критеріями.
Мета: навчити основам роботи з базами даних SQL з використанням мови програмування Java.
Учні повинні знати:
Учні повинні мати уявлення про можливості комплексу Java + MySQL.
Учні повинні вміти:
Обладнання: комп'ютери зі встановленими ОС, середовищем Netbeans для програмування мовою Java, LAMP або XAMPP.
Структура уроку
Примітка. Цей урок проводять лише після успішного опанування матеріалом уроків щодо вивчення SQL і виконання усіх його практичних завдань.
Хід уроку
1. Організаційний момент
Вітання з класом. Перевірка присутності і готовності учнів до уроку.
2. Актуалізація опорних знань
Дати відповідь на питання і порівняти з очікуваним.
3. Вивчення нового матеріалу
Під'єднання бази даних і здійснення запиту мовою SQL мовою Java здійснюють за допомогою:
Для ОС Linux Mint 19 після встановлення файл JAR можна виявити за адресою /usr/share/java/mysql-connector-java-8.0.28.jar (тут замість номера версії 8.0.28 може бути інший номер). Файл JAR можна залишити на місці встановлення або перенести у довільне інше місце. Наприклад, у теку проєкту.
У будь-якому випадку встановлений файл JAR необхідно приєднати до проєкту, що використовує SQL. У середовищі Netbeans це можна зробити таким чином:
вкликати контекстне меню бібліотек проєкту Libraries натисканням правої кнопки миші і вибрати ADD JAR/Folder...;
у вікні діалогу ADD JAR/Folder вказати розташування файлу і натиснути кнопку Open.
Розглянемо випадок, коли попередньо виконано такі вказівки MySQL.
SET collation_connection = 'utf8_unicode_ci'; CREATE DATABASE school; ALTER DATABASE school CHARACTER SET utf8 COLLATE utf8_unicode_ci; USE school; SOURCE structure.sql; SOURCE data.sql;
Примітка. Дія всіх вказівок з CHARACTER SET utf8 COLLATE utf8_unicode_ci спрямована на уникнення винятків, породжених конфліктами різних схем упорядкування й порівняння.
У цьому випадку програма мовою Java може мати такий вигляд
package work; import java.sql.*; // під'єднання бібліотеки підпрограм роботи з SQL import java.util.*; class Work { public static void main(String args[]) { try { Class.forName("com.mysql.cj.jdbc.Driver"); // завантаження драйвера Connection con = DriverManager.getConnection // створення сполучення з базою даних ("jdbc:mysql://localhost:3306/school", // school - назва бази даних "root", // обліковий запис користувача базами даних "!@#123Qwe" // пароль ); Statement stmt=con.createStatement(); ResultSet rs=stmt.executeQuery("SELECT * FROM pupils WHERE form = '11Б';"); while (rs.next()) System.out.println (rs.getString(1)+" "+rs.getString(2)+" " +rs.getString(3)+" "+rs.getString(4)); con.close(); } catch(Exception e) {System.out.println("Отримано виняток "+e);} } }
з таким виведенням у консоль.
ЛИСЕНКО ДМИТРО 11Б 113 РУДЕНКО ОЛЕГ 11Б 114 САВЧЕНКО ВАЛЕРІЙ 11Б 115 ПЕТРЕНКО ЛЕОНІД 11Б 116 ШУЛЬГА ГАЛИНА 11Б 117 РАДЧЕНКО ТЕТЯНА 11Б 118 КОРОЛЬ НАДІЯ 11Б 119 ОСТАПЕНКО ЛЮДМИЛА 11Б 120
Інколи під'єднання неможливе внаслідок використання кодування UTF-8 чи роботи у різних часових поясах. У цьому випадку радять перший аргумент методу getConnection задавати таким рядком тексту.
"jdbc:mysql://localhost:3306/school?autoReconnect=true&useSSL=false&useUnicode=yes&characterEncoding=UTF-8"
Клас ResultSet підтримує вказівник на поточний рядок даних. Спочатку вказівник розташовано перед першим рядком.
Метод next класу ResultSet переміщує вказівник до наступного рядка і повертає false, коли пройдено всі рядки. Цей метод зручно використовувати в циклі while для перебору отриманих даних.
Вказівник ResultSet рухається лише в одному напрямку — уперед. Таким чином, можна пройти його лише один раз і лише від першого до останнього рядка.
Клас ResultSet надає методи get* (getBoolean, getLong, getString і так далі) для отримання значень у стовпчиках поточного рядка. Значення можна отримати, вказавши або номер стовпчика (їх нумерують від 1), або назву стовпчика.
Для методів get* драйвер JDBC намагається перетворити дані бази у тип Java, зазначений у методі get* (замість *), і повертає відповідне значення Java. Специфікація JDBC містить таблицю, що показує допустимі відображення типів SQL у типи Java, які можуть використовувати методи ResultSet.
Назви стовпчиків, які використовуються як вхідні дані для методів get*, не чутливі до регістру. Коли метод get* викликають з назвою стовпчка, а кілька стовпчиків мають однакові назви, буде повернуто значення у першому такому стовпчику. Опція назви стовпчика призначена для використання, коли назви стовпчиків використано в запиті SQL, який створив набір результатів. Для стовпчиків, які не названі явно в запиті, найкраще використовувати номери стовпчиків.
Запит SELECT при наявності предствника Statement здійснюють методом executeQuery("...").
Оновлення даних у базі даних здійснюють методом executeUpdate(...).
Якщо заздалегідь не відомо, вказівка SQL буде SELECT чи UPDATE/INSERT, то використовують метод execute(...). Цей метод поверне true, якщо запит SQL був SELECT, або false, якщо це був UPDATE, INSERT або DELETE.
Якщо метод execute(...) використав запит SELECT, результат отримують методом getResultSet().
Якщо метод execute(...) використав вказівку UPDATE, INSERT або DELETE, кількість відповідних рядків отримують, застосувавши метод getUpdateCount() до представника Statement.
Існує можливість отримати дані про властивості баз даних, таблиць та їхніх складових — див. стислий опис або детальну документацію JDK. Навіть не заглядаючи у ці документи, у практичній роботі можна використати вказівки такого вигляду:
ResultSet rs = st.executeQuery(s); int n = rs.getMetaData().getColumnCount();
Тут першою вказівкою отримано для st — представника класу Statement — таблицю результатів rs — представник класу ResultSet — для запиту, поданого рядком s (тип String). Другою вказівкою отримано кількість стовпчиків цієї таблиці результатів. Це зручно для виведення усіх результатів запиту за умови, коли наперед невідомо кількість стовпчиків цієї таблиці результатів. Або при введенні результатів запитів з різною кількістю стовпчиків таблиці результатів і небажанні відстежувати цю кількість та збільшувати код при врахуванні кожного конкретного випадку. Таке зручно зробити, наприклад, при виконанні завдання 2 практичної роботи.
У поданій вище програмі використано конструкція try-catch-finally для опрацювання винятків.
Виняток — це проблема (помилка), що виникає під час виконання програми. Винятки можуть виникати у багатьох випадках, наприклад: користувач увів некоректні дані, файл, до якого звертається програма, не знайдено, мережеве з'єднання з сервером було втрачено під час передавання даних тощо.
Опрацювання виняткових ситуацій (exception handling) — механізм мов програмування, призначений для опису реакції програми на помилки часу виконання й інші можливі проблеми (виключення), які можуть виникнути при виконанні програми і призводять до неможливості подальшої відпрацювання програмою її основного алгоритму.
У Java є декілька ключових слів для роботи з винятками (після тире вказано, для позначення чого використовують відповідне слово):
try — початок блоку коду, який потенційно може привести до помилки;
catch — початок блоку коду, призначеного для перехоплення й опрацювання винятків;
finally — початок додаткового блоку коду, розташованого після останнього блоку catch. Керування зазвичай буде передано у блок finally у будь-якому випадку.
4. Інструктаж з ТБ
5. Закріплення вивченого матеріалу
На початку виконання завдань середовище MySQL/MariaDB повинне бути активним і не містити бази даних school. При виконанні завдань використати демонстраційні розв'язання a, b, c завдань уроку 1 щодо SQL.
Завдання 1. Створити програму мовою Java, яка засобами SQL:
створить базу даних school;
виконає запити створення структури й наповнення таблиць бази даних school згідно з вказівками, записаними у файлах
structure.txt і
data.txt теки проєкту.
Примітка. Вказівка SOURCE є лише вказівкою MySQL, а не SQL, тому нею скористатися буде неможливо. Радимо скористатися програмою попереписування вмісту файлу рядками, щоб запозичити потрібні частини для склеювання всіх вказівок та їхніх частин в один рядок з наступним поділом на рядки методом split(";");
виведе у консоль назви усіх наявних баз даних;
для усіх наявних таблиць бази даних school виведе у консоль назви цих таблиць і результати запиту щодо їхньої структури у вигляді таблиці такого самого вигляду, як у створеної у середовищі MySQL:
заголовок таблиці ввести такими вказівками:
System.out.println("┌──────────────┬─────────────────────┬──────┬──────┬─────────┬───────┐"); System.out.printf( "│ %-12.12s │ %-19.19s │ %-4.4s │ %-4.4s │ %-7.7s │ %-5.5s │\n", "Field", "Type", "Null", "Key", "Default", "Extra"); System.out.println("├──────────────┼─────────────────────┼──────┼──────┼─────────┼───────┤");
System.out.printf("│ %-12.12s │ %-19.19s │ %-4.4s │ %-4.4s │ %-7.7s │ %-5.5s │\n", r.getString(1),r.getString(2),r.getString(3),r.getString(4),r.getString(5),r.getString(6));
де r — представник класу ResultSet, що містить відповідь на запит щодо структури певної таблиці бази даних school;
System.out.println("└──────────────┴─────────────────────┴──────┴──────┴─────────┴───────┘");;
Порівняти з очікуваними виведенням і кодом.
Завдання 2. Використовуючи попередньо апробований код SQL, створити програму мовою Java для виведення у консоль у вигляді асоціативних масивів таких даних:
всі поля з таблиці pupils про учнів 11Б класу (поле form);
всі поля з таблиці classroom про аудиторії корпусу A (птоле building, латиниця), ємність яких (поле capacity) менше 24 і більше від 16 (2 варіанти);
з таблиці pupils про прізвище (поле sename) та ім'я (поле name) усіх тих записів, у яких прізвище закінчується на 'УК';
з таблиці pupils про прізвище (поле sename) та ім'я (поле name) усіх тих записів, у яких ім'я (поле name) 'Андрій' або 'Григорій';
з таблиці pupils про загальну кількість учнів;
з таблиці tea chers про категорії (поле quality) та кількість учителів цієї категорії;
з таблиці teachers про категорії (поле quality) та кількість учителів цієї категорії, що перевищує 1;
з таблиці marks про прізвище (поле sename) й оцінку (поле mark) за день 2020-09-24 у порядку зростання оцінки;
з таблиці marks про прізвище (поле sename) й оцінку (поле mark) за день 2020-09-24 у порядку спадання оцінки;
з таблиці marks про прізвище (поле sename) й оцінку (поле mark) за день 2020-09-24 у порядку спадання оцінки лише тих, хто посів 4, 5 і 6 місце у цьому списку з підписами стовпчиків 'Прізвище' й 'Оцінка';
з таблиці courses список всіх дисциплін (поле course) і відповідну інформацію про кафедри з таблиці department у режимах;
Виконати запити й порівняти з очікуваними виведенням і кодом мовою Java.
Завдання 3. Використовуючи попередньо апробований код SQL, створити програму мовою Java для такого:
створити віртуальну таблицю own_view усіх полів усіх записів таблиці marks, у яких оцінка (поле mark) менша ніж 7;
вивести у консоль у вигляді асоціативних масивів даних own_view.
Виконати запити й порівняти з очікуваними виведенням і кодом.
Завдання 4. Використовуючи попередньо апробований код SQL, створити програму мовою Java для такого:
Виконати запити й порівняти з очікуваними виведенням і кодом.
6. Підбиття підсумків уроку
Дати відповідь на питання і порівняти з очікуваним.
Виставлення оцінок.
7. Домашнє завдання
У разі потреби доробити завдання. Вивчити систаксис під'єднання бази даних і здійснення запиту мовою SQL з програми мовою Java. Написати програму мовою Java, яка зчитуватиме з клавіатури й виконуватиме запити SQL до тих пір, поки не буде введено порожній рядок.
Текст упорядкував Олександр Рудик.