Определение структуры данных

Команда CREATE TABLE

Для создания новых таблиц используется команда CREATE TABLE. В общем виде ее синтаксис следующий:

CREATE TABLE <имя таблицы>

(

<имя колонки> <тип колонки>[(<размер колонки>)] [<ограничение целостности уровня колонки>]

[, <имя колонки> <тип колонки>[(<размер колонки>)] [<ограничение целостности уровня колонки>]]

[, …]

[<ограничение целостности уровня таблицы>]

[,<ограничение целостности уровня таблицы>]

[, …]

)

Примеры:

CREATE TABLE Departments

(

DeptNum int NOT NULL PRIMARY KEY,

Name varchar(80) NOT NULL

)

CREATE TABLE Employees

(

TabNum int NOT NULL PRIMARY KEY,

Name varchar(100) NOT NULL,

Position varchar(200),

DeptNum int,

Salary decimal(10, 2) DEFAULT0,

CONSTRAINT FK_DEPARTMENT FOREIGN KEY (DeptNum)

REFERENCES Departments(DeptNum)

)

Помимо команды CREATE TABLE, можно создать новую таблицу с помощью специальной формы команды SELECT:

SELECT [DISTINCT] <список колонок>

INTO <имя новой таблицы>

FROM <имя таблицы> [JOIN <имя таблицы> ON <условия связывания>]

[WHERE <условия выборки>]

[GROUP BY <список колонок для группировки> [HAVING <условия выборки групп>] ]

[ORDER BY <список колонок для сортировки>]

При наличии ключевого слова INTO в команде SELECT ядро СУБД не вернет результирующую выборку пользователю, а автоматически создаст новую таблицу с указанным именем и заполнит ее данными из результирующей выборки. Имена колонок таблицы и типы будут определены автоматически при анализе команды SELECT и словаря базы данных.

Команда ALTER TABLE

Созданную таблицу можно впоследствии изменить с помощью команды ALTER TABLE. Команда ALTER TABLE позволяет добавлять новые колонки и ограничения целостности, удалять их, менять типы колонок, переименовывать колонки.

Примеры различных вариантов команды ALTER TABLE:

ALTER TABLE Departments ADD COLUMN City int

ALTER TABLE Departments DROP COLUMN City

ALTER TABLE Departments ADD

CONSTRAINT FK_City

FOREIGN KEY (City)

REFERENCES Cities(City)

ALTER TABLE Departments DROP CONSTRAINT FK_City

Команда DROP TABLE

Удаление ранее созданной таблицы производится командой DROP TABLE:

DROP TABLE Departments

 
Приложение 5

HIBERNATE

Hibernate – инструмент объектно-реляционного отображения (Object-Relational Mapping, ORM) данных для Java-окружения. Целью Hibernate является освобождение разработчика от большинства общих работ, связанных с задачами получения, сохранения данных в СУБД. Эта технология помогает удалить или инкапсулировать зависящий от поставщика SQL-код, а также решает стандартную задачу преобразования типов Java-данных в типы данных SQL и наборов данных из табличного представления в объекты Java-классов.

Установка

1. Загрузить и установить сервер баз данных MySQL с сервера http://dev.mysql.com/

2. Загрузить и подключить Hibernate с сервера

http://hibernate.org/

3. Загрузить и подключить JDBC-драйвер, используемой базы данных
в tomcat/common/lib (или, в случае использования Ant, в папку lib проекта), в данном случае mysql-connector-java-3.1.12.jar. Обычно JDBC-драйвер предоставляется на сайте разработчика сервера баз данных.

Библиотека hibernate3.1.3.jar является основной. Кроме нее, устанавливается еще целый ряд необходимых библиотек из дистрибутива Hibernate,
а именно:

cglib.jar, commons-collections.jar, commons-logging.jar, jta.jar, dom4j.jar, log4j.jar, а также библиотеки antlr.jar, asm.jar, asm-attrs.jar для запуска приложения из-под Apache Ant.

