Session.createQuery(“from Company”)




Интерфейс Query имеет следующие методы:

list() - выполняет запрос, результат возвращается в коллекции List;

session.createQuery(“from Company”).list();

executeUpdate() – для выполнения удалений, изменений, применяемых к многочисленным объектам;

session.createQuery(“delete from Company where status =’closed’”).executeUpdate();

setString(int index, String value), setDate() и т. д. –
устанавливает параметр в запрос по индексу;

session.createQuery(“delete from Company where status =?”).setString(0, ‘closed’).executeUpdate();

также можно установить параметр по имени:

session.createQuery(“delete from Company where status =:stat”).setString(‘stat’, ‘closed’).executeUpdate();

iterate() - возвращает Iterator по результатам запроса

Iterator it = createQuery(“from Company”).iterate();

Долгоживущие Объекты и Коллекции (Persistent Objects and Collections) – это однопоточные, короткоживущие объекты, содержащие сохраняемое состояние
и бизнес-функции. Это могут быть обычные JavaBean/POJO (Plain Old Java Objects) объекты, их отличительная особенность – это то, что они ассоциированы с одной сессией (Session). Как только их сессия закрыта, эти объекты становятся отсоединенными и свободными для использования на любом уровне приложения, например, непосредственно как объекты передачи данных на уровень представления и с него.

Временные Объекты и Коллекции (Transient Objects and Collections) – это экземпляры долгоживущих классов, которые в данный момент не ассоциированы
с сессией (Session). Это могут быть объекты, созданные приложением и в данный момент еще не переведенные в долгоживущее состояние.

Транзакция net.sf.hibernate.Transaction – однопоточный, короткоживущий объект, используемый приложением для указания атомарной единицы выполняемой работы. Он абстрагирует приложение от нижележащих JDBC, JTA или CORBA транзакций. В некоторых случаях одна сессия (Session) может породить несколько транзакций:

commit() – фиксирует транзакцию базы данных;

rollback() – принуждает транзакцию возвращаться обратно.

Интерфейс net.sf.hibernate.connection.ConnectionProvider –поставщик соединений, фабрика и пул для JDBC-соединений. Абстрагирует приложение от нижележащих объектов Datasource или DriverManager. Внутренний объект Hibernate недоступен для приложения, но может быть расширен или реализован разработчиком. Методы:

close() – освобождает все ресурсы, занимаемые поставщиком соединения;

closeConnection(Connection conn) – закрывает используемое соединение;

configure(Properties props) – инициализирует поставщика соединений из переданных свойств.

Фабрика транзакций net.sf.hibernate.TransactionFactory – фабрика для экземпляров класса Transaction. Внутренний объект Hibernate недоступен для приложения, но также может быть расширен или реализован разработчиком.

beginTransaction(SessionImplementor session) – начинает транзакцию и возвращает ее объект.

Простейшее применение объявленных выше классов при добавлении
в сервлет реализаций методов generateAndExecuteCreationScript()
и createProperties() выглядит следующим образом:

/* пример # 5: простейшее применение hibernate: MainServlet.java */

package courses.servlet;

import net.sf.hibernate.cfg.Configuration;

import net.sf.hibernate.tool.hbm2ddl.SchemaExport;

import net.sf.hibernate.MappingException;

import net.sf.hibernate.HibernateException;

import net.sf.hibernate.Session;

import net.sf.hibernate.SessionFactory;

 

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import javax.servlet.ServletException;

import java.io.IOException;

import java.util.List;

import java.util.Properties;

 

public class MainServlet extends HttpServlet {

public static SessionFactory factory;

static{

factory =

new Configuration().configure().buildSessionFactory();

}

private String ACTION_SHOW = "show";

private String ACTION_GENERATE = "generate";

 

protected void doGet(HttpServletRequest req,

HttpServletResponse resp)

throws ServletException, IOException {

performTask(req, resp);

}

protected void doPost(HttpServletRequest req,

HttpServletResponse resp)

throws ServletException, IOException {

performTask(req, resp);

}

private void performTask(HttpServletRequest req,

HttpServletResponse resp)

throws ServletException, IOException {

String action = req.getParameter("action");

 

if (action.equals(ACTION_SHOW)) {

try {

 

Session session = factory.openSession();

 

List courses = session.createQuery(

"from Course").list();

req.setAttribute("courses", courses);

List students = session.createQuery(

"from Student").list();

req.setAttribute("students", students);

 

resp.sendRedirect("show.jsp");

req.getRequestDispatcher("show.jsp").forward(resp, req);

session.close();

} catch (Exception e) {

throw new RuntimeException(e);

}

} else if (action.equals(ACTION_GENERATE)) {

try {

Configuration configuration = new Configuration();

//или createConfiguration();

 

Properties properties = createProperties();

generateAndExecuteCreationScript(

configuration.configure(), properties);

resp.sendRedirect("generated.jsp");

} catch (Exception e) {

throw new RuntimeException(e);

}

}

}

}

