I have a hard time understanding on how to user MVC pattern in my java based web application.
I have multiple tables (postgreSQL 9.4) and the data stored there is going to be visible to multiple users.
As far as my understanding goes I need a Model (which holds all data from the DB tables) and any user who wants to view any of this data uses a view to do so.
Right now I have a class that is full of getter methods. Each of those asks the database to provide the stored data from a specific sql table. That data is then retured as a json String into my .jsp page and there I fill this data into a html table (.jsp just hols the table construct)
This is sort of a model, except the fact that data is just pulled from the db and given to the jsp to display.
From there on, how can I assure that all users always have the same view on the data and data is always up to date even when user A makes changes to the data that other users are also looking at??
As I have multiple db tables do I need a model for each table?
EDIT: The way I would approach this issue would be the following.
- I have a class (model) for each database table.
- On Application startup I pull the data from the SQL table and store it inside the specific class
- If any user wants to view data I have a getter Method in each model class to send this data to the .jsp page for display
- If any user does changes to the database (setter method) the data is (after the set method is executed) pulled again so the model is up to date
- Then I somehow need the data that is viewed by any user is updated on the .jsp page
Is this going in the same direction as MVC pattern?
EDIT1:
An example
One of my SQL tables looks like this
CREATE TABLE users ( id serial NOT NULL, user character varying(50) NOT NULL, CONSTRAINT users_pkey PRIMARY KEY (id) ) My Model class looks like this:
public class Users extends HttpServlet implements Servlet{ private List<List<String>> users = new ArrayList<List<String>>(); private void load_userData(){ // Code to pull data from database /**/ List<List<String>> users = new ArrayList<List<String>>(2); // instantiate array list users.add(new ArrayList<String>()); users.add(new ArrayList<String>()); try { m_ResultSet = database_connection.execute_querry_on_db(query); while (m_ResultSet.next()) { users.get(0).add(m_ResultSet.getString("id")); users.get(1).add(m_ResultSet.getString("user")); } } catch (SQLException ex) { Logger.getLogger(Login.class.getName()).log(Level.SEVERE, null, ex); } // store pulled data into model this.users = users ; } private List<List<String>> get_userData(){ // Code to pull data from Model return users; } private void set_userData(){ // make changes to SQL table with an update/insert query // Update Model with new data since it has been altered get_userData(); } @Override public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{ String requested_values = request.getParameter("type"); if("get_users".equals(requested_values)){ String json_users = new Gson().toJson(get_userData()); // write JSON string to response response.getWriter().write(json_users); } } } This way the model is always up to date with the actual data from the database.
Since there is model & controller in the same class a possible controller would look like the one below??
Because using a controller like this I have to some "initialisation" in a main area of my code I guess, but that is not clear to me..
public class User_Controller extends HttpServlet implements Servlet{ private User_data model; public OE_Controller(User_data model){ this.model = model; } private List<List<String>> get_userData(){ return model.users; } @Override public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{ String requested_values = request.getParameter("type"); if("get_users".equals(requested_values)){ String json_users = new Gson().toJson(get_userData()); // write JSON string to response response.getWriter().write(json_users); } } } ####### Solution to MVC-"Problem" ####### What do you think about this solution? (as the controller will hand out data directly, instead of calling a method from "main")
Users.java (Model)
public class Users{ private List<List<String>> users = new ArrayList<List<String>>(); public List<List<String>> get_users(){ return users; } // Fill model with data from database public void pull_UserData(){ /**/ List<List<String>> users = new ArrayList<List<String>>(2); // instantiate array list users.add(new ArrayList<String>()); users.add(new ArrayList<String>()); try { m_ResultSet = database_connection.execute_querry_on_db(query); while (m_ResultSet.next()) { users.get(0).add(m_ResultSet.getString("id")); users.get(1).add(m_ResultSet.getString("user")); } } catch (SQLException ex) { Logger.getLogger(Login.class.getName()).log(Level.SEVERE, null, ex); } /**/ this.users = users; } } User_Controller.java (Controller)
public class User_Controller extends HttpServlet implements Servlet{ private Users model; public User_Controller(Users model){ this.model = model; } public List<List<String>> get_users(){ return model.get_users(); } @Override public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{ String requested_values = request.getParameter("type"); if("get_users".equals(requested_values)){ String json_users = new Gson().toJson(get_users()); // write JSON string to response response.getWriter().write(json_users); } } } "MAIN"
// create Model Users model = pull_UserData(); // create Controller User_Controller controller = new User_Controller(model); // get Model data controller.get_oes(); // Even though I will never access Model data from here since // my Controller will hand out the data via the do_Get() method // "Main" is just to load the model data once on application startup // and the model data reload is done after a setter method is executed public static Users fill_model_Users_data(){ Users users = new Users(); users.pull_UserData(); return users; } What is left is to have the data always updated on all session in the frontend.
So each user of my application needs to see the same data. Here I would need a listener that refreshes the .jsp page when another user does changes to the database. How would I do this??
EDIT: I found some solutions working with a time interval to check for new data but that still leaves me with the problem that there is a data mismatch based on how long the timer interval is & setting the interval to 1ms for example cannot be the optimal solution I guess (there has to be a "smoother" way to do that)
I'd rather have the application to update the .jsp page with new data as soon as there is new data available & even then I'm left with the Race-Condition which user is faster in clicking a button to lets say delete a user (one will succeed & one will fail)