Сервлеты с дизайном базы данных - PullRequest
5 голосов
/ 12 августа 2011

У меня есть общий вопрос об использовании Servlet и JDBC.

Например, у меня есть класс MyDatabaseManager, который предоставляет функции

public boolean updateUser(User user) {...}
public boolean deleteUser(User user) {...}
public boolean inserUser(User user){...}

, эти функции будут обращаться к базе данных и манипулировать ею.

У меня вопрос к сервлетуреализация.В настоящее время я использую три сервлета (UpdateUserServlet, InsertUserServlet и DeleteUserServlet), и каждый сервлет вызывает функцию MyDatabaseManager (только один здесь, с использованием шаблона Singleton).(Например, UpdateUserServlet вызывает MyDatabaseManager.updateUser ...).

Я думаю, что это самый простой способ использования сервлетов и баз данных.Но я не уверен, что это правильный способ сделать это.Например, как это реализовано в индустрии.

Ответы [ 6 ]

5 голосов
/ 12 августа 2011

Люди на самом деле не используют сервлеты прямо сейчас, они используют фреймворки, которые позволяют упростить вашу работу, но если вы действительно хотите использовать сервлеты, вы можете выполнить все действия в одном, используя другие методы, doPut,doDelete и даже создание собственных методов.Вот пример того, как вы это сделаете:

public abstract class BaseServlet extends HttpServlet {

    @Override
    protected void service(HttpServletRequest request,
        HttpServletResponse response) throws ServletException, IOException {
        String method = request.getParameter("_method");
        if ("form".equals(method)) {
            this.doForm(request, response);
        } else {
            if ("delete".equals(method)) {
                this.doDelete(request, response);
            } else {
        super.service(request, response);
            }
        }
   }

   protected void doForm(HttpServletRequest request,
        HttpServletResponse response) throws ServletException, IOException {
        throw new UnsupportedOperationException();
   }

}

Как вы можете видеть, этот сервлет использует специальное поле _method в формах, чтобы решить, какой специальный метод вызывать, если _method недоступен, он собирается использовать обычный сервисный метод и собирается вызвать doGet или doPost .

А вот как реализация дляэтот сервлет будет выглядеть так:

public class UsersServlet extends BaseServlet {

private UsersRepository cadastro = new UsersRepository();

@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
        throws ServletException, IOException {

    req.setAttribute("usuarios", cadastro.list());
    req.getRequestDispatcher("/usuarios/listar.jsp").forward(req, resp);

}

@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
        throws ServletException, IOException {

    User usuario = this.getUser(req);

    usuario.setNome(req.getParameter("nome"));
    usuario.setEmail(req.getParameter("email"));
    usuario.setSenha(req.getParameter("senha"));

    this.cadastro.persist(usuario);

    resp.sendRedirect(req.getContextPath() + "/usuarios");

}

protected User getUser(HttpServletRequest req) {
    User usuario;

    if (req.getParameter("id") == null) {
        usuario = new Usuario();
    } else {
        Long id = new Long(req.getParameter("id"));
        usuario = this.cadastro.search(id);
    }

    return usuario;
}

@Override
protected void doDelete(HttpServletRequest req, HttpServletResponse resp)
        throws ServletException, IOException {
    User usuario = this.getUser(req);
    this.cadastro.remover(usuario);
    resp.sendRedirect(req.getContextPath() + "/usuarios");
}

@Override
protected void doForm(HttpServletRequest request,
        HttpServletResponse response) throws ServletException, IOException {

    User usuario = this.getUser(request);

    request.setAttribute("usuario", usuario);
    request.getRequestDispatcher("/usuarios/form.jsp").forward(request,
            response);
}

}

Таким образом, вы можете сделать все это в одном сервлете.

2 голосов
/ 12 августа 2011

Трудно ответить, потому что существуют сотни шаблонов дизайна! Я хорошо знаю, что управление базой данных называется DAO (объекты доступа к данным). Я часто этим пользуюсь. Я советую вам взглянуть.

Не поймите меня неправильно, синглтон для удержания вашего менеджера - хорошая идея. В основном это то, чем я обычно занимаюсь. Однако обычно у меня есть DAOFactorySingleton, который в значительной степени отвечает за генерацию всех классов DAO в моем приложении, и эта фабрика хороша, потому что у меня могут быть некоторые правила DataSource, которые эта фабрика просто опрашивает откуда-то и вставляет в мой DAO! Так что почти каждому DAO не нужно заботиться о таких вещах, как соединение с JDBC!

Следуйте 2 ссылкам, чтобы объяснить больше о DAO! http://java.sun.com/blueprints/corej2eepatterns/Patterns/DataAccessObject.html

http://community.jboss.org/wiki/GenericDataAccessObjects

Второй - использовать с Hibernate! Вы можете прочитать его и не обязательно использовать только с Hibernate. Мне действительно нравится этот второй, хотя и более сложный.

1 голос
/ 12 августа 2011

Это, безусловно, вопрос выбора дизайна, вы можете использовать такие среды, как Spring, Struts и т. Д., Которые делают это намного проще. В качестве альтернативы, если вы хотите использовать классический шаблон запроса / ответа сервлета, я предлагаю создать родительский сервлет, который перехватывает запрос и передает его правильному методу для выполнения запроса.

