Модераторы: LSD, AntonSaburov
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Механизмы подключения к БД, Как более правильно работать с БД 
V
    Опции темы
RussianHero
  Дата 13.5.2011, 12:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 88
Регистрация: 14.8.2007
Где: г. Балашиха, МО

Репутация: нет
Всего: нет



Добрый день, господа джавощики!

Суть темы в следующем:

Разрабатываю вёб-приложение с довольно простым содержимым: есть БД (Оракл) и есть странички (JSP). Пользователь открывает бразуер, подключается к серверу. Видит формочку аутентификации, вводил логин и пароль и нажимает "Submit". После чего, данные формы передаются в ... сервлет (??? вы скажите куда лучше), который внутри себя должен проверить, существует ли этот пользователь в БД или нет, и если да, то перебросить на другую страничку, иначе, вернуть на форму логина/пароля и сказать всё, что думает об этом человеке.

Так вот внимание, вопрос: каким механизмом (сервлет, бин (не хотелось бы, так как я понимаю это больше вёб-сервис, чем реальный объект), сама JSP, самописный объект Джава, что-то другое) лучше всего сделать так, чтобы подключение (использую просто JDBC) к БД осуществлялось лишь один раз за время работы вёб-прилжения? Работа  с БД осуществляется чуть ли не на каждой JSP-страничке, и каждый раз подключаться к ней, сами понимаете, не айс. Хочется сделать "правильное" приложение, чтобы, например, при старте вёб-сервера (Томкет 7), каким-то образом создавался объект Connection, который, сами понимаете, подключался бы к БД и просто "висел". А из каждой JSP-шки, когда мне нужно будет обратиться к БД, я бы просто брал бы этот объект, и выполнял бы SQL-запрос и выводил бы содержимое на страницу.

Хочется сразу отметить, что пытаюсь по максимуму развести представление от логики (MVC), по этому, хочу использовать сервлеты, просто объекты Джава и JSP. Иначе давно бы уже всё засунул в JSP-шки, как ПХПшники и не парился бы 8)

И ещё маленький вопрос, никто не в курсе, зачем у Оракла на сайте есть OJDC (Oracle Java DB Connection), аналог JDBC, если есть и так прекрассно работающий JDBC? То есть стоит ли подключать Оракловую JAR-ку, чтобы работать с БД, или стоит использовать стандартную JDBC?

Буду очень признателен, если ещё поможете кодом.

З.Ы. Пришёл в джаву и вёб из толстого программизма (паскаль, плюс плюс, шарп), так что для меня все эти реквесты и респонсы, сессии, сервлеты и т.п. - очень новая тема. Терминологию более менее понимаю, а парктика близка к нулю. Так что не глумитесь пожалуйста, а отнеситесь с пониманием. Спасибо.
PM MAIL WWW ICQ   Вверх
Entwickler
Дата 13.5.2011, 14:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 285
Регистрация: 14.4.2007

Репутация: нет
Всего: 2



Привет,

в context.xml твоего Tomcat добавляешь что то вроде:
Код

<Resource auth="Container" driverClassName="oracle.jdbc.OracleDriver"
        maxActive="20" maxIdle="10" maxWait="-1" name="jdbc/MyDataSource"
        password="..." type="javax.sql.DataSource"
        url="jdbc:oracle:thin:@ ... "
        username="..." />


в web.xml твоего приложения: 
Код

<resource-ref>
    <res-ref-name>jdbc/MyDataSource</res-ref-name>
    <res-type>javax.sql.DataSource</res-type>
    <res-auth>Container</res-auth>
    <res-sharing-scope>Shareable</res-sharing-scope>
</resource-ref>


в Java классе, который должен получить/записать данные в DB, пишешь:
Код

...
Context initContext = new InitialContext();
Context envContext  = (Context)initContext.lookup("java:/comp/env");
DataSource ds = (DataSource)envContext.lookup("jdbc/MyDataSource");
Connection conn = ds.getConnection();
...


ну вроде и всё... "Тигрёнок" сам будет работать с соединениями к базе... а вообше поищи: Database Connection Pooling, Container managed database connection...
PM MAIL   Вверх
Entwickler
Дата 13.5.2011, 15:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 285
Регистрация: 14.4.2007

Репутация: нет
Всего: 2



P.S

и посмотри ещё в сторону Spring... очень мошьный Framework. Если предпочитаешь MVC, то для тебя очень хорошо подойдёт Spring MVC.

Для работы с данными лучше использовать DAO и VO. (DataAccessObject, ValueObject)... DAO работает с DB и возвращают "заполненные" VO обекты. Эти самые VO ты и отображаешь потом на странице...

