Книга 1 - Начальные сведения
Книга 2 - Более профессиональный подход |
Студенческий отдел кадров База данных
Получив некоторое представление, что существуют такие замечательные структуры как коллекции, Вы
наверняка задумались: "Возможно все это здорово, только все эти данные существуют временно -
а когда программа завершится, то все исчезнет. Ну и зачем такая нужна ?" Прекрасно понимая, что работа с базами данных на сегодня является первостепенной задачей разработчики Java создали специальную технологию - JDBC (Java Database Connectivity). Она позволяет однообразно получать доступ к различным базам данных. Фактически для каждой базы данных существует специальный драйвер, который загружается и используется приложением на Java для доступа к конкретной базе. Но что самое интересное - для программиста работа с различными драйверами практически полностью одинакова, что для MS SQL Server, что для Oracle. В нашем мире хоть какой-то островок стабильности - это уже большое счастье.
Для запуска наших примеров я установил MySQL - он свободен для доступа:
MySQL 5.0
Рекомендуем: Вам надо ознакомиться с общими понятиями баз данных и
SQL (Structured Query Language) для понимания этой части.
Для самого простого уровня достаточно воспринимать базы данных, как набор таблиц, у которых есть
фиксированный набор столбцов и любой количество строк. А SQL - это
язык, который позволяет получать данные из этих таблиц и модифицировать данные в этих таблицах.
Наверняка вы все видели какие-то ведомости, даже расписывались в них. И заметили, что у них обычно
есть столбцы с какими либо наименованиями и дальше разлинованные строки, в которые вписываются
реальные данные. Так же с точки зрения прикладного программиста (т.е. большинства из нас) выглядят
и таблицы в базе данных. Только строки можно добавлять, удалять и модифицировать не зачеркивая -
думаю, что многие из вас работали с Excel - так и воспринимайте таблицы в базе данных. Кроме
этого учтите, что каждый столбец в базе имеет определенный тип данных. Чаще всего это строки
определенной длины, числа (целые, вещественные), даты. В общем-то и все.
Здесь мы рассмотрим очень простые команды SQL - чтобы просто понимать о чем буджет идти речь в дальнейшем.
Добавление записи INSERT INTO <имя_таблицы> (<имя_поля_1>, <имя_поля_2>, <имя_поля_3>, ...) VALUES (<величина_поля_1>, <величина_поля_1>, <величина_поля_3>, <величина_поля_3>, ...) Думаю, что вы уже догадались что есть что.
Причем заметим, что порядок полей не важен - главное, чтобы было соответствие между порядком
в обоих списках полей и величин. Т.е. если я что-то хочу вставить в поле (например
STUDENT_NAME), которое идет вторым, то и реальная величина должна
быть второй. INSERT INTO STUDENT_GROUP (GROUP_NAME, CURATOR, SPECIALITY) VALUES ("Первая", "Доктор Борменталь", "Делание человеков из собачек")
Редактирование записи
UPDATE <имя_таблицы> SET <имя_поля_1>=<величина_поля_1>, <имя_поля_2>=<величина_поля_2> ...
Думаю, что комментарии по именам особо не нужны. Важно отметить вот что - оператор в такой форме произведет изменения ПО ВСЕМ СТРОКАМ в таблице. Конечно же нам такого не хочется - мы хотим делать изменения только для какой-то одной записи. Давайте рассмотрим поначалу синтаксис оператора удаления и после него вернемся к нашей проблеме.
Удаление записи
DELETE FROM <имя_таблицы>
И здесь мы натолкнемся на похожую проблему - удаление будет сделано ДЛЯ ВСЕХ ЗАПИСЕЙ таблицы. Т.е. таким опертором мы удалим все данные. Для решения возникшей проблемы нам потребуется рассмотреть два понятия: Первое - это возможность добавлять условия в наши операторы. Условия позволяют указать нам то множество записей, которые мы хотим удалить или отредактировать. Также условия позволяет нам получить ограниченный набор записей, а не все. Чуть позже мы посмотрим синтаксис получения данных. Для удаления и редактирования выглядит это так: UPDATE <имя_таблицы> SET <имя_поля_1>=<величина_поля_1>, <имя_поля_2>=<величина_поля_2> ... WHERE <условия> DELETE FROM <имя_таблицы> WHERE <условия> После ключевого слово WHERE можно поставить какие-либо условия, которые указывают какие именно записи надо изменить/удалить. Условия могут записываться с помощью достаточно понятных выражений - >, <, =, >=, <=, <> (больше, меньше, равно, больши или равно, меньше или равно, не равно). Также Вы можете использовать неколько условия, соединяя их операторами AND, OR (и, или).
Второе - первичный ключ. Это поле или набор полей, которое (который) уникален
для каждой записи. Чаще всего это поле, которое имеет автоматическое увеличение. Кроме того на
такое поле накладывается условия уникальности. Т.е. две записи не могут иметь одинаковое значение
первичного поля. Много копий сломано в попытках доказать, насколько нужны искусственное введение
такого рода полей, но подавляющее большинство программистов используют их. И автор советует делать
тоже самое.
UPDATE STUDENTS SET group_id=2, educationYear=2007 WHERE student_id=10
Здесь мы для студента с идентификатором 10 установили группу 2 и год обучения в этой группе 2007. Для удаления студента используется такой синтаксис:
DELETE FROM STUDENTS WHERE student_id=10
Как Вы наверно уже догадались можно делать групповые изменения в таблице. Например мы можем удалить всех студентов и группы с ИД 2 и годом обучения 2006.
DELETE FROM STUDENTS WHERE group_id=2 AND educationYear=2006
Также можно одним оператором перевести студентов из группы с ИД 1 и с годом 2006 в группу 2 с годом 2007
UPDATE STUDENTS SET group_id=2, educationYear=2007 WHERE group_id=1 AND educationYear=2006
Выборка записей
SELECT <имя_поля_1>, <имя_поля_2>, ... FROM <таблица> WHERE <условия>
Если Вы хотите получить все записи из таблицы, то можно вместо списка полей использовать знак "*".
SELECT * FROM <таблица> WHERE <условия>
Поля в принципе могут идти в любом порядке. Хотя чаще всего они передаются в том порядке, в котором они идут в описании таблицы. Но рассчитывать на это не рекомендуется. Для примера получения списка студентов для группы с ИД 1 и годом обучения 2006 мы можем сделать выборку таким образом:
SELECT * FROM STIDENTS WHERE group_id=1 AND educationYear=2006
Также хотелось бы отметить, что одновременно с получением данных Вы можете их отсортировать с помощью команды ORDER BY. ORDER BY может сортировать как в возрастающем так и возрастающем порядке. Для этого используется модификатор DESC. SELECT * FROM STIDENTS WHERE group_id=1 AND educationYear=2006 ORDER BY group_id SELECT * FROM STIDENTS WHERE group_id=1 AND educationYear=2006 ORDER BY group_id DESC Как Вы сами понимаете (а многие из вас уже знают), что SQL гораздо более мощное средство, чем то, что я показал. Он позволяет соеденить данные из нескольких таблиц в один набор данных, причем будет соблюдать всевозможные условия такого соеденения. В общем ссылки я вам дал - разбирайтесь :). Цель моего описания - дать в минимальном размере те знания, которые понадобятся для понимания нашего приложения. Тестовые данные и установка MySQL
Для установки MySQL не надо предпринимать каких-то очень сложных действий. После запуска инсталляции
надо только обратить внимание на следующие моменты:
mysql -u root -p < students.sql DROP DATABASE IF EXISTS students; CREATE DATABASE students DEFAULT CHARACTER SET 'utf8'; USE students; create table groups ( group_id int unsigned not null auto_increment, groupName varchar(255) not null, curator varchar(255) not null, speciality varchar(255) not null, primary key (group_id) ) engine=InnoDB; create table students ( student_id int unsigned not null auto_increment, firstName varchar(255) not null, surName varchar(255) not null, patronymic varchar(255) not null, dateOfBirth date not null, sex char(1), group_id int not null, educationYear int not null, primary key (student_id) ) engine=InnoDB; set names 'utf8'; insert into groups (groupName, curator, speciality) values ('Первая', 'Доктор Борменталь', 'Создание собачек из человеков'); insert into groups (groupName, curator, speciality) values ('Вторая', 'Профессор Преображенский', 'Создание человеков из собачек'); insert into students (firstName, patronymic, surName, sex, dateOfBirth, group_id, educationYear) values ('Иван', 'Сергеевич', 'Степанов', 'М', '1990-03-20', 1, 2006); insert into students (firstName, patronymic, surName, sex, dateOfBirth, group_id, educationYear) values ('Наталья', 'Андреевна', 'Чичикова', 'Ж', '1990-06-10', 1, 2006); insert into students (firstName, patronymic, surName, sex, dateOfBirth, group_id, educationYear) values ('Виктор', 'Сидорович', 'Белов', 'М', '1990-01-10', 1, 2006); insert into students (firstName, patronymic, surName, sex, dateOfBirth, group_id, educationYear) values ('Петр', 'Викторович', 'Сушкин', 'М', '1991-03-12', 2, 2006); insert into students (firstName, patronymic, surName, sex, dateOfBirth, group_id, educationYear) values ('Вероника', 'Сергеевна', 'Ковалева', 'Ж', '1991-07-19', 2, 2006); insert into students (firstName, patronymic, surName, sex, dateOfBirth, group_id, educationYear) values ('Ирина', 'Федоровна', 'Истомина', 'Ж', '1991-04-29', 2, 2006); Как видите в конце мы использовали операторы вставки для заполнения нашей базы данных некоторыми данными. В первой части мы создавали таблицы с помощью команд CREATE TABLE. Первая строка DROP DATABASE IF EXISTS students уничтожит базу данных students, если такая существует. Здесь хотелось бы обратить внимание на строки
create table groups
(
group_id int unsigned not null auto_increment,
...
create table students
(
student_id int unsigned not null auto_increment,
Поля для ИД групп и студентов содержат понятие auto_increment.
Это значит, что данные поля не подлежат редактированию и, что очень важно, при вставке новой
записи они будут увеличивать свое значение автоматически. Т.е. каждый новый студент или группа
получат ИД без наших усилий. Что очень удобно. Работа с драйвером JDBCКаждая база данных должна отдавать свои данные наружу - пользователям. Передача данных от сервера клиентскому приложению производится по определенным правилам (определенному протоколу), который для каждого производителя может быть свой. Для того, чтобы программисту не влезать во все эти дебри производитель базы данных разрабатывает драйвера для общения со свой базой данных. Для Java это JDBC-драйвера. Самое главное, что для Java-программиста НЕ ВАЖНО, к какому серверу он подключается. Работа с драйвером будет всегда одинакова. Таким образом единственное, что может помешать легкому перенесению базы данных с SQL-сервера одного производителя на другой - это особенности самих SQL-запросов. Если же они у вас не очень сложные и подчиняются стандартам, то скорее всего перенос не будет проблематичным. Рассмотрим простой пример взаимодействия с базой данных. import java.io.FileNotFoundException; import java.io.PrintStream; import java.io.UnsupportedEncodingException; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; public class TestJDBC { public static void main(String args[]) { // Снова используем файл для вывода из-за кодировки try { System.setOut(new PrintStream("out.txt")); } catch (FileNotFoundException ex) { ex.printStackTrace(); return; } System.out.println("Copyright 2009, Anton Saburov"); Connection con = null; Statement stmt = null; ResultSet rs = null; try { Class.forName("com.mysql.jdbc.Driver"); String url = "jdbc:mysql://localhost:3306/students"; con = DriverManager.getConnection(url, "root", "root"); stmt = con.createStatement(); rs = stmt.executeQuery("SELECT * FROM students"); while (rs.next()) { String str = rs.getString(1) + ":" + rs.getString(2); printString(str); } } catch (Exception e) { e.printStackTrace(); } finally { // Эта часть позволяет нам закрыть все открытые ресуры // В противном случае возмжожны проблемы. Поэтому будьте // всегда аккуратны при работе с коннектами try { if (rs != null) { rs.close(); } if (stmt != null) { stmt.close(); } if (con != null) { con.close(); } } catch (SQLException ex) { ex.printStackTrace(); System.err.println("Error: " + ex.getMessage()); } } } // Снова используем этот метод для вывода из-за кодировки public static void printString(Object s) { try { System.out.println(new String(s.toString().getBytes("windows-1251"), "windows-1252")); } catch (UnsupportedEncodingException ex) { ex.printStackTrace(); } } }
Давайте подробно рассмотрим, что же мы делаем.
Эта строка создает запрос, который мы будем посылать на сервер Мы рассмотрели пример, когда нам необходимо получить данные. В случае, если нам надо просто произвести изменения, то для этого существует вызов executeUpdate. Подробнее о вызовах можно посмотреть в документации по Java API. Сборка данного примера не требует дополнительных библиотек и можно его собрать командой javac TestJDBC.java А вот для запуска на потребуется подключить драйвер. Обычно драйвер JDBC представляет из себя набор классов в JAR (Java Archive), который надо просто подключить через CLASSPATH. Например, если драйвер находится в файле mysql-connector-java-3.1.13-bin.jar, то командная строка для запуска будет выглядеть вот так java -cp .;mysql-connector-java-3.1.13-bin.jar TestJDBC
Теперь мы с вами изменим нашу систему получения данных - ManagementSystem.
Т.к. коннект к базе нам будет нужен постоянно, то создадим его один раз и будем использовать везде. Все
остальные команды рассмотрим прямо в коде нашего класса ManagementSystem.
Прошу обратить внимание, что у нас появились дополнения во многих методах - теперь они порождают
исключение SQLException. Student.java package students.logic; import java.text.DateFormat; import java.sql.ResultSet; import java.sql.SQLException; import java.text.Collator; import java.util.Date; import java.util.Locale; public class Student implements Comparable { private int studentId; private String firstName; private String surName; private String patronymic; private Date dateOfBirth; private char sex; private int groupId; private int educationYear; public Student(ResultSet rs) throws SQLException { setStudentId(rs.getInt(1)); setFirstName(rs.getString(2)); setPatronymic(rs.getString(3)); setSurName(rs.getString(4)); setSex(rs.getString(5).charAt(0)); setDateOfBirth(rs.getDate(6)); setGroupId(rs.getInt(7)); setEducationYear(rs.getInt(8)); } public Date getDateOfBirth() { return dateOfBirth; } public void setDateOfBirth(Date dateOfBirth) { this.dateOfBirth = dateOfBirth; } public int getEducationYear() { return educationYear; } public void setEducationYear(int educationYear) { this.educationYear = educationYear; } public int getGroupId() { return groupId; } public void setGroupId(int groupId) { this.groupId = groupId; } public int getStudentId() { return studentId; } public void setStudentId(int studentId) { this.studentId = studentId; } public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } public String getPatronymic() { return patronymic; } public void setPatronymic(String patronymic) { this.patronymic = patronymic; } public String getSurName() { return surName; } public void setSurName(String surName) { this.surName = surName; } public char getSex() { return sex; } public void setSex(char sex) { this.sex = sex; } public String toString() { return surName + " " + firstName + " " + patronymic + ", " + DateFormat.getDateInstance(DateFormat.SHORT).format(dateOfBirth) + ", Группа ИД=" + groupId + " Год:" + educationYear; } public int compareTo(Object obj) { Collator c = Collator.getInstance(new Locale("ru")); c.setStrength(Collator.PRIMARY); return c.compare(this.toString(), obj.toString()); } } Group.java package students.logic; public class Group { private int groupId; private String nameGroup; private String curator; private String speciality; public String getCurator() { return curator; } public void setCurator(String curator) { this.curator = curator; } public int getGroupId() { return groupId; } public void setGroupId(int groupId) { this.groupId = groupId; } public String getNameGroup() { return nameGroup; } public void setNameGroup(String nameGroup) { this.nameGroup = nameGroup; } public String getSpeciality() { return speciality; } public void setSpeciality(String speciality) { this.speciality = speciality; } public String toString() { return nameGroup; } } ManagementSystem.java package students.logic; import java.sql.Connection; import java.sql.Date; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.ArrayList; import java.util.Collection; import java.util.List; public class ManagementSystem { private static Connection con; private static ManagementSystem instance; private ManagementSystem() throws Exception { try { Class.forName("com.mysql.jdbc.Driver"); String url = "jdbc:mysql://localhost:3306/students"; con = DriverManager.getConnection(url, "root", "root"); } catch (ClassNotFoundException e) { throw new Exception(e); } catch (SQLException e) { throw new Exception(e); } } public static synchronized ManagementSystem getInstance() throws Exception { if (instance == null) { instance = new ManagementSystem(); } return instance; } public List<Group> getGroups() throws SQLException { List<Group> groups = new ArrayList<Group>(); Statement stmt = null; ResultSet rs = null; try { stmt = con.createStatement(); rs = stmt.executeQuery("SELECT group_id, groupName, curator, speciality FROM groups"); while (rs.next()) { Group gr = new Group(); gr.setGroupId(rs.getInt(1)); gr.setNameGroup(rs.getString(2)); gr.setCurator(rs.getString(3)); gr.setSpeciality(rs.getString(4)); groups.add(gr); } } finally { if (rs != null) { rs.close(); } if (stmt != null) { stmt.close(); } } return groups; } public Collection<Student> getAllStudents() throws SQLException { Collection<Student> students = new ArrayList<Student>(); Statement stmt = null; ResultSet rs = null; try { stmt = con.createStatement(); rs = stmt.executeQuery( "SELECT student_id, firstName, patronymic, surName, " + "sex, dateOfBirth, group_id, educationYear FROM students " + "ORDER BY surName, firstName, patronymic"); while (rs.next()) { Student st = new Student(rs); students.add(st); } } finally { if (rs != null) { rs.close(); } if (stmt != null) { stmt.close(); } } return students; } public Collection<Student> getStudentsFromGroup(Group group, int year) throws SQLException { Collection<Student> students = new ArrayList<Student>(); PreparedStatement stmt = null; ResultSet rs = null; try { stmt = con.prepareStatement( "SELECT student_id, firstName, patronymic, surName, " + "sex, dateOfBirth, group_id, educationYear FROM students " + "WHERE group_id=? AND educationYear=? " + "ORDER BY surName, firstName, patronymic"); stmt.setInt(1, group.getGroupId()); stmt.setInt(2, year); rs = stmt.executeQuery(); while (rs.next()) { Student st = new Student(rs); students.add(st); } } finally { if (rs != null) { rs.close(); } if (stmt != null) { stmt.close(); } } return students; } public void moveStudentsToGroup(Group oldGroup, int oldYear, Group newGroup, int newYear) throws SQLException { PreparedStatement stmt = null; try { stmt = con.prepareStatement( "UPDATE students SET group_id=?, educationYear=? " + "WHERE group_id=? AND educationYear=?"); stmt.setInt(1, newGroup.getGroupId()); stmt.setInt(2, newYear); stmt.setInt(3, oldGroup.getGroupId()); stmt.setInt(4, oldYear); stmt.execute(); } finally { if (stmt != null) { stmt.close(); } } } public void removeStudentsFromGroup(Group group, int year) throws SQLException { PreparedStatement stmt = null; try { stmt = con.prepareStatement( "DELETE FROM students WHERE group_id=? AND educationYear=?"); stmt.setInt(1, group.getGroupId()); stmt.setInt(2, year); stmt.execute(); } finally { if (stmt != null) { stmt.close(); } } } public void insertStudent(Student student) throws SQLException { PreparedStatement stmt = null; try { stmt = con.prepareStatement( "INSERT INTO students " + "(firstName, patronymic, surName, sex, dateOfBirth, group_id, educationYear) " + "VALUES (?, ?, ?, ?, ?, ?, ?)"); stmt.setString(1, student.getFirstName()); stmt.setString(2, student.getPatronymic()); stmt.setString(3, student.getSurName()); stmt.setString(4, new String(new char[]{student.getSex()})); stmt.setDate(5, new Date(student.getDateOfBirth().getTime())); stmt.setInt(6, student.getGroupId()); stmt.setInt(7, student.getEducationYear()); stmt.execute(); } finally { if (stmt != null) { stmt.close(); } } } public void updateStudent(Student student) throws SQLException { PreparedStatement stmt = null; try { stmt = con.prepareStatement( "UPDATE students SET " + "firstName=?, patronymic=?, surName=?, " + "sex=?, dateOfBirth=?, group_id=?, educationYear=?" + "WHERE student_id=?"); stmt.setString(1, student.getFirstName()); stmt.setString(2, student.getPatronymic()); stmt.setString(3, student.getSurName()); stmt.setString(4, new String(new char[]{student.getSex()})); stmt.setDate(5, new Date(student.getDateOfBirth().getTime())); stmt.setInt(6, student.getGroupId()); stmt.setInt(7, student.getEducationYear()); stmt.setInt(8, student.getStudentId()); stmt.execute(); } finally { if (stmt != null) { stmt.close(); } } } public void deleteStudent(Student student) throws SQLException { PreparedStatement stmt = null; try { stmt = con.prepareStatement( "DELETE FROM students WHERE student_id=?"); stmt.setInt(1, student.getStudentId()); stmt.execute(); } finally { if (stmt != null) { stmt.close(); } } } } StudentsFrame.java package students.frame; import java.util.Vector; import java.awt.FlowLayout; import java.awt.BorderLayout; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JList; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JSpinner; import javax.swing.SpinnerModel; import javax.swing.SpinnerNumberModel; import javax.swing.SwingUtilities; import javax.swing.border.BevelBorder; import students.logic.Group; import students.logic.ManagementSystem; import students.logic.Student; public class StudentsFrame extends JFrame { ManagementSystem ms = null; private JList grpList; private JList stdList; private JSpinner spYear; public StudentsFrame() throws Exception { // Устанавливаем layout для всей клиентской части формы getContentPane().setLayout(new BorderLayout()); // Создаем верхнюю панел, где будет поле для ввода года JPanel top = new JPanel(); // Устанавливаем для нее layout top.setLayout(new FlowLayout(FlowLayout.LEFT)); // Вставляем пояснительную надпись top.add(new JLabel("Год обучения:")); // Делаем спин-поле // 1. Задаем модель поведения - только цифры // 2. Вставляем в панель SpinnerModel sm = new SpinnerNumberModel(2006, 1900, 2100, 1); spYear = new JSpinner(sm); top.add(spYear); // Создаем нижнюю панель и задаем ей layout JPanel bot = new JPanel(); bot.setLayout(new BorderLayout()); // Создаем левую панель для вывода списка групп JPanel left = new JPanel(); // Задаем layout и задаем "бордюр" вокруг панели left.setLayout(new BorderLayout()); left.setBorder(new BevelBorder(BevelBorder.RAISED)); // Нам необходимо обработать ошибку при обращении к базе данных Vector gr = null; Vector st = null; // Попробуем получить коннект к базе данных ms = ManagementSystem.getInstance(); // Получаем список групп gr = new Vector<Group>(ms.getGroups()); // Получаем список студентов st = new Vector<Student>(ms.getAllStudents()); // Создаем надпись left.add(new JLabel("Группы:"), BorderLayout.NORTH); // Создаем визуальный список и вставляем его в скроллируемую // панель, которую в свою очередь уже кладем на панель left grpList = new JList(gr); left.add(new JScrollPane(grpList), BorderLayout.CENTER); // Создаем правую панель для вывода списка студентов JPanel right = new JPanel(); // Задаем layout и задаем "бордюр" вокруг панели right.setLayout(new BorderLayout()); right.setBorder(new BevelBorder(BevelBorder.RAISED)); // Создаем надпись right.add(new JLabel("Студенты:"), BorderLayout.NORTH); // Создаем визуальный список и вставляем его в скроллируемую // панель, которую в свою очередь уже кладем на панель right stdList = new JList(st); right.add(new JScrollPane(stdList), BorderLayout.CENTER); // Вставляем панели со списками групп и студентов в нижнюю панель bot.add(left, BorderLayout.WEST); bot.add(right, BorderLayout.CENTER); // Вставляем верхнюю и нижнюю панели в форму getContentPane().add(top, BorderLayout.NORTH); getContentPane().add(bot, BorderLayout.CENTER); // Задаем границы формы setBounds(100, 100, 600, 400); } public static void main(String args[]) { SwingUtilities.invokeLater(new Runnable() { public void run() { try { // Мы сразу отменим продолжение работы, если не сможем получить // коннект к базе данных StudentsFrame sf = new StudentsFrame(); sf.setDefaultCloseOperation(EXIT_ON_CLOSE); sf.setVisible(true); } catch (Exception ex) { ex.printStackTrace(); } } }); } } ВНИМАНИЕ!!! Теперь для запуска нашего приложения нам потребуется драйвер. Поместите его в корневой каталог нашего приложения. Теперь структура нашего каталога выглядит так:
- student
- frame
- StudentsFrame.java
- logic
- Student.java
- Group.java
- ManagementSystem.java
- mysql-connector-java-3.1.13-bin.jar
Для сборки нам потребуется команда
javac students/frame/*.java students/logic/*.java Для запуска нам надо указать в CLASSPATH файл mysqlJDBC-3.1.13-bin.jar java -cp .;mysql-connector-java-3.1.13-bin.jar students.frame.StudentsFrame Теперь мы можем сосредоточить наши усилия на совершенствовании нашего пользовательского интерфейса - Часть 4 - GUI, предварительные знания Архив с исходными кодами: Исходный код |