dom4j.jar – отвечает за разбор файлов XML-настроек и файла XML-mapping метаданных;

CGLIB (cglib.jar) – эта библиотека используется для генерации кода для расширения классов во время исполнения;

commons-collections.jar – вспомогательная библиотека из проекта Apache Jakarta Commons;

commons-logging.jar – вспомогательная библиотека для журналирования событий из проекта Apache Jakarta Commons;

ODMG4 (odmg.jar) – пакет, необходимый для mapping-коллекций;

EHCache (ehcache.jar) – кэш-провайдер второго уровня;

ANother Tool for Language (antlr.jar) – инструмент, позволяющий создавать трансляторы, компиляторы и распознаватели для текстов, содержащие Java, C#, C++ или Python код;

ASM (asm.jar, asm-attrs.jar) – библиотека, предназначенная для динамического создания классов, а также их динамической корректировки.

Создание простейшего приложения

Hibernate использует JDBC-соединения для вызова SQL-запросов к базе данных, поэтому необходимо указать настроенный пул JDBC-соединений либо использовать один из поддерживаемых пулов, встроенных в Hibernate (C3P0, Proxool). Tomcat настраивает и дает доступ к пулу соединений, используя встроенный DBCP пул, а Hibernate запрашивает данные соединения через интерфейс JNDI. Tomcat связывает пул соединений с JNDI, объявляя ресурс в свой основной конфигурационный файл Tomcat 5.5/conf/server.xml, в виде:

<Context path="/test_db" docBase="test_db">

<Resource name="jdbc/test_db" scope="Shareable"

type="javax.sql.DataSource"/>

 

<ResourceParams name="jdbc/test_db">

<parameter>

<name>factory</name>

<value>org.apache.commons.dbcp.BasicDataSourceFactory </value>

</parameter>

<Context/>

Далее следует настроить конфигурационный файл Hibernate на использование пула соединений. Этот файл должен располагаться в каталоге
WEB-INF/classes и иметь имя hibernate.cfg.xml.

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE hibernate-configuration PUBLIC

"-//Hibernate/Hibernate Configuration DTD 3.0//EN"

"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

<hibernate-configuration>

<session-factory>

<property name="connection.datasource"> java:comp/env/jdbc/test_db</property>

<property name="show_sql">true</property>

<property name="dialect"> net.sf.hibernate.dialect.MySQLDialect</property>

<property name="hibernate.connection.password">pass</property>

<property name="hibernate.connection.username">root</property>

 

<mapping resource="courses/hiber/Course.hbm.xml"/>

<mapping resource="courses/hiber/Student.hbm.xml"/> </session-factory>

</hibernate-configuration>

Здесь указан способ получения JDBC-соединения, включено логирование команд SQL, настроен диалект SQL.

Для настройки параметров работы Hibernate вместо конфигурационного XML-файла можно использовать файл hibernate.properties в WEB-INF/classes (в случае, если приложение разбито по пакетам, необходимо это учитывать, чтобы данный файл был доступен):

##Данная директива позволяет делать автозамену значений ##полей класса в другие значения для удобства хранения
в ##базе данных

hibernate.query.substitutions true 1, false 0, yes 'Y',
no 'N'

##Прописывается JDBC-драйвер для базы данных MySQL

hibernate.dialect net.sf.hibernate.dialect.MySQLDialect

hibernate.connection.driver_class com.mysql.jdbc.Driver

##Прописывается адрес для подсоединения к серверу

##баз данных

##Формат подключения следующий:

##hibernate.connection.url ##jdbc:mysql://АДРЕС_МАШИНЫ:НОМЕР_ПОРТА/ИМЯ_БАЗЫ_ДАННЫХ? ##autoReconnect=Автоматически переподключатся к базе данных ##или нет, при потере соединения. Этот параметр должен быть ##выставлен в true, т.к. отключение от БД происходит в ##случае 30-ти минутного простоя.