<!-- пример # 6: отображение информации, извлеченной из БД: show.jsp -->

<%@ page import="java.util.List,

Courses.hiber.Course,

courses.hiber.Student "%>

<HTML><HEAD><TITLE>Data from database</TITLE></HEAD>

<BODY>

All Courses:

<TABLE width="100%">

<TR>

<TD>Id</TD>

<TD>Title</TD>

</TR>

<%

List courses = (List)request.getAttribute("courses");

if (courses!= null) {

for (int i=0; i<courses.size(); i++)

{ %>

<TR>

<TD><%= ((Course)courses.get(i)).getId() %></TD>

<TD><%= ((Course)courses.get(i)).getTitle() %></TD>

</TR>

<%} }%>

</TABLE>

All Students:

<TABLE width="100%">

<TR>

<TD>Id</TD>

<TD>First Name</TD>

<TD>Last Name</TD>

</TR>

<%

List students = (List)request.getAttribute("students");

if (students!= null) {

for (int i=0; i<students.size(); i++) {%>

<TR>

<TD><%=((Student)students.get(i)).getId()%></TD>

<TD><%=((Student)students.get(i)).getFirstname()%></TD>

<TD><%=((Student)students.get(i)).getLastname()%></TD>

</TR>

<%}}%>

</TABLE></BODY></HTML>

<!-- пример # 7: сообщение о генерации скрипта: generated.jsp -->

<HTML><HEAD><TITLE>Script was generated</TITLE></HEAD>

<BODY>Script was generated</BODY></HTML>

Очевидно, что если сервлет при каждом обращении к нему будет создавать заново объект SessionFactory, то этот процесс будет слишком трудоемким и с точки зрения производительности системы, и с точки зрения разработчика при дальнейшем расширении системы. Поэтому следует создать класс, задачами которого будет создание и необходимая инициализация объектов Configuration, SessionFacroty и один из методов класса будет возвращать готовый объект Session. Следовательно, в методе сервлета для вывода содержимого таблиц базы данных на экран можно использовать готовый объект Session и из него загрузить интересующие параметры.

Профессиональная реализация

Используя заданную выше последовательность, для инициализации mapping-файлов и для корректного манипулирования соединением с базой данных создается класс ConnectionFactory. Было замечено, что в некоторых версиях hibernate, несмотря на директиву autoReconnect=true, автоматическое пере­подключение к БД происходит со второго раза, то есть подключение происходит сразу же, но появляется исключение о невозможности подключиться к БД.

/* пример # 8: инициализация mapping и подключение к БД:

ConnectionFactory.java */

package com.hib;

import net.sf.hibernate.HibernateException;

import net.sf.hibernate.MappingException;

import net.sf.hibernate.Session;

import net.sf.hibernate.SessionFactory;

import net.sf.hibernate.cfg.Configuration;

import java.util.Date;

 

public class ConnectionFactory {

public static long timer = 0;

public static SessionFactory sessionFactory = null;

 

public static void initConnectionFactory() {

Date dt = new Date();

timer = dt.getTime();

try {

//добавление mapping-файлов в конфигурацию подключения

Configuration cfg = new Configuration().addClass(Student. class).addClass(Course. class);

 

//создание подключения к БД

sessionFactory = cfg.buildSessionFactory();

} catch (MappingException e) {

System.err.print(e);

} catch (HibernateException e) {

System.err.print(e);

destroy();

}

}

public static Session getOrInitSession() {

try {

Date curDate = new Date();

long curTime = curDate.getTime();

long tenminutes = 10 * 60 * 1000;

 

if (curTime - timer > tenminutes){

destroy();

}

else {

curDate = new Date();

timer = curDate.getTime();

}

if (sessionFactory == null) {

initConnectionFactory();

}

return sessionFactory.openSession();

 

} catch (HibernateException e) {

System.err.print(e);

destroy();

return null;

}

}

public static void destroy() {

timer = 0;

try {

//необходимо вызывать, т.к. иначе будут утечки памяти

sessionFactory.close();

} catch (Exception e) {

e.printStackTrace();

}

sessionFactory = null;

}

}

Данный класс проверяет наличие подключения к БД и сохраняет время проверки. Если на момент проверки класс «простаивает» больше 10 минут, то идет повторное подключение к базе данных. В случае удаления класса он предотвращает утечки памяти. Хотя в Hibernate есть средства для того, чтобы исключить необходимость подключать каждый hbm.xml файл по отдельности, всё же лучше это делать вручную во избежание указанных выше ошибок.

Этот класс обрабатывает ошибки, которые возникали на практике при работе c Hibernate, JDBC драйвером MySQL и сервером баз данных MySQL.

