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)