##Параметр useUnicode=true отвечает за использование

##кодировки unicode при работе с БД.

##Параметр characterEncoding=Cp1251 отвечает за кодировку ##при передаче данных в базу данных

hibernate.connection.url jdbc:mysql://localhost:3306/test_db?autoReconnect =true&useUnicode=true&characterEncoding=Cp1251

##Имя пользователя при подключении к БД

hibernate.connection.username root

##Пароль при подключении к БД

hibernate.connection.password pass

##Размер пула соединений к БД

##Обычно используется значение в 50 соединений при

##создании реальных проектов

hibernate.connection.pool_size 50

##Кеширование запросов. Кеш повышает быстродействие при ##использовании большого числа однотипных запросов к базе ##данных

hibernate.statement_cache.size 20

##Директива, которая используется при debug. Результатом ##является то, что все запросы, которые осуществляются
к базе ##данных, будут показаны (или нет) разработчику.

hibernate.show_sql true

Как еще одну альтернативу (не очень удачную) можно рассматривать метод, генерирующий объект java.util.Properties. Например, в виде:

private Properties createProperties() {

Properties properties = new Properties();

properties.setProperty(

"hibernate.dialect",

"net.sf.hibernate.dialect.MySQLDialect");

properties.setProperty(

"hibernate.connection.driver_class",

"com.mysql.jdbc.Driver");

properties.setProperty(

"hibernate.connection.url",

"jdbc:mysql://localhost/test_db");

properties.setProperty(

"hibernate.connection.username", "root");

properties.setProperty(

"hibernate.connection.password", "pass");

return properties;

}

Создание POJO-классов

В примере, рассматривающем учебные курсы и студентов, их посещающих, будут созданы следующие классы POJO (Plain Ordinary Java Objects):

Класс Course – хранит информацию об учебном курсе (название курса
и список студентов, записанных на курс);

Класс Student – содержит информацию о студенте (имя, фамилия).

Кроме указанных выше полей, оба эти класса имеют поле id. Это свойство содержит значение столбца первичного ключа в таблице базы данных. Такое свойство может называться любым именем, и иметь любой примитивный тип,
тип класса-оболочки базового типа, а также типы java.lang.String
и java.util.Date. Свойство-идентификатор не является обязательным для класса, можно не создавать его и дать Hibernate самостоятельно следить за идентификацией объекта.

/* пример # 1: POJO-класс сущности : Course.java */

package courses.hiber;

import java.util.Set;

 

public class Course {

private Integer id;

private String title;

private Set students;

 

public Integer getId() {

return id;

}

protected void setId(Integer id) { /*в данном случае использовать protected как спецификатор доступа, поскольку данное поле не бу­дет определяться вручную, а значение генерируется автоматически в соответствии с mapping-файлом. Сама технология Hibernate имеет доступ к по­лям и методам, имеющим любые спецификаторы доступа(friendly, public, protected, private)*/

this.id = id;

}

public String getTitle() {

return title;

}

public void setTitle(String title) {

this.title = title;

}

public Set getStudents() {

return students;

}

public void setStudents(Set students) {

this.students = students;

}

}

/* пример # 2: POJO-класс сущности : Student.java */

package courses.hiber;

 

public class Student {

private Integer id;

private String lastname;

private String login;

private String password;

 

public Integer getId() {

return id;

}

protected void setId(Integer id) {

this.id = id;

}

public String getLogin() {

return login;

}

public void setLogin(String login) {

this.login = login;

}

public String getLastname() {

return lastname;

}

public void setLastname(String lastname) {

this.lastname = lastname;

}

public String getPassword() {

return password;

}

public void setPassword(String password) {

this.password = password;

}

}

