Sunday, 17 June 2012

MVVM–List Item–Hibernate–MySQL–Part 2

In the part 1, we have seen, how to list the records from DB using ZK List box. Now let us go further and see how we can add new record and edit exiting record and update into DB.
In this post, we will see how we can do the following stuffs
1. Add new person by calling a model window in MVVM and update in the DB
2. On Double click of the records in the list item, edit the existing record by calling a modal window in MVVM and update in the DB
3. Then after edit and add, we will refresh the list. Note, after edit, we no need to do anything, because data binding will take care. But after adding new person, we will refresh the list using Global command

Left hug     Many thanks to potix Jimmy who helped me to complete this part 2. http://www.zkoss.org/forum/listComment/19829-ZK-MVVM-Modal-Window

ZK Version : ZK 6

Project Name :ListItemMVVMHibernate

Project Structure;

image

Demo.zul



<?page title="Listitem MVVM Demo with Hibernate" contentType="text/html;charset=UTF-8"?>
<zk>
    <style>
        .z-listcell.red .z-listcell-cnt, .z-label.red{ color:red; }
    </style>
    <window title="Listitem MVVM Demo with Hibernate" border="normal"
        apply="org.zkoss.bind.BindComposer"
        viewModel="@id('myvm') @init('domainVMS.PersonVM')">
        <div>
            <button label="Add Person"
                onClick="@command('addNewPerson')" />
        </div>
        <separator />

        <listbox id="test" model="@load(myvm.allPersons)"
            selectedItem="@bind(myvm.curSelectedPerson)">
            <listhead sizable="true">
                <listheader label="First Name" width="400px"
                    sort="auto(firstName)" />
                <listheader label="Last Name" width="285px"
                    sort="auto(lastName)" />
                <listheader label="email" width="285px"
                    sort="auto(email)" />
            </listhead>
            <template name="model" var="p1">
                <listitem onDoubleClick="@command('onDoubleClicked')">
                    <listcell label="@load(p1.firstName)"
                        sclass="@load(empty p1.email ?'red':'')" />
                    <listcell label="@load(p1.lastName)"
                        sclass="@load(empty p1.email ?'red':'')" />
                    <listcell label="@load(p1.email)" />
                </listitem>
            </template>
        </listbox>
    </window>
</zk>



AddPerson.zul

<zk>
    <window id="win" title=" " width="520px" height="220px"
        border="normal" minimizable="false" mode="modal" maximizable="false"
        closable="true" action="show: slideDown;hide: slideUp"
        apply="org.zkoss.bind.BindComposer" 
        viewModel="@id('vm') @init('domainVMS.PersonCRUDVM')"  >
        <separator />
        <label value="Person information" />
        <separator />
        <panel width="100%">
            <panelchildren>
                <separator />
                <grid width="99.5%">
                    <columns>
                        <column label="" width="150px" />
                        <column label="" />
                    </columns>
                    <rows>
                        <row>
                            <hbox>
                                <label value="First Name" />
                                <label value="*" />
                            </hbox>
                            <textbox name="firstName"
                                value="@bind(vm.selectedPerson.firstName)" cols="50" />
                        </row>
                        <row>
                            <hbox>
                                <label value="Last Name" />
                                <label value="*" />
                            </hbox>
                            <textbox name="firstName"
                                value="@bind(vm.selectedPerson.lastName)" cols="50" />
                        </row>
                        <row>
                            <hbox>
                                <label value="email" />
                                <label value="*" />
                            </hbox>
                            <textbox name="email"
                                value="@bind(vm.selectedPerson.email)" cols="50" />
                        </row>
                    </rows>
                </grid>
            </panelchildren>
        </panel>
        <separator />
        <div align="center">
            <button label="Submit" onClick="@command('save')" />
            <button label="Cancel"  onClick="@command('closeThis')" />
        </div>
    </window>
</zk>



PersonDAO.java

package domainDAO;

import java.util.List;
import org.hibernate.Session;
import org.hibernate.Query;
import org.zkoss.zul.Messagebox;

import HibernateUtilities.HibernateUtil;
import mydomain.Person;

public class PersonDAO {

    @SuppressWarnings("unchecked")
    public List<Person> getAllPersons() {
        List<Person> allrecords = null;
        try {
            Session session = HibernateUtil.beginTransaction();
            Query q1 = session.createQuery("from Person");
            allrecords = q1.list();
            HibernateUtil.CommitTransaction();
        } catch (RuntimeException e) {
            e.printStackTrace();
        }
        return allrecords;
    }

    public void saveOrUpdate(Person p1) {

        try {
            Session session = HibernateUtil.beginTransaction();
            session.saveOrUpdate(p1);
            HibernateUtil.CommitTransaction();
        } catch (RuntimeException e) {
            e.printStackTrace();
        }

    }
}


PersonCRUDVM.java


