Научитесь программировать в сервлете Java подключение к БД - PullRequest
0 голосов
/ 14 сентября 2018

Я учусь программировать на Java и использовать страницу сервлета и jsp.

У меня возникли проблемы с пониманием того, как я могу установить соединение с базой данных. В частности, у меня есть страница Java с именем Database.java, где я создаю соединение с базой данных и на которой есть все выполняемые функции. И я создал страницу под названием Prenotation.java, где я должен выполнить некоторые действия. Моя проблема в том, что я не хотел бы оставлять соединение с базой данных на этой странице (как вы можете видеть из кода), но я хотел бы установить соединение через страницу Database.java. Я пробовал несколько раз, но я не понимаю, как я могу это сделать. Вы можете дать мне какой-то совет? Спасибо.

Database.java

package db;
import java.math.BigDecimal;
import java.sql.*;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.concurrent.TimeUnit;

import entity.*;

public class Database {

    private Connection connection = null;
    private PreparedStatement statement = null;
    private ResultSet rs = null;

    private String dbname = "Hotel";
    String nomeutente = "root";
    String password = "123456789";
     private static Database db = null;

    public static synchronized Database getDatabase() {
        if (db == null) {
            db = new Database();
        }
        return db;
    }
    private Database() {
        try {
            Class.forName("com.mysql.jdbc.Driver").newInstance();
            connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/" + dbname 
                    + "?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC",
                    nomeutente, password);
        } catch (Exception exc) {
            exc.printStackTrace();
        }
    }
    public Connection getConnection() {
        return connection;
    }
    public boolean checkUser(String email, String password) throws SQLException {
        boolean result = false;
        String query = "select password from users where email=?";

            statement = connection.prepareStatement(query);
            statement.setString(1, email);
            rs = statement.executeQuery();
            if (rs.next() && password.equals(rs.getString("password"))) {
                result = true;
            }

            rs.close();
            statement.close();

        return result;
    }
    public boolean existingMail(String email) throws SQLException {
        String query = "select * from users where email=?";
        boolean result = true;
        statement = connection.prepareStatement(query);
        statement.setString(1, email);
        rs = statement.executeQuery();

        if (rs.next()) {
            result = true;
        } else {
            result = false;
        }
        rs.close();
        statement.close();
        return result;
    }

    public boolean insertUtente(Utente u,String password) throws SQLException {
         String query = "INSERT INTO users (email,nome,cognome,luogodinascita,datadinascita,indirizzo,password) VALUES (?,?,?,?,?,?,?)";
         if(existingMail(u.getEmail())) {
             return false;
         } 
            statement = connection.prepareStatement(query);
            statement.setString(1, u.getEmail());
            statement.setString(2, u.getNome());
            statement.setString(3, u.getCognome());
            statement.setString(4, u.getLuogodinascita());
            statement.setString(5, u.getDatadinascita());
            statement.setString(6, u.getIndirizzo());
            statement.setString(7, password);
            statement.execute();
            statement.close();
            return true;

    }

    public Utente getUtente(String email) throws SQLException {
        String query= "select * from users where email=?";
        statement = connection.prepareStatement(query);
        statement.setString(1, email);
        rs=statement.executeQuery();
        if(!rs.next()) {
            return null;
        }
        Utente u=new Utente(email,rs.getString("nome"),rs.getString("cognome"),rs.getString("datadinascita"),rs.getString("luogodinascita"),rs.getString("indirizzo"));
        rs.close();
        statement.close();
        return u;
    }

    public boolean modificaPassword(String email, String password) throws SQLException {
        String query="UPDATE users SET password='"+password+"' WHERE email='"+email+"'";   
        Statement statement=connection.createStatement();
        statement.executeUpdate(query);
        statement.close();
        return true;
    }
    public boolean modificaProfilo(Utente u) throws SQLException {
        String query="UPDATE users SET nome = ?, cognome = ?, datadinascita = ?, luogodinascita = ?, indirizzo = ? WHERE email = ?";
        statement = connection.prepareStatement(query);
        statement.setString(1, u.getNome());
        statement.setString(2, u.getCognome());
        statement.setString(3, u.getDatadinascita());
        statement.setString(4, u.getLuogodinascita());
        statement.setString(5, u.getIndirizzo());
        statement.setString(6, u.getEmail());
        statement.executeUpdate();
        statement.close();
        return true;
    }}

Это страница, о которой я говорю

package servlet;
import java.io.IOException;
import java.io.PrintWriter;
import java.sql.*;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.swing.JOptionPane;
import db.Database;
import entity.Prenotazione;
/**
 *
 * @author OOPs
 */
public class Prenotation extends HttpServlet {

    private static final String ResultSet = null;

    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        HttpSession session=request.getSession();
         String idPrenotazione = request.getParameter("idPrenotazione");
         String email = request.getParameter("email");
         int typeRoom = Integer.parseInt(request.getParameter("typeRoom"));;
         String arrivalDate = request.getParameter("arrivalDate");
         String departureDate = request.getParameter("departureDate");
         response.setContentType("text/html;charset=UTF-8");
         PrintWriter out = response.getWriter();