Кроме того, у вас есть выбор для различных решений ORM, таких как Hibernate, JPA и т. Д., Которые вы можете использовать для управления операциями доступа к базе данных. Тем не менее, если вы решите придерживаться классических вызовов JDBC, вы можете использовать Фильтры и обработчики , чтобы решить, какие вызовы будут обеспечивать соединение базы данных и работать с ней.

0 голосов
/ 12 августа 2011

В мире индустрии мы все за простоту.Например, для взаимодействия пользователя от браузера до сервера и постоянного хранилища (базы данных) мы используем следующие подходы.

MVC шаблон, в первую очередь,Это позволило бы нам полностью , а не написать сервлет для каждого взаимодействия пользователя от браузера к серверу.Это позволяет нам делать следующее:

  • Разрешить контроллеру обрабатывать запрос пользователя и связывать его с нашими действиями пользователя (нашей модели).Эта модель позволяет нам писать бизнес-логику для реагирования на пользовательские данные.

В современном мире Java существует Frameworks, отвечающая нашим требованиям MVC.Тот, который выходит из коробки Java, это JSF (JavaServer Faces).

Для бэкэнда мы определенно используем базы данных, но мы тоже умны и используем ORM (Object Relational Mapping), чтобы смоделировать нашу реальную проблему в объектной модели и как ее лучше сохранить (хранить) эти объектные модели.Некоторые используют ERM (Entity-Relational Modeling) для разработки семантической модели данных.

В середине, в бизнес-логике, мы добавляем сервис (как слой бизнес-логики), но нехотите позаботиться о том, где читать / записывать данные, при условии, что они могут видеть нужные данные.Для этого добавлен Сервисный уровень, который облегчает это.По сути, у нас есть этот эффект.

public class ActionServlet extends HttpServlet {

    //Action registration
    public void init() {
        ActionMapping mapping = .....; //some instatiation
        mapping.setAction("/userRegistration", UserRegistrationAction.class);

        //Save it in Application Scope
        getServletContext().setAttribute("actionConfig", mapping);
    }

    private void doAction(HttpServletRequest request, HttpServletResponse response) throws Exception {
        String path = request.getPathInfo();

        Action action = ((ActionMapping)getServletContext().getAttribute("actionConfig")).getAction(path);
        if (action == null) {
            throw new Exception("No action of '" + path + "' found.");
        }

        action.execute(request, response);
    }

    public void doGet(HttpServletRequest request, HttpServletResponse response) throws Exception {
        doAction(request, response);
    }

    public void doPost(HttpServletRequest request, HttpServletResponse response) throws Exception {
        doAction(request, response);
    }
}


public abstract class Action {

    public abstract void execute(HttpServletRequest request, HttpServletResponse response) throws Exception;

    protected void dispatch(HttpServletRequest request, String path) {

        RequestDispatcher dispatcher = request.getRequestDispatcher(path);
        dispatcher.forward(request, response);
    }
}


public class UserRegistrationAction extends Action {

    public void execute(HttpServletRequest request, HttpServletResponse response) throws Exception {
        //Business Logic goes here...
        //Call DAO,
        UserRegistrationDAO dao = ; //Some DAO instantation
        User user = createUserFromForm(request);
        dao.save(user);

        dispatch(request, "success");
    }
}

Что касается настойчивости, Java 5 и выше поставляется с JPA .Вы можете использовать любую форму ORM, в зависимости от масштаба вашего проекта.Есть Hibernate (который также поддерживает JPA) или, если хотите, напишите свой собственный DAO.

Еще одна вещь, все эти процессы скучно склеивать.К счастью, у нас есть фреймворки, которые помогают нам упростить наш прекрасный пример выше.Фреймворки, такие как JBoss Seam , делают это и полностью используют спецификации Java.А пока, перейдите на простые модели проектирования и MVC (в учебных целях).Когда вы привыкнете к архитектуре, используйте фреймворки.

0 голосов
/ 12 августа 2011

Многие в отрасли используют ORM + инфраструктуру внедрения зависимостей + менеджер транзакций + библиотеки пулов баз данных, например Hibernate (ORM) + Spring DI (внедрение зависимостей) + диспетчер транзакций Spring (менеджер транзакций) + Apache DBCP (пул соединений с БД),

Иногда, когда использование ORM не может быть оправдано (например, очень простая схема БД, накладные расходы на производительность ORM запрещены из-за характера приложения и т. Д.), Разработчики могут использовать необработанный JDBC.Многие по-прежнему используют внедрение зависимостей и пул соединений с БД.

Очень редко использование инъекций зависимостей или пулов соединений с БД не может быть оправдано.Т.е., если это не очень редкое, специальное приложение, разработчики в отрасли используют инфраструктуру внедрения зависимостей и пул соединений с БД.

В этом случае состояние, которым необходимо управлять, управляется структурой пула соединений с БД, поэтому вам не нужно беспокоиться об управлении состоянием или безопасности потоков (если вы не делите ничего между разнымисами создайте потоки и следуйте API в структуре пула соединений с БД).Т.е. вам не понадобится синглтон.Если вы реализуете свой собственный пул соединений с БД, то использование синглтона имело бы смысл.

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

0 голосов
/ 12 августа 2011

Singleton в классе Database хорошо звучит, особенно если учесть, что он содержит код обновления / удаления / вставки.

Если вы используете пулы подключений, убедитесь, что вы используете Singleton the DataSourceFactory.

...