Если есть вопросы, пиши Privat, чем смогу, помогу...
PM MAIL   Вверх
RussianHero
  Дата 13.5.2011, 15:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 88
Регистрация: 14.8.2007
Где: г. Балашиха, МО

Репутация: нет
Всего: нет



Entwickler, спасибо за ответ!

Но мне бы хотелось как можно меньше возиться с настройками самого контейнера...
Я где-то читал, что можно даже прописать в конфиге структуру таблицы "USERS", драйвер БД самом собой и т.п., так, что будут логин и пароль проверяться Томкетом самостоятеельно.

Но я ка краз так не хочу. Необходимо по минимуму трогать контейнер. Тока вёб.хмл придётся править из-за сервлетов и всё.

Я не сомневаюсь в мощьмности Томкета или другого контейнера, но мне необходимо сделать упор на программирование в Джаве. Сервлеты и JSP.
Я даже неоднократно как-то читал, что сервлеты для того и следует использовать, чтобы они работали с БД, а JSP читали результаты их работы. При том что где-то в сервлете можно задать "уровень его жизни" (1 раз создаётся при старте контейнера и существует всегда, или же для каждой сессии создаётся новый или же для каждой страницы и т.п.)

Если я ошибаюсь на счёт сервлетов, то объясните, что следует использовать в моё случае (самописаня JAR-ка с объектами или что-то дургое).

Постараюсь объяснить что нужно таким образом:

Есть JSP - login.JSP.
В ней есть 
Код

<FORM name="loginForm" method="post" accept-charset="UTF-8" action="<%= LoginServlet.CheckUser() %>>
<INPUT type="text" name="<%= LoginServlet.FORM_LOGIN_NAME %>" class="EdtBox"/>
<INPUT type="password" name="<%= LoginServlet.FORM_LOGIN_PASSWORD %>" class="EdtBox"/>
<INPUT type="submit" name="enter" value="Логин" class="button"/>


В сервлете LoginServlet необходимо сделать так:
чтобы функция CheckUser() проверила введённые FORM_LOGIN_NAME и FORM_LOGIN_PASSWORD.
Для этого, в этом сервлете вызывается объект Connection, который уже должен быть где-то и присоединён к БД. Далее делается простой запрос на сответствеи введённых данных таблице в БД. и сервлет должен ерекинуть на нужную страницу.

Допустим аутентификация удалась и нас перекинуло на страницу main.jsp. 
В ней я хочу вевести содержимой другой таблицы из базы. Для чего я просто делаю
Код

<% Connection con = ???.getMyConnection(); %>

и дальше SQL-запрос. Вывожу его результаты в обычной табличке, что-то типа:
Код

<TD> <%= RecordSet.GetValue("Column1") %> </TD>


То есть хочется всё сделать по максимуму на джаве. Так что по возможности, помогите шаблонами классов/сервлетов ну и объясните мне, как всё это реализовать? 8)

Добавлено через 1 минуту и 55 секунд
Я много читал про разные фреймворки, Спринг, Гибернейт и т.п.
Но дело в том, что я ещё для этого слишком мало знаю... Мне нужно за месяц сделать то, что я тут описал. При том что в джаве, а то чнее в вёб-технологиях, как видите, я не очень силён. так что хочу просто начать с начала сделав такой маленький, обыкновенный, без фреймворков, джава бинсов, фильтров контейнера и т.п. приложение.
PM MAIL WWW ICQ   Вверх
Entwickler
Дата 13.5.2011, 15:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 285
Регистрация: 14.4.2007

Репутация: нет
Всего: 2



ну если только масимально на Java, то...

на твоём месте я бы изменил форму: 
Код

<FORM name="loginForm" method="post" accept-charset="UTF-8" action="/LoginServlet" >
<INPUT type="text" name="FORM_LOGIN_NAME" class="EdtBox"/>
<INPUT type="password" name="FORM_LOGIN_PASSWORD" class="EdtBox"/>
<INPUT type="submit" name="enter" value="Логин" class="button"/>


твой сервлет:
Код

protected void doPost(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
        String login = request.getParameter("FORM_LOGIN_NAME");
                String pwd  = request.getParameter("FORM_LOGIN_PASSWORD");

                String redirectString = "";

                if(checkUser(login, pwd)) {
                         redirectString = "/myapplication/secure/index.jsp";
                } else {
                         redirectString = "/myapplication/error.jsp";
                }

                 response.sendRedirect(redirectString);
}

....

private Boolean checkUser(String login, String pwd) {
               //имплиментируй логику
               . . .

               return Boolean.TRUE; //ну или Boolean.FALSE;
}


ну вот и всё вроде... и ещё используй Servlet Filter чтобы фильтровать запросы на ресурсы... то есть все странички в папке secure закрыты пока не залогинешся...