       try {

            Class.forName("com.mysql.cj.jdbc.Driver");
      //  out.println("driver loaded");
            Connection  con = DriverManager.getConnection("jdbc:mysql://localhost:3306/Hotel?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC","root" ,"123456789");
            out.println("Connect");


            Statement  st =  con.createStatement();
           // Statement stmt = con.createStatement();
            out.println("connection successfull");
            int total = 0;
            PreparedStatement ps = con.prepareStatement( "SELECT COUNT(*) as total FROM reservation WHERE typeRoom = ? AND (? >= arrivaldate AND ? <= departuredate) OR (? >= arrivaldate AND ? <= departuredate)");

            int c = 0;
            ps.setInt(++c, typeRoom);
            ps.setString(++c, arrivalDate);
            ps.setString(++c, departureDate);
            ps.setString(++c, arrivalDate);
            ps.setString(++c, departureDate);

            ResultSet rs = ps.executeQuery();

           // ResultSet rs2  = stmt.executeQuery(check);
            out.println("<h1> Stringa check eseguito </h1>");

            if( total  > 0) { 
            //  response.sendRedirect("home.jsp");
                response.sendRedirect("PrenotazioneNegata.jsp");
            }
            else {
             st.executeUpdate("insert into reservation (email,typeRoom,arrivalDate,departureDate)values ('"+email+"','"+typeRoom+"','"+arrivalDate+"','"+departureDate+"')");
             response.sendRedirect("PrenotazioneAvvenuta.jsp");
            }
          out.println("<h1> Registrazione Eseguita </h1>");

        }catch(Exception e){
        out.println("Errore." +e);
        }
        finally {
            out.close();
        }
    }

    // <editor-fold defaultstate="collapsed" desc="HttpServlet methods. Click on the + sign on the left to edit the code.">
    /**
     * Handles the HTTP <code>GET</code> method.
     *
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    /**
     * Handles the HTTP <code>POST</code> method.
     *
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    /**
     * Returns a short description of the servlet.
     *
     * @return a String containing servlet description
     */
    @Override
    public String getServletInfo() {
        return "Short description";
    }// </editor-fold>

}

1 Ответ

0 голосов
/ 14 сентября 2018

Веб-контейнер обычно направляет запросы в один и тот же экземпляр сервлета, поэтому он должен быть потокобезопасным.В настоящее время класс Database предоставляет единственное соединение, которое будет использоваться параллельными запросами, поэтому оно не будет потокобезопасным.

Рассмотрите возможность создания чего-то вроде ConnectionFactory класса.Например:

public class ConnectionFactory {
    public Connection getConnection() {
        // move all the creation code from Database class to here
        // create and return a new instance
    }
}

Затем измените класс Database, чтобы использовать фабрику

public class Database {
   private final ConnectionFactory connectionFactory;

   public Database(ConnectionFactory connectionFactory) {
      this.connectionFactory = connectionFactory;
   }

   // change to private and use the factory
   private Connection getConnection() {
      return connectionFactory.getConnection();
   }

   // example method to be used by servlet
   public int getTotalReservations(int typeRoom, String arrivalDate, departureDate) {
      // query related code currently in serlvet goes here...
   }
}

И используйте метод жизненного цикла сервлета init() для создания объектов, чтобы сервлет мог использоватьЭто.Например:

public class Prenotation extends HttpServlet {
    private Database database;

    @Override
    public void init()  throws ServletException {
        super.init();
        this.database = new Database(new ConnectionFactory());  // no statics needed!
    }

protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    HttpSession session=request.getSession();
     String idPrenotazione = request.getParameter("idPrenotazione");
     String email = request.getParameter("email");
     int typeRoom = Integer.parseInt(request.getParameter("typeRoom"));;
     String arrivalDate = request.getParameter("arrivalDate");
     String departureDate = request.getParameter("departureDate");
     response.setContentType("text/html;charset=UTF-8");
     PrintWriter out = response.getWriter();

    // use the method from `Database` which knows how to query the DB.
    int totalReservations = database.getTotalReservations(typeRoom, arrivalDate, departureDate);

    // more processing... and forward to the JSP
}

Обратите внимание, что Database теперь относится как к таблице USERS, так и к таблице RESERVATTIONS.Было бы лучше разделить их на отдельные классы, такие как UsersQuery и ReservationsQuery.Они оба могут совместно использовать один и тот же ConnectionFactory экземпляр.

См. Также:

  • принцип единой ответственности
  • инверсия управления (введение ConnectionFactory в Database)
  • жизненный цикл сервлета
  • , почему статические переменные (или одиночные символы) являются / могут быть злыми
  • Источник данных (вместо низкого уровня ConnectionFactory)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...