Команда 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) DEFAULT 0,
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
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 >
< class name= "courses.hiber.Course" table= "course" >
< id name= "id" column= "id" type= "java.lang.Integer" >
< generator class= "increment"/ >
< /id >
< property name= "title" type= "java.lang.String" />
< set name= "students" table= "course_student"
cascade= "all" >
< key column= "course_id" />
< many-to-many column= "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 ">
< id name ="id" column ="id" type="java.lang.Integer" >
< generator class="native"/>
< /id >
< property name ="lastname" type ="java.lang.String" />
< property name ="login" type ="java.lang.String" />
< property name ="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, которая доступна на сайте разработчика.