PM MAIL   Вверх
RussianHero
  Дата 13.5.2011, 16:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 88
Регистрация: 14.8.2007
Где: г. Балашиха, МО

Репутация: нет
Всего: нет



Вооот! Уже почти то чно надо!
Спасибище, Entwickler!

Осталось пару вещей уяснить:
1.  //имплиментируй логику
Я тут как раз и хотел узнать, как это сделать проще/выгоднее/правильнее.
То есть не буду же я в этом сервлете создавать подключение для проверки логина/пароля,а потом на странице main.jsp для вывода содержимого таблицы, заново подключатся?
Хотелось бы в этой логике получить какой-то огбъект Connection, который был создан ранее, ну или будет создан тут впервые, а потом будет везде доступен. Вот и необходимо уяснить, что это за объект такой (ещё один сервлет или просто клкасс и JAR-ки. и как его написать/проинициализировать и сделать видимым отовсюду.

2. По поводу сервлет-фильтра.
Буду очень признателен, если приведёте маленький примерчик, чем проще, тем лучше 8)
Но, как я уже говрил, надо максимально джаватизировать приложение. А это значит что я скорее всего пойду по пути:
после проверки логина в сессию пользователя добавлю атрибут (строку какую-нибудь, что он залогинен и имеет такие-то права).
А на всех страничках сделаю инклюд какого-нибудь заголовка (другой JSP-шки), которая будет проверять наличие этого атрибута у сессии, и если его не будет - то перекидывать на login.jsp.

Кстати, если поможете кодом в осуществлении моей идеи, опять же, буду на 7ом небе от счастья. Как видите, вроде в терминологии чего-то понимаю, но практики считайте что нет. Посему и хочу тут выведать побольше. Заранее благодарю!
PM MAIL WWW ICQ   Вверх
ynblpb
Дата 16.5.2011, 12:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 29
Регистрация: 24.9.2007

Репутация: нет
Всего: нет



Можешь использовать Singleton

Код

public class MyConnection{

    static private Connection conn;

    public static Connection getConn() throws SQLException {
        try {
            Class.forName("oracle.jdbc.OracleDriver");
        } catch (ClassNotFoundException ex) {
            ex.printStackTrace();
        }
        if(!conn.isClosed())
        conn = DriverManager.getConnection("jdbc:oracle:thin:@ ....");
        return conn;
    }
}


И в коде обращайся к нему MyConnection.getConn().
Но лучше используй пул соединений.

Это сообщение отредактировал(а) ynblpb - 16.5.2011, 13:15
PM MAIL Skype   Вверх
RussianHero
  Дата 16.5.2011, 22:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 88
Регистрация: 14.8.2007
Где: г. Балашиха, МО

Репутация: нет
Всего: нет



ynblpb, как я говорил, фреймворки не хочу, да и не могу использовать. Недостаточно ещё опытен для них...

Пока что сделал вот как:
Создал сервлетв котором вот такие вот пироги:

Код

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
    {
        request.setCharacterEncoding("UTF-8");
        response.setContentType("text/html; charset=UTF-8");
        
                HttpSession ss = request.getSession(true);    //obtain session, of create new if it does not exist
        String login = request.getParameter("login");
        String pass = request.getParameter("pass");
        //Enumeration<String> Attrs = request.getSession().getAttributeNames();
        
        if(CheckUser(login, pass))
        {
            ss.setAttribute("Logged", true);        //set the "logged in" parameter
            //ss.setAttribute("SecStr", AccessStr);    //set the "security string" parameter
            response.sendRedirect("/test/common/projects.jsp");
        }
        else
        {
            response.sendRedirect("/test/error_login.jsp");
        }
    }
    
    private Boolean CheckUser(String login, String pass)
    {
        DButil.setConnection("jdbc:oracle:thin:@localhost:1521:XE", "test", "test");
        AccessStr = DButil.CheckUserAccess(login, pass);

        if (AccessStr == null)
        {
            return false;
        }
        else
        {
            DButil.setUser(login);
            return true;
        }
    }


DButil.setConnection(...)
Записывает в статическую переменную DButil.connection моё соединение. и дальше я с ним работаю.

Так что наверное вопрос по теме как бы снят, но если у кого есть ответы по моему предыдущему посту, скажу спасибо!

З.Ы. Зачем в Web.xml объявлять <servlet> ...   и <servlet-mapping>, если и без этого вроде как сервлет вызывается и нормально работает?
И что ещё вот это вот за хрень такая:
@WebServlet(description = "Servlet for authentication process", name = "LoginSvl", urlPatterns={"/LoginSvl"})
 и зачем она нужна?

PM MAIL WWW ICQ   Вверх
Entwickler
Дата 16.5.2011, 22:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 285
Регистрация: 14.4.2007