Взаимодействие с БД

При работе с базой данных удобно функции манипулирования с объектами собирать воедино и создавать менеджеры транзакций.

/* пример # 9: инициализация mapping и подключение к БД: StudentDAO.java */

package com.hib;

import net.sf.hibernate.*;

public class StudentDAO {

//проверка на существование записи в базе данных

public static Boolean studentExists(String login) {

Session session =

ConnectionFactory.getOrInitSession();

Student _student = null;

try {

// создание запроса к БД

Query query =

session.createQuery(

" from Student a where a.login =:login ");

query.setParameter("login", login);

/*этот метод позволяет получать уникальные результаты. Необходимо обеспе­чить уникальность результатов на уровне БД, если используется данная функция */

_student = (Student) query.uniqueResult();

} catch (HibernateException e) {

e.printStackTrace();

ConnectionFactory.destroy();

} finally {

if (session!= null) {

try {

session.close();

} catch (HibernateException e) {

e.printStackTrace();

ConnectionFactory.destroy();

}

}

}

if (_student!= null) {

return new Boolean(true);

} else {

return null;

}

}

public static Student getStudent(String login,

String password) {

Session session =

ConnectionFactory.getOrInitSession();

Student _student = null;

try {

Query query =

session.createQuery(

"from Student a where a.login =:login");

query.setParameter("login", login);

_student = (Student) query.uniqueResult();

} catch (HibernateException e) {

e.printStackTrace();

ConnectionFactory.destroy();

} finally {

if (session!= null) {

try {

session.close();

} catch (HibernateException e) {

e.printStackTrace();

ConnectionFactory.destroy();

}

}

}

if (_student!= null) {

if (password.equals(_student.getPassword())) {

return _student;

} else

return null;

} else

return null;

}

//обновление учетной записи студента

//для возможности таких обновлений прописывался тег id в mapping

public static void updateStudent(Student _student) {

Session session =

ConnectionFactory.getOrInitSession();

try {

Transaction tx = null;

tx = session.beginTransaction();

session.update(_student);

tx.commit();

} catch (HibernateException e) {

e.printStackTrace();

tx.rollback();

ConnectionFactory.destroy();

} finally {

if (session!= null) {

try {

session.close();

} catch (Exception e) {

e.printStackTrace();

ConnectionFactory.destroy();

}

}

}

}

//добавление учетной записи студента

// в этом случае работает директива native из mapping

public static Boolean addStudent(Student _student) {

Session session =

ConnectionFactory.getOrInitSession();

try {

Transaction tx = null;

tx = session.beginTransaction();

session.save(_student);

tx.commit();

} catch (HibernateException e) {

e.printStackTrace();

tx.rollback();

ConnectionFactory.destroy();

return null;

} finally {

if (session!= null) {

try {

session.close();

} catch (Exception e) {

e.printStackTrace();

ConnectionFactory.destroy();

return null;

}

}

}

return new Boolean(true);

}

//удаление учетной записи студента

public static void deleteStudent(Student _student) {

Session session =

ConnectionFactory.getOrInitSession();

try {

Transaction tx = null;

tx = session.beginTransaction();

session.delete(_student);

tx.commit();

} catch (HibernateException e) {

e.printStackTrace();

tx.rollback();

ConnectionFactory.destroy();

} finally {

if (session!= null) {

try {

session.close();

} catch (Exception e) {

e.printStackTrace();

ConnectionFactory.destroy();

}

}

}

}

}

 

Класс SessionFactory относится к потокобезопасным классам, поэтому обычно его объект будет создаваться один раз и храниться в статической переменной. Если же возникли проблемы с базой данных, с пулом соединений либо
с освобождением ресурсов, которые хранятся в объекте SessionFactory, то, возможно, придется поддержать вышеприведенный подход.

Для управления Session используются два похода:

Session для каждой операции с базой данных, либо Session per request в контексте транзакции.

Начиная с версии 3.1, в Hibernate появился новый параметр hibernate.current_session_context_class, который может принимать одно из трех коротких значений, " jta ", " thread " и "managed",
либо классов, которые реализуют интерфейс org.hibernate.context.CurrentSessionContext и будут ответственны за открытие/закрытие сессии.

Если данный параметр установлен в конфигурационном файле, то в коде для получения сессии нужно только вызвать метод SessionFactory.getCurrentSession(),который либо вернет уже привязанную к данному контексту сессию, либо создаст новую.

Установив свойство в конфигурационном файле

<property name= "current_session_context_class">thread </property> метод deleteStudent() можно переписать следующим образом.

public static void deleteStudent(Student _student) {

 

Session session =

ConnectionFatory.sessionFactory

.getCurrentSession();

try {

Transaction tx = null;

tx = session.beginTransaction();

session.delete(_student);

tx.commit();

} catch (HibernateException e) {

e.printStackTrace();

tx.rollback();

}

}

 

