работа с базой данных

Работа с базой данных MySql в Java

Это 5 статья из цикла статей: «Простой сайт на Java» и сегодня мы поговорим о работе с базой данных. На повестке дня:

  • создание записи;
  • выбор всех записей;
  • изменение, удаление записей;
  • выбор по определенному параметру.

Для создания запроса создается объект PreparedStatement. Его удобнее использовать для отправки операторов SQL в базу данных. Этот особый тип инструкции выводится из более общего класса, Statement.

PreparedStatement создается не как обычный новый объект. Он берется как результат метода prepareStatement объекта Connection. Общий вид записи будет выглядеть так:

Код    
  1. Connection con = ConnectionPool.getInstance().getConnection(); - получение соединения с базой данных
  2. PreparedStatement pr = con.prepareStatement("SQL запрос");

Чтобы выполнить запрос нужно вызвать метод executeUpdate() для создания, редактирования, удаления записи или executeQuery() для извлечения записи. Метод executeQuery() возвращает ResultSet объект из которого уже можно получить данные и использовать их для наших целей. Чтобы долго не расписывать теорию предлагаю сразу перейти к примерам.

В прошлой статье мы уже создали базу данных и создали пул соединений. Теперь пришло время поработать с базой.

В этой статье будет показано пример работы с таблицей Article. Работу с остальными доменными классами можно будет посмотреть в видео или скачать готовый код, который будет в конце статьи.

Для начала нужно извлечь все данные с таблицы article:

Код    
  1. public List<Article> getAllArticles() {
  2.         List<Article> articles = new ArrayList<Article>();//создаем список статей. пока пустой
  3.         Article article = null;
  4.         Connection con = ConnectionPool.getInstance().getConnection();
  5.         try {//PreparedStatement выбрасывает SQLException. Поэтому, нужно всегда следить за тем, чтобы код был обработан обработчиком try-catch
  6.             PreparedStatement pr = con.prepareStatement("select id, title, body, category_id, users_id from article");
  7.             ResultSet rs = pr.executeQuery();
  8.             while (rs.next()){//пока у ResultSet есть данные
  9.                 article = new Article();
  10.                 article.setId(rs.getInt(1));//вынимаем данные в том порядке, в котором мы указали в запросе. Можно выбирать не по
  11. //цифре, а по имени поля в таблице базы например можно было бы указать rs.getInt("id")
  12.                 article.setTitle(rs.getString(2));
  13.                 article.setBody(rs.getString(3));
  14.                 Category category = new Category();//не забываем о вложенных объектах
  15.                 category.setId(rs.getInt(4));
  16.                 article.setCategory(category);
  17.                 Users user = new Users();
  18.                 user.setId(rs.getInt(5));
  19.                 article.setUsers(user);
  20.                 articles.add(article);
  21.             }
  22.         } catch (SQLException e) {
  23.             // TODO Auto-generated catch block
  24.             e.printStackTrace();
  25.         }
  26.         try {
  27.             con.close();//после выполнения запроса нужно закрыть соединение
  28. //метод close тоже выбрасывает исключение. Для избежания громоздких записей лучше обработать исключение один раз в отдельном методе например closeConnection
  29. //и потом вызывать только его
  30.         } catch (SQLException e) {
  31.             // TODO Auto-generated catch block
  32.             e.printStackTrace();
  33.         }
  34.         return articles;
  35.     }

Такой же механизм и в выборе данных по определенному критерию:

Код    
  1. public Article getArticleById(int id) {
  2.         Article article = null;
  3.         Connection connection = ConnectionPool.getInstance().getConnection();
  4.         try {
  5.             PreparedStatement pr = connection.prepareStatement("select id, title, body, "
  6.                     + "category_id, users_id from article where id=?");
  7.             pr.setInt(1, id);//то, что нужно вставить вместо первого знака вопроса
  8. //можно было бы написать "select id, title, body, " + "category_id, users_id from article where id="+id в запросе
  9. //но в целях безопасности советую подставлять значение через метод сет.
  10.             ResultSet rs = pr.executeQuery();
  11.             if (rs.next()){
  12.                 article = new Article();
  13.                 article.setId(rs.getInt(1));
  14.                 article.setTitle(rs.getString(2));
  15.                 article.setBody(rs.getString(3));
  16.                 Category category = new Category();
  17.                 category.setId(rs.getInt(4));
  18.                 article.setCategory(category);
  19.                 Users user = new Users();
  20.                 user.setId(rs.getInt(5));
  21.                 article.setUsers(user);
  22.             }
  23.         } catch (SQLException e) {
  24.             // TODO Auto-generated catch block
  25.             e.printStackTrace();
  26.         }
  27.         try {
  28.             connection.close();
  29.         } catch (SQLException e) {
  30.             // TODO Auto-generated catch block
  31.             e.printStackTrace();
  32.         }
  33.         return article;
  34.     }