Репутация: нет
Всего: 2



Код

@WebServlet(description = "Servlet for authentication process", name = "LoginSvl", urlPatterns={"/LoginSvl"})


это то же самое что и 

Код

<servlet>
      <servlet-name>LoginSvl</servlet-name>
        <servlet-class>
          com.myclass.myservlet
        </servlet-class>
</servlet>

...

<servlet-mapping>
        <servlet-name>LoginSvl</servlet-name>
        <url-pattern>/LoginSvl</url-pattern>
    </servlet-mapping>


то есть декларирует сервлет и урл по которому ты обращаешся к нему... Servlet 3.0 спецификация.

Добавлено через 31 секунду
кстати именно по этому и не нужна декларация сервлета в web.xml...

Добавлено через 3 минуты и 33 секунды
в твоём методе используй 
Код
Boolean.TRUE
 или 
Код
Boolean.FALSE
 а не просто true и false
PM MAIL   Вверх
ynblpb
Дата 17.5.2011, 06:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 29
Регистрация: 24.9.2007

Репутация: нет
Всего: нет



Цитата(RussianHero @  16.5.2011,  20:08 Найти цитируемый пост)
ynblpb, как я говорил, фреймворки не хочу, да и не могу использовать

Это не фреймворк, это паттерн. Который говорит о том что: класс созданный таким образом будет в приложении единственным экземпляром. Хотя приведенный пример не совсем Singleton. По моему то что тебе надо... Почитай про статические переменные.
PM MAIL Skype   Вверх
RussianHero
  Дата 17.5.2011, 15:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 88
Регистрация: 14.8.2007
Где: г. Балашиха, МО

Репутация: нет
Всего: нет



Entwickler, благодарю про разъяснение о @WebServlet
Просто даже в голове не укаладывается, как это может работать и к чему это относится...

А почему это:
Цитата(Entwickler @  16.5.2011,  22:38 Найти цитируемый пост)
в твоём методе используй 
Выделить всёкод Java
1:
    
Boolean.TRUE
 или 
Выделить всёкод Java
1:
    
Boolean.FALSE
 а не просто true и false 

?
Это про return'ы?

ynblpb, фреймворк я хотя бы знаю что есть такое 8)
а при слове "паттерн" у меня в голове только регулярные выражения возникают...  smile 

Цитата(ynblpb @  17.5.2011,  06:00 Найти цитируемый пост)
Почитай про статические переменные. 


Я как бы это и сделал в своём примере - статической переменной. Но минус такой реализации-то овт в чём:
каждый раз, когда у меня вызывается сервлет, у меня вызывается DButil.setConnection(...), а это значит, что если пользователь ввёл пароль неправильно 10 раз, у меня 10 раз создавалось подключение заново.  smile 
Я как бы и хотел этого избежать.

PM MAIL WWW ICQ   Вверх
Entwickler
Дата 17.5.2011, 16:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 285
Регистрация: 14.4.2007

Репутация: нет
Всего: 2



для того чтобы не создавать по 10 "коннектов", как я уже и говорил используй Connection Pooling! Коннекты хронятся в poole и ты берешь просто себе один использовал и назад в pool! 

смотри: Connection Pooling

Добавлено через 1 минуту и 2 секунды
а другого пути кроме как постоянно создавать новое соединение нет
PM MAIL   Вверх
RussianHero
  Дата 17.5.2011, 21:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 88
Регистрация: 14.8.2007
Где: г. Балашиха, МО

Репутация: нет
Всего: нет



Entwickler, спасибо за ссылочку. Очень интересно, коротко и ясно. Буду иметь в виду.

Так по чему лучше Boolean.TRUE и Boolean.FALSE? из-за того что указатель что ли передаётся а не значение?

З.Ы. Где таких умных держат? 8)
Где работаете или чем занимаетесь, если не секрет? Просто по-моему, люди шарящие очень хорошо в вёб-джаве - это самые востребованные ай-тишники в ближайшем будущем да и сегодня.
PM MAIL WWW ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Java"
LSD   AntonSaburov
powerOn   tux
  • Прежде, чем задать вопрос, прочтите это!
  • Книги по Java собираются здесь.
  • Документация и ресурсы по Java находятся здесь.
  • Используйте теги [code=java][/code] для подсветки кода. Используйтe чекбокс "транслит", если у Вас нет русских шрифтов.
  • Помечайте свой вопрос как решённый, если на него получен ответ. Ссылка "Пометить как решённый" находится над первым постом.
  • Действия модераторов можно обсудить здесь.
  • FAQ раздела лежит здесь.

Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Java EE (J2EE) и Spring | Следующая тема »


 




[ Время генерации скрипта: 0.1429 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.