В данном случае управление соединением будет производиться классом org.hibernate.context.ThreadLocalSessionContext,который будет использовать соединение, пока метод beginTransaction() не был вызван,
и соответственно отпустит соединение при вызове метода commit() либо rollback().

Запуск из-под Apache Ant

Для того чтобы запустить проект из-под Apache Ant, необходимо, чтобы папки проекта были организованы следующим образом:

+lib

<Hibernate and third-party libraries>

+src

<All source files and packages including hbm files>

hibernate.cfg.xml

build.xml

Файл build.xml служит руководством к действию для Ant. Изначально он должен выглядеть следующим образом:

<project name="hibernate-tutorial" default="compile">

<property name="sourcedir" value="${basedir}/src"/>

<property name="targetdir" value="${basedir}/bin"/>

<property name="librarydir" value="${basedir}/lib"/>

<path id="libraries">

<fileset dir="${librarydir}">

<include name="*.jar"/>

</fileset>

</path>

<target name="clean">

<delete dir="${targetdir}"/>

<mkdir dir="${targetdir}"/>

</target>

<target name="compile" depends=

"clean, copy-resources">

<javac srcdir="${sourcedir}"

destdir="${targetdir}"

classpathref="libraries"/>

</target>

<target name="copy-resources">

<copy todir="${targetdir}">

<fileset dir="${sourcedir}">

<exclude name="**/*.java"/>

</fileset>

</copy>

</target>

</project>

Далее выполняется команда ant, находясь в папке проекта или явно указывая рабочую папку. Если компиляция прошла успешно, то в файл build.xml необходимо добавить следующие строки:

<target name="run" depends="compile">

<java fork="true" classname="ClassName"

classpathref="libraries">

<classpath path="${targetdir}"/>

</java>

</target>

где параметр ClassName содержит имя класса, который можно запустить (есть метод main, правильно объявленный). В конце концов, для запуска используется команда ant run.

 
Приложение 6

STRUTS

Проект Struts был запущен в мае 2000 г. К. Макклэнаном (Craig R. McClanahan) для обеспечения возможности разработки приложений с архитектурой, базирующейся на парадигме Model/View/Controller. В июле 2001 г. был выпущен первый релиз Struts 1.0. Struts является частью проекта Jakarta, поддерживаемого Apache Software Foundation. Цель проекта Jakarta Struts – разработка среды с открытым кодом для создания Web-приложений с помощью технологий Java Servlet and JSP.

Шаблон проектирования MVC (Model-View-Controller)

При использовании шаблона MVC поток выполнения приложения всегда обязан проходить через контроллер приложения. Контроллер направляет запросы –
в данном случае HTTP(S)-запросы – к соответствующему обработчику. Обработчики запроса связаны с бизнес-моделью, и в итоге каждый разработчик приложения должен только обеспечить взаимодействие между запросом и бизнес-моделью. В результате реакции системы на запрос вызывается соответствующая JSP-страница, выполняющая в данной схеме роль представления.

В результате модель отделена от представления, и все связывающие их команды проходят через контроллер приложения. Приложение, соответствующее этим принципам, становится более понятным с точки зрения разработки, поддержки и совершенствования, а отдельные его части довольно легко могут быть использованы повторно.

Состав Struts

Согласно шаблону Model/View/Controller, Struts имеет три основных компонента: сервлет-контроллер, который входит в Struts, JSP-страницы и бизнес-логику приложения.

Загрузить последнюю версию struts-2.0.9-bin.zip можно по адресу:

https://struts.apache.org

Три основных класса, задействованные при обработке запроса:

org.apache.struts.action.ActionServlet –класс, связывающий между собой все части MVC-шаблона;

org.apache.struts.action.Action – класс-обработчик запроса;

org.apache.struts.action.ActionForm – класс, предназначенный для получения данных, которые приходят с клиентской стороны? либо для их отображения в браузере пользователя.

Запрос к серверу обрабатывается классом-контроллером ActionServlet
в соответствии с настройками в файле web.xml. Запрос на сервер выполняет пользователь нажатием кнопки Submit, введением URL в поле браузера, вызовом submit-формы на JavaScript и пр. Во время инициализации главный контроллер считывает (parse) конфигурационный файл struts-config.xml, который однозначно определяет все соответствия и альтернативы для всех запросов данного приложения и упаковывает их в объект класса



Поделиться:




Поиск по сайту

©2015-2024 poisk-ru.ru
Все права принадлежать их авторам. Данный сайт не претендует на авторства, а предоставляет бесплатное использование.
Дата создания страницы: 2016-02-16 Нарушение авторских прав и Нарушение персональных данных


Поиск по сайту: