Peter Penzov
Peter Penzov

Reputation: 1716

JSF - how to insert into database table many values

I have this form which can insert/update values into database table.

                  <div id="settingsdiv" style="width:350px; height:400px; position:absolute;  background-color:r; top:20px; left:1px">
                    <h:form>
                    <h:panelGrid columns="2">
                        <h:panelGroup>User Session Timeout</h:panelGroup>
                        <h:panelGroup>
                            <h:selectOneMenu value="#{ApplicationController.setting['SessionTTL']}">
                                <f:selectItem itemValue="#{ApplicationController.setting['SessionTTL']}" itemLabel="#{ApplicationController.setting['SessionTTL']}" />
                                <f:selectItem itemValue="two" itemLabel="Option two" />
                                <f:selectItem itemValue="three" itemLabel="Option three" />
                                <f:selectItem itemValue="custom" itemLabel="Define custom value" />
                                <f:ajax render="input" />
                            </h:selectOneMenu>
                            <h:panelGroup id="input">
                                <h:inputText value="#{ApplicationController.setting['SessionTTL']}" rendered="#{ApplicationController.setting['SessionTTL'] == 'custom'}" required="true" />
                            </h:panelGroup>

                        </h:panelGroup>

                        <h:panelGroup>Maximum allowed users</h:panelGroup>
                        <h:panelGroup></h:panelGroup>                                                                     
                    </h:panelGrid>                         
                        <h:commandButton value="Submit" action="#{ApplicationController.UpdateDBSettings()}"/>
                    </h:form>                                   
                </div>   

I know that I can send values to managed bean using setter method and insert them into database with sql query. What if I have for example 40 values for which I have to write setter method for each one of it. Is there other more quick solution for inserting many values from JSF page into database table?

Best wishes Peter

UPDATE

Here is the code so far that I have done:

the JSF page:

<div id="settingsdiv" style="width:350px; height:400px; position:absolute;  background-color:r; top:20px; left:1px">
    <h:form>
    <h:panelGrid columns="2">
        <h:panelGroup>User Session Timeout</h:panelGroup>
        <h:panelGroup>
            <h:selectOneMenu value="#{ApplicationController.settings['SessionTTL']}">
                <f:selectItem itemValue="#{ApplicationController.settings['SessionTTL']}" itemLabel="#{ApplicationController.settings['SessionTTL']}" />
                <f:selectItem itemValue="two" itemLabel="Option two" />
                <f:selectItem itemValue="three" itemLabel="Option three" />
                <f:selectItem itemValue="custom" itemLabel="Define custom value" />
                <f:ajax render="input" />
            </h:selectOneMenu>
            <h:panelGroup id="input">
                <h:inputText value="#{ApplicationController.settings['SessionTTL']}" rendered="#{ApplicationController.settings['SessionTTL'] == 'custom'}" required="true" />
            </h:panelGroup>

        </h:panelGroup>

        <h:panelGroup>Maximum allowed users</h:panelGroup>
        <h:panelGroup></h:panelGroup>                                                                     
    </h:panelGrid>                         
        <h:commandButton value="Submit" action="#{ApplicationController.UpdateDBSettings()}"/>
    </h:form>                         
</div>  

The managed bean:

package com.DX_57.SM_57;
/* include default packages for Beans */
import java.io.Serializable;
import javax.enterprise.context.SessionScoped;
// or import javax.faces.bean.SessionScoped;
import javax.inject.Named;
/* include SQL Packages */
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;
import javax.annotation.PostConstruct;
import javax.sql.DataSource;
import javax.annotation.Resource;
import javax.faces.context.FacesContext;
import javax.inject.Inject;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
// or import javax.faces.bean.ManagedBean;   

import org.glassfish.osgicdi.OSGiService;

@Named("ApplicationController")
@SessionScoped
public class Application implements Serializable {

    /* This Hash Map will be used to store setting and value */
    private HashMap<String, String> settingsMap = null;    
    private HashMap<String, String> updatedSettingsMap = null;

    public Application(){     
    }   

    /* Call the Oracle JDBC Connection driver */
    @Resource(name = "jdbc/Oracle")
    private DataSource ds;


    /* Hash Map
     * Send this hash map with the settings and values to the JSF page
     */
    public HashMap<String, String> getsettings(){
        return settingsMap;        
    }

    /* Hash Map
     * Returned from the JSF page with the updated settings
     */
    public HashMap<String, String> setsettings(){
        return updatedSettingsMap;
    }

    /* Get a Hash Map with settings and values. The table is genarated right 
     * after the constructor is initialized. 
     */
    @PostConstruct
    public void initSettings() throws SQLException
    {        
        settingsMap = new HashMap<String, String>();

        if(ds == null) {
                throw new SQLException("Can't get data source");
        }
        /* Initialize a connection to Oracle */
        Connection conn = ds.getConnection(); 

        if(conn == null) {
                throw new SQLException("Can't get database connection");
        }
        /* With SQL statement get all settings and values */
        PreparedStatement ps = conn.prepareStatement("SELECT * from GLOBALSETTINGS");

        try
        {
            //get data from database        
            ResultSet result = ps.executeQuery();
            while (result.next())
            {
               settingsMap.put(result.getString("SettingName"), result.getString("SettingValue"));
            }            
        }
        finally
        {
            ps.close();
            conn.close();         
        }        
    }

    /* Update Settings Values */
    public String UpdateDBSettings(String userToCheck) throws SQLException {


        //here the values from the updatedSettingsMap will be inserted into the database

            String storedPassword = null;        
            String SQL_Statement = null;

            if (ds == null) throw new SQLException();      
       Connection conn = ds.getConnection();
            if (conn == null) throw new SQLException();      

       try {
            conn.setAutoCommit(false);
            boolean committed = false;
                try {
                       SQL_Statement = "Update GLOBALSETTINGS where sessionttl = ?";

                       PreparedStatement updateQuery = conn.prepareStatement(SQL_Statement);
                       updateQuery.setString(1, userToCheck);

                       ResultSet result = updateQuery.executeQuery();

                       if(result.next()){
                            storedPassword = result.getString("Passwd");
                       }

                       conn.commit();
                       committed = true;
                 } finally {
                       if (!committed) conn.rollback();
                       }
            }
                finally {               
                conn.close();

                }  

       return storedPassword;       
       }    


}

I suppose that this code is correct and will work.

Upvotes: 0

Views: 5950

Answers (1)

BalusC
BalusC

Reputation: 1109570

I don't forsee problems. Just keep them in a Map like as you already have, then you need just only one getter. JSF will already set the updated value straight in the Map. You just have to call service.update(settings).


Update: as requested, it should just look something like this:

@ManagedBean
@ViewScoped
public class Admin {

    private Map<String, String> settings;

    @EJB
    private SettingsService service;

    @PostConstruct
    public void init() {
        settings = service.getAll();
    }

    public void save() {
        service.update(settings);
    }

    public Map<String, String> getSettings() {
        return settings;
    }

}

with

<h:form>
    <h:inputSomething value="#{admin.settings['key1']}" ... />
    <h:inputSomething value="#{admin.settings['key2']}" ... />
    <h:inputSomething value="#{admin.settings['key3']}" ... />
    <h:inputSomething value="#{admin.settings['key4']}" ... />
    <h:inputSomething value="#{admin.settings['key5']}" ... />
    ...
    <h:commandButton value="Save" action="#{admin.save}" />
</h:form>

Note that you do not need a setter for settings. JSF will use Map's own put() method to update the map with submitted values. The same also applies to all other complex properties referencing an array or a collection or a nested bean like Object[], List<E>, SomeBean, etc. The setter is only called for simple properties like String, Integer, etc.

Upvotes: 3

Related Questions