Для создания записи нужно только заменить pr.executeQuery(); на pr.executeUpdate();

Код    
  1. public int createArticle(Article article) {
  2.         Connection con = ConnectionPool.getInstance().getConnection();
  3.         try {
  4.             PreparedStatement pr = con.prepareStatement("insert into "
  5.                     + "article(title, body, category_id, users_id) values(?,?,?,?)");
  6.             pr.setString(1, article.getTitle());
  7.             pr.setString(2, article.getBody());
  8.             pr.setInt(3, article.getCategory().getId());
  9.             pr.setInt(4, 1);
  10.             pr.executeUpdate();
  11.         } catch (SQLException e) {
  12.             // TODO Auto-generated catch block
  13.             e.printStackTrace();
  14.             try {
  15.                 con.close();
  16.             } catch (SQLException e1) {
  17.                 // TODO Auto-generated catch block
  18.                 e1.printStackTrace();
  19.             }
  20.             return 0;
  21.            
  22.         }
  23.         try {
  24.             con.close();
  25.         } catch (SQLException e) {
  26.             // TODO Auto-generated catch block
  27.             e.printStackTrace();
  28.         }
  29.         return 1;//чтобы контролировать выполнение запроса можно выводить переменную в зависимости от успешность или неудачи выполнения запроса.
  30. //можно также выводить айди объекта, который был добавлен в базу.
  31.     }

Ну и бонусом скину код для обновления и удаления записи:

Код    
  1. public int editArticle(Article article) {
  2.         int result = 0;
  3.         Connection con = ConnectionPool.getInstance().getConnection();
  4.         try {
  5.             PreparedStatement pr = con.prepareStatement("update article set "
  6.                     + "title=?, body=?, category_id=?");
  7.             pr.setString(1, article.getTitle());
  8.             pr.setString(2, article.getBody());
  9.             pr.setInt(3, article.getCategory().getId());
  10.             result = pr.executeUpdate();
  11.         } catch (SQLException e) {
  12.             // TODO Auto-generated catch block
  13.             e.printStackTrace();
  14.         }
  15.         try {
  16.             con.close();
  17.         } catch (SQLException e) {
  18.             // TODO Auto-generated catch block
  19.             e.printStackTrace();
  20.         }
  21.         return result;
  22.     }
  23.  
  24.     public void deleteArticle(int id) {
  25.         Connection con = ConnectionPool.getInstance().getConnection();
  26.         try {
  27.             PreparedStatement pr = con.prepareStatement("delete from article where id=?");
  28.             pr.setInt(1, id);
  29.             pr.executeUpdate();
  30.         } catch (SQLException e) {
  31.             // TODO Auto-generated catch block
  32.             e.printStackTrace();
  33.         }
  34.         try {
  35.             con.close();
  36.         } catch (SQLException e) {
  37.             // TODO Auto-generated catch block
  38.             e.printStackTrace();
  39.         }
  40.        
  41.     }

Как видите, работать с базой через стандартный jdbc просто но неудобно: записи получаются громоздкие, нужно постоянно обрабатывать возможные ошибки, ошибиться в коде очень легко, пропустил символ в строке выбора и код не работает. И это у нас еще небольшая база. Понятно, что легче всего пользоваться фреймоворками типа Hibernate, Spring JPA. Эти инструменты очень облегчают жизнь.

Наш случай — научиться и понять, как все работает на начальных уровнях. Ведь все фреймворки строятся на этом.

Код на гитхаб: https://github.com/caligula95/simplewebapp-part5

Видео на ютуб:

Добавить комментарий