package domainVMS;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.zkoss.bind.BindUtils;
import org.zkoss.bind.annotation.Command;
import org.zkoss.bind.annotation.ContextParam;
import org.zkoss.bind.annotation.ContextType;
import org.zkoss.bind.annotation.ExecutionArgParam;
import org.zkoss.bind.annotation.Init;
import org.zkoss.bind.annotation.NotifyChange;
import org.zkoss.zul.Messagebox;
import org.zkoss.zk.ui.Component;
import domainDAO.PersonDAO;
import mydomain.Person;
import org.zkoss.zk.ui.select.Selectors;
import org.zkoss.zk.ui.select.annotation.Wire;
import org.zkoss.zul.Window;

public class PersonCRUDVM {
    
    @Wire("#win")
    private Window win;
    
    private Person selectedPerson;
    
    public Person getSelectedPerson() {
        return selectedPerson;
    }

    public void setSelectedPerson(Person selectedPerson) {
        this.selectedPerson = selectedPerson;
    }

    @Init
    public void initSetup(@ContextParam(ContextType.VIEW) Component view, @ExecutionArgParam("selectedPerson") Person selectedPerson) {
        Selectors.wireComponents(view, this, false);
        if (selectedPerson == null)
            this.selectedPerson = new Person();
        else
            this.selectedPerson = selectedPerson;
        
    }
    
    @Command 
    public void save() {
        new PersonDAO().saveOrUpdate(this.selectedPerson);
        Map args = new HashMap();
        args.put("newadded", this.selectedPerson); 
        BindUtils.postGlobalCommand(null, null, "refreshList", args);
        win.detach();
    }
    
    @Command 
    public void closeThis() {
        win.detach();
    }
}


PersonVM.java


package domainVMS;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import mydomain.Person;
import org.zkoss.bind.annotation.Command;
import org.zkoss.bind.annotation.Init;
import org.zkoss.zk.ui.Executions;
import org.zkoss.zul.Messagebox;
import domainDAO.PersonDAO;
import org.zkoss.bind.annotation.BindingParam;
import org.zkoss.bind.annotation.GlobalCommand;
import org.zkoss.bind.annotation.NotifyChange;

public class PersonVM {

    private List<Person> persons = new ArrayList<Person>();
    private Person curSelectedPerson;

    public Person getCurSelectedPerson() {
        return curSelectedPerson;
    }

    public void setCurSelectedPerson(Person curSelectedPerson) {
        this.curSelectedPerson = curSelectedPerson;
    }

    public List<Person> getallPersons() {
        return persons;
    }

    @Init
    public void initSetup() {
        persons = new PersonDAO().getAllPersons();

    }

    @Command
    public void onDoubleClicked() {
        final HashMap<String, Object> map = new HashMap<String, Object>();
        map.put("selectedPerson", curSelectedPerson);
        Executions.createComponents("AddPerson.zul", null, map);
    }

    @Command
    public void addNewPerson() {
        final HashMap<String, Object> map = new HashMap<String, Object>();
        map.put("selectedPerson", null);
        Executions.createComponents("AddPerson.zul", null, map);
    }

    //note this will be executed after when we new person from the model window
    @GlobalCommand
    @NotifyChange("allPersons")
    public void refreshList(@BindingParam("newadded") Person p1) 
    {  
        persons.add(p1);
    }

}




HibernateUtil.java

package HibernateUtilities;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.service.ServiceRegistryBuilder;

public class HibernateUtil {

    private static SessionFactory factory;
    private static ServiceRegistry serviceRegistry;

    public static Configuration getInitConfiguration() {
        Configuration config = new Configuration();
        config.configure();
        return config;
    }

    public static Session getSession() {
        if (factory == null) {
            Configuration config = HibernateUtil.getInitConfiguration();
            serviceRegistry = new ServiceRegistryBuilder().applySettings(
                    config.getProperties()).buildServiceRegistry();
            factory = config.buildSessionFactory(serviceRegistry);
        }
        Session hibernateSession = factory.getCurrentSession();
        return hibernateSession;
    }

    public static Session beginTransaction() {
        Session hibernateSession;
        hibernateSession = HibernateUtil.getSession();
        hibernateSession.beginTransaction();
        return hibernateSession;
    }

    public static void CommitTransaction() {
        HibernateUtil.getSession().getTransaction().commit();
    }

    public static void closeSession() {
        HibernateUtil.getSession().close();
    }

    public static void rollbackTransaction() {
        HibernateUtil.getSession().getTransaction().rollback();
    }

}



Now you can run the demo.zul. And click Add Person to add new person or double click any one of the list items to edit.

image

Download the source as war file

continued on next post - Part 3

3 comments:

  1. Thanks for posting this. It's very helpful Saw you mentioned it in the ZK forums. Thanks for giving back to the community.

    ReplyDelete
  2. Hi, since zk 6.0.2, to wire component in a view model, you have to use new @AfterCompose annotation,
    please read upgrade note : http://books.zkoss.org/wiki/Small_Talks/2011/November/ZK_6:_Upgrade_Notes#ZK_Bind_Since_6.0.2

    ReplyDelete
  3. es posible, trabajar con MVC jejejeje

    ReplyDelete