После создания таблиц в базе данных задается соответствие между POJO-классами и таблицами. Объектно-реляционный mapping описывается в виде XML-документа hbm.xml в каталоге, содержащем *.class файл соответствующего класса: для Tomcat - это WEB-INF\classes\’каталог_пакета’, а для Ant - bin\’каталог_пакета’. Эти файлы создаются для того, чтобы обеспечить Hibernate данными о том, какие объекты по каким таблицам базы данных создавать и как их инициализировать. Язык описания mapping-файла ориентирован на Java, следовательно, mapping конструируется вокруг объявлений java-классов, а не таблиц БД.

/* пример # 3: Mapping-файл для класса courses.hiber.Course */

<?xml version="1.0"?>

<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>

<classname="courses.hiber.Course"table="course">

<idname="id"column="id"type="java.lang.Integer">

<generatorclass="increment"/>

</id>

<propertyname="title"type="java.lang.String"/>

<setname="students"table="course_student"

cascade="all">

<keycolumn="course_id"/>

<many-to-manycolumn="student_id"class="courses.hiber.Student"/>

</set>

</class>

</hibernate-mapping>

/* пример # 4: Mapping-файл для класса courses.hiber.Student */

<?xml version="1.0"?>

<!DOCTYPE hibernate-mapping PUBLIC "- //Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping package="courses.hiber">

<class name="Student" table="student">

<idname="id"column="id" type="java.lang.Integer">

<generator class="native"/>

</id>

<property name="lastname" type="java.lang.String"/>

<propertyname="login"type="java.lang.String"/>

<propertyname="password"type="java.lang.String"/>

</class>

</hibernate-mapping>

Пояснения по приведенному коду:

<class name="courses.hiber.Course"> – необходимо указать класс, который будет использоваться при работе с указанной ниже таблицей базы данных. Причём есть две возможности указать пакет расположения класса: либо явно указать полное имя класса, либо указать атрибут package в теге <hibernate-mapping>;

table="course" – указывается таблица на сервере баз данных, к которой будет вестись обращение. Если данный атрибут не указан, то за название таблицы берется название класса, т.е. в данном случае COURSE, поэтому в данном примере атрибут table можно было опустить;

<id name="id" column="id" type="java.lang.Integer">

<generator class="native"/>

</id> – указывается соответствие поля класса и столбца в базе данных, которые являются основными идентификаторами, т.е. уникальны, не имеют значений null. Тег <generator> указывает способ генерация значений в данном столбце, возможные его значения: increment, identity, sequence, hilo,, seqhilo, uuid, guid, native, assigned, select, foreign;

<property name="title" column="column" type="java.lang.String"/> – указывается соответствие полей класса
и столб­цов базы данных. В
mapping-файле несколько параметров может быть вы­делено как id. Это позволяет получать объекты из БД, удалять, создавать их без написания SQL-запросов. Процесс реализации будет продемонстрирован ниже.

Кроме того, следует обратить внимание на следующие теги и их параметры:

<many-to-one name="propertyName" column="column_name"class="ClassName"lazy="proxy|no-proxy|false"> – данный тег используется для указания связи таблиц (классов). К примеру, объект одного класса содержит ссылку на объект другого класса, а последний, в свою очередь, содержит коллекцию объектов первого класса. Параметры name и column аналогичным параметрам в предыдущих тегах и несут такой же смысл. Атрибут class указывает, какой класс будет связан с данным. Параметр lazy в большей части случаев является существенным, т.е. его необходимо выставлять вручную, поскольку значение по умолчанию, proxy, означает, что объекты класса, с которым связан данный, не будут автоматически загружены в память.

<set name="propertyName" inverse="true">

<key column="foreignId"/>

<one-to-many class="ClassName"/>

</set> - является интерпретацией коллекции «множество».

Необходимо строгое соответствие между столбцами таблиц базы данных
и mapping-файлами.

При изменении базы данных необходимо следить за изменением mapping-файлов и соответствующих им классов, т.к. такие ошибки достаточно сложно выявить.

Более подробно о рассмотренных и прочих тегах и их атрибутах вы можете прочитать в документации по технологии Hibernate, которая доступна на сайте разработчика.