Tuesday, March 19, 2013

MySQL 5.6'da Bölümleme

Uzunca bir süredir beklediğimiz MySQL 5.6 sürümü nihayet yayınlandı. Bu sürüm Oracle'ın satın almadan sonra çıkardığı ikinci sürüm olma özelliğini taşıyor. Yeni sürüm birçok alanda iyileştirmeler ve yenilikler içeriyor. Bu sürümde de İyileştirmelerin ve yeniliklerin ağırlıklı olarak InnoDB depolama motoru üzerinde gerçekleştirildiğini rahatlıkla söyleyebiliriz. Yeni sürümü bu adresten indirebilirsiniz.
5.6 ile gelen önemli yeniliklerden biri bölümleme ile ilgili. Hem başarımı iyileştirilmiş hem de yönetimini kolaylaştırılmış. Örneğin artık belirli bir bölümü seçip üzerinde SELECT, INSERT, UPDATE ve DELETE cümlelleri çalıştırabiliyoruz. Bir bölümü başka bir tablo ile değiş tokuş edebiliyoruz. Bunlara ilişkin örnekleri aşağıda bulabilirsiniz.

mysql> create table employees (
    -> id int not null auto_increment primary key,
    -> first_name varchar(30),
    -> last_name varchar(30),
    -> salary float(8,2) )
    -> partition by hash(id) partitions 5;     


1 row in set (0.00 sec)

mysql> show table status like 'employees'\G

*************************** 1. row ***************************
           Name: employees
         Engine: InnoDB
        Version: 10
     Row_format: Compact
           Rows: 5
 Avg_row_length: 16384
    Data_length: 81920
Max_data_length: 0
   Index_length: 0
      Data_free: 0
 Auto_increment: 1
    Create_time: NULL
    Update_time: NULL
     Check_time: NULL
      Collation: latin1_swedish_ci
       Checksum: NULL
 Create_options: partitioned
        Comment:
1 row in set (0.00 sec)

mysql> show create table employees\G

*************************** 1. row ***************************
       Table: employees
Create Table: CREATE TABLE `employees` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `first_name` varchar(30) DEFAULT NULL,
  `last_name` varchar(30) DEFAULT NULL,
  `salary` float(8,2) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
/*!50100 PARTITION BY HASH (id)
PARTITIONS 5 */
1 row in set (0.00 sec)

mysql> select partition_name,table_rows from information_schema.partitions where table_name='employees';

+----------------+------------+
| partition_name | table_rows |
+----------------+------------+
| p0             |          0 |
| p1             |          0 |
| p2             |          0 |
| p3             |          0 |
| p4             |          0 |
+----------------+------------+
5 rows in set (0.01 sec)

mysql> insert into employees values
    -> (1,'jack','bauer',24000),
    -> (2,'jack','shephard',32000),
    -> (3,'kate','austen',27500),
    -> (4,'ben','linus',21750),
    -> (5,'claire','littleton',43000),
    -> (6,'jin','kwon',35000),
    -> (7,'sun','kwon',26500),
    -> (8,'john','locke',43500),
    -> (9,'hugo','reyes',125000),
    -> (10,'sayid','jarrah',12500),
    -> (11,'james','ford',33500),
    -> (12,'desmond','hume',25000),
    -> (13,'charlie','pace',45000),
    -> (14,'micheal','dawson',47000),
    -> (15,'juliet','burke',37000);
Query OK, 15 rows affected, 15 warnings (0.07 sec)
Records: 15  Duplicates: 0  Warnings: 15

mysql> select partition_name,table_rows from information_schema.partitions where table_name='employees';
+----------------+------------+
| partition_name | table_rows |
+----------------+------------+
| p0             |          3 |
| p1             |          3 |
| p2             |          3 |
| p3             |          3 |
| p4             |          3 |
+----------------+------------+
5 rows in set (0.01 sec)

mysql> select * from employees partition(p0);
+----+------------+-----------+----------+
| id | first_name | last_name | salary   |




+----+------------+-----------+----------+
|  5 | claire     | littleton | 43000.00 |
| 10 | sayid      | jarrah    | 12500.00 |
| 15 | juliet     | burke     | 37000.00 |
+----+------------+-----------+----------+
3 rows in set (0.00 sec)

mysql> select * from employees partition(p1);
+----+------------+-----------+----------+
| id | first_name | last_name | salary   |
+----+------------+-----------+----------+
|  1 | jack       | bauer     | 24000.00 |
|  6 | jin        | kwon      | 35000.00 |
| 11 | james      | ford      | 33500.00 |
+----+------------+-----------+----------+
3 rows in set (0.00 sec)

mysql> select * from employees partition(p2);
+----+------------+-----------+----------+
| id | first_name | last_name | salary   |
+----+------------+-----------+----------+
|  2 | jack       | shephard  | 32000.00 |
|  7 | sun        | kwon      | 26500.00 |
| 12 | desmond    | hume      | 25000.00 |
+----+------------+-----------+----------+
3 rows in set (0.00 sec)

mysql> select * from employees partition(p3);
+----+------------+-----------+----------+
| id | first_name | last_name | salary   |
+----+------------+-----------+----------+
|  3 | kate       | austen    | 27500.00 |
|  8 | john       | locke     | 43500.00 |
| 13 | charlie    | pace      | 45000.00 |
+----+------------+-----------+----------+
3 rows in set (0.00 sec)

mysql> select * from employees partition(p4);
+----+------------+-----------+-----------+
| id | first_name | last_name | salary    |
+----+------------+-----------+-----------+
|  4 | ben        | linus     |  21750.00 |
|  9 | hugo       | reyes     | 125000.00 |
| 14 | micheal    | dawson    |  47000.00 |
+----+------------+-----------+-----------+
3 rows in set (0.00 sec)


mysql> select * from employees partition(p1,p3);
+----+------------+-----------+----------+
| id | first_name | last_name | salary   |
+----+------------+-----------+----------+
|  1 | jack       | bauer     | 24000.00 |
|  6 | jin        | kwon      | 35000.00 |
| 11 | james      | ford      | 33500.00 |
|  3 | kate       | austen    | 27500.00 |
|  8 | john       | locke     | 43500.00 |
| 13 | charlie    | pace      | 45000.00 |
+----+------------+-----------+----------+
6 rows in set (0.00 sec)


mysql> insert into employees partition(p1) values (NULL,'shannon','rutherford',75000);
Query OK, 1 row affected (0.03 sec)

mysql> select * from employees partition(p1);
+----+------------+------------+----------+
| id | first_name | last_name  | salary   |
+----+------------+------------+----------+
|  1 | jack       | bauer      | 24000.00 |
|  6 | jin        | kwon       | 35000.00 |
| 11 | james      | ford       | 33500.00 |
| 16 | shannon    | rutherford | 75000.00 |
+----+------------+------------+----------+
4 rows in set (0.00 sec)

mysql> insert into employees partition(p2) values (NULL,'ana','cortez',51250);
Query OK, 1 row affected (0.06 sec)

mysql> select * from employees partition(p2);
+----+------------+-----------+----------+
| id | first_name | last_name | salary   |
+----+------------+-----------+----------+
|  2 | jack       | shephard  | 32000.00 |
|  7 | sun        | kwon      | 26500.00 |
| 12 | desmond    | hume      | 25000.00 |
| 17 | ana        | cortez    | 51250.00 |
+----+------------+-----------+----------+
4 rows in set (0.00 sec)



mysql> create table emp_backup like employees;
Query OK, 0 rows affected (1.61 sec)



mysql> alter table emp_backup remove partitioning;
Query OK, 0 rows affected (1.52 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> alter table employees exchange partition p0 with table emp_backup ;


Query OK, 0 rows affected (0.52 sec)

mysql> select * from employees partition (p0);
Empty set (0.00 sec)

mysql> select * from emp_backup;
+----+------------+-----------+----------+
| id | first_name | last_name | salary   |
+----+------------+-----------+----------+
|  5 | claire     | littleton | 43000.00 |
| 10 | sayid      | jarrah    | 12500.00 |
| 15 | juliet     | burke     | 37000.00 |
+----+------------+-----------+----------+
3 rows in set (0.00 sec)



Wednesday, January 23, 2013

Java ME'de Location API Kullanımı

Java deyince genellikle akla ilk olarak java programlama dili gelmektedir. Bu çok da yanlış sayılmaz. Ancak java öncelikli olarak bir platformun adıdır. Bu platform bize java programlama dilini kullanarak uygulama geliştirmek, geliştirdiğimiz bu uygulamayı dağıtmak ve en sonunda bu uygulamayı çalıştırmak için bir ortam sağlar. Üstelik bu platform tek de değildir. Java Standard Edition (SE), Java Enterprise Edition (EE), Java Micro Edition (ME), Gömülü Java, Java Card, JavaFx gibi biri biriyle ilintili ama farklı platformlar bulunmaktadır. Peki neden tek platform yeterli değildir? Sizce neden bunca sayıda platforma ihtiyaç duyulmuş olabilir? İşlevsel olmayan gereksinimleri ve doğal sonucu olarak mimarileri biri birinden farklı uygulama türleri bulunur: konsol uygulamaları, masa üstü uygulamaları, istemci-sunucu mimarisine sahip uygulamalar, çok katmanlı ve dağıtık uygulamalar. Java platformlarının her biri belirli bir tür uygulama türünde uygulama geliştirmek çin tasarlanmıştır. Örneğin, konsol ve masaüstü uygulamalar geliştirmek için Java SE, cep telefonu gibi kısıtlı bellek ve işlemci kapasitesine sahip cihazlar için ise Java ME platformu kullanılır. Konsol uygulamalarında kullanıcı etkileşimi tuş takımı ve ekran üzerinden gerçekleşmektedir. Uygulamanın çalışma sırası kod sırasını takip eder ve ardışıl bir akışa sahiptir. Masa üstü uygulamaları grafiksel kullanıcı arayüzüne sahiptir ve olay temelli olarak çalışır. Olay kullanıcının bir düğmeye basması, metin kutusuna bir değer girmesi gibi kullanıcı arayüzü ile yaptığı etkileşimleri modeller. Uygulama çalışmaya başlar başlamaz uykuya dalar ve bir olay gerçekleşmesi için bekler. Olay gerçekleştiğinde uyanır ve geliştirici tarafından bu olay için kaydedilen metodu çalıştırır. Bu çalışma biçimi başka benzer problemlerde de kullandığımız bir kalıptır ve gözlemci kalıbı olarak adlandırılır. Java platformları arasında en güçlü ve gelişmiş olanı Java EE platformudur. Java EE platformunu kullanarak kurumsal uygulamalar geliştirilir. Kurumsal uygulamaların masa üstü uygulamarından beklemediğimiz farklı iki işlevsel olmayan gereksinimi bulunur: Yüksek erişilebilirlik ve ölçeklenebilirlik. Uygulamayı oluşturan bileşenler birden fazla makinaya dağıtılmış olarak çalıştırılabilinir. Makinalardan biri donanımsal ya da yazılımsal bir problem nedeni ile erişilemez olduğunda geriye kalan makinalar kullanıcılardan gelen isteklere cevap vermeye devam edecektir. Diğer taraftan kullanıcı sayısı arttığında kümeye yeni makinalar ekleyerek artan ihtiyacı karşılamak mümkün olabilir.
Java platformları arasında en zayıf olanı Java ME'dir diyebiliriz. Java ME'nin yerini iPhone OS ve Android platformlarının aldığını söyleyebiliriz. Aslında Java ME bir platform iken Android ve iPhone OS ise birer işletim sistemidir. Dolayısı ile karşılıştırılmaları çok da doğru olmayacaktır. Oracle Sun'ı satın aldıktan sonra Java platformunun geleceği konusunda bazı şüpheler ve kaygılar ortaya çıkmış olsa da geçen 2-3 sene boyunca bu satın almanın en azından Java platformu için olumlu olduğunu genel olarak söyleyebiliriz. Oracle tekrar Java ME'ye yüklendiğini ve öne çıkarmaya çalıştığını gözlemliyoruz. Bu ne kadar anlamlı bir adım ya da Oracle bundan nasıl bir çıkar bekliyor, açıkçası kestiremiyorum. Bundan bağımsız olarak Java ME'de hala az da olsa uygulama geliştirildiğini görebiliyoruz. Android yada iPhone OS'e göre oldukça kısıtlı bir programlama yeteneği sunuyor. Burada Location API ile ilgili basit bir örnek kod göstermek istiyorum. Örnek kod cihazdan aldığı konum bilgilerini ekranda gösteriyor. Kodun çalışabilmesi için projeye Lightweight UI Toolkit 1.5 kütüphanesinin eklenmesi gerekir. Bu kütüphaneyi linki izleyerek indirebilirsiniz. Zip dosyayı açtığınızda lib dizininde bulunan LWUIT_MIDP.jar ve MIDP_IO.jar dosyalarını projeye eklemeniz yeterli olacaktır. SimpleLocationMidlet sınıfı MIDlet sınıfından türetilmiştir. Konum bilgilerini ise gözlemci kalıbını kullanarak öğreneceğiz. Bunun için SimpleLocationMidlet sınıfı LocationListener arayüzünü gerçekleyecek şekilde tanımlanmıştır. Bu arayüzün iki tane metodu bulunmaktadır: locationUpdated ve providerStateChanged. Konum bilgisi değiştiğinde locationUpdated metodu ve cihazın durum değişikliğinde ise providerStateChanged metodu tetiklenmektedir. Konum bilgisi cihaz tarafından sağlanmaktadır. Cihazın bu yeteneği LocationProvider sınıfı ile modellenmektedir. LocationProvider ile gözlemci arasındaki ilişki kodda aşağıdaki gibi sağlanmaktadır:
       LocationProvider lp = LocationProvider.getInstance(null);
       lp.setLocationListener(this, 2, 1, -1);

Kodu test etmek için Java ME SDK 3.2 ile birlikte gelen emülatör kullanılabilir. Konum bilgisi değişikliğini simğle etmek için aşağıdaki gibi basit bir betik yazmak ve çalıştırmak gerekir:

   <waypoints>
      <waypoint time="0" latitude="0" longtitude="5" altitude="0"/>
      <waypoint time="15000" latitude="30" longtitude="10" altitude="50"/>
   </waypoints>










package com.example;

import com.sun.lwuit.Display;
import com.sun.lwuit.Form;
import com.sun.lwuit.Label;
import com.sun.lwuit.layouts.BoxLayout;
import javax.microedition.location.Location;
import javax.microedition.location.LocationException;
import javax.microedition.location.LocationListener;
import javax.microedition.location.LocationProvider;
import javax.microedition.location.QualifiedCoordinates;
import javax.microedition.midlet.*;

public class SimpleLocationMidlet extends MIDlet implements LocationListener {

    private Label lonLabel, latLabel, altLabel, stateLabel;

    public void startApp() {
        Display.init(this);
        stateLabel = new Label();
        latLabel = new Label("Lat: ");
        lonLabel = new Label("Lon: ");
        altLabel = new Label("Alt: ");
        try {
            LocationProvider lp = LocationProvider.getInstance(null);
            lp.setLocationListener(this, 2, 1, -1);
            setStateString(lp);
        } catch (LocationException ex) {
            stateLabel.setText(ex.getMessage());
        }
        Form form = new Form("Location");
        form.setLayout(new BoxLayout(BoxLayout.Y_AXIS));
        form.addComponent(stateLabel);
        form.addComponent(latLabel);
        form.addComponent(lonLabel);
        form.addComponent(altLabel);
        form.show();
    }

    public void pauseApp() {
    }

    public void destroyApp(boolean unconditional) {
    }

    public void locationUpdated(LocationProvider lp, Location location) {
        if (location!= null) {
            QualifiedCoordinates coordinates = location.getQualifiedCoordinates();
            if (coordinates != null) {
                latLabel.setText("Lat: " + coordinates.getLatitude());
                lonLabel.setText("Lon: " + coordinates.getLongitude());
                altLabel.setText("Alt: " + coordinates.getAltitude());
            }
        }
    }

    public void providerStateChanged(LocationProvider lp, int i) {
        setStateString(lp);
    }


  1.     private void setStateString(LocationProvider lp) {

        String state = "";
        if (lp.getState() == LocationProvider.AVAILABLE) {
            state += "Available";
        } else if (lp.getState() == LocationProvider.TEMPORARILY_UNAVAILABLE) {
            state += "Temporarily Unavailable";
        } else if (lp.getState() == LocationProvider.OUT_OF_SERVICE) {
            state += "Out of servive!";
        }
        stateLabel.setText(state);
    }
}


Uygulamanın kaynak koduna NetBeans projesi olarak bu bağlantıdan erişebilirsiniz. Aynı projeyi eclipse projesi olarak bu bağlantıdan indirebilirsiniz. Bunun için öncelikli olarak bu bağlantıdan Eclipse eklentisini kullanıdığınız Eclipse IDE'sine tanıtmanız ve makinanıza Java Me SDK 3.2 kurmanız gerekir. Eclipse for Mobile kurulumu için aşağıdaki adımları takip etmeniz uygun olur:

  1.  Eclipse for Mobile'ı http://www.eclipse.org/downloads/packages/eclipse-mobile-developers/junosr2 indirin.
  2. Help->Install New Software...
  3. Add butonuna basın
  4. Location etiketli alana "http://download.eclipse.org/releases/indigo" adresini girin:
  5. Ok butonuna basın.
  6. Mobile and Device Development Tools altındaki "Mobile Tools for Java Examples", "Mobile Tools for Java SDK" ve "Mobile Tools for Java Examples" liste başlıklarını seçiniz:   
  7. Next butonuna basınız ve kurulumu tamamlayınız. Kurulum bitince Eclipse yeniden başlatmayı önerecektir. Kabul edin.
  8. Eclipse yeniden açıldıktan sonra nihayet Oracle'ın sayfasından indirdiğimiz Java Me eklentisini  kurabiliriz.
  9. Help->Install New Software...
  10. Add butonuna basınız
  11. Archive butonuna basınız ve eclipse-me-sdk-plugins-uc.zip dosyasını seçin.
  12. Kurulumu tamamladıktan sonra jar çakıştırmasını gidermek için plugins dizini altındaki org.eclipse.jetty.server_8.1.3.v20120522.jar isimli dosyayı org.eclipse.jetty.server_8.1.3.v20120522.old olarak değiştiriniz.
  13. Eclipse'i yeniden başlatın. Açıldığında artık Perspective listesinde Java Me gözükecektir:

  14. Menüden Window->Preference'ı seçin.
  15. Java ME->Device Management'ı seçin:
Manual Install butonuna tıklayın ve Java Me Platform SDK'nın kurulu olduğu dizini gösterin:

Aynı uygulamayı eclipse projesi olarak bu bağlantıdan indirebilirsiniz.

Wednesday, January 16, 2013

The easiest way to retrieve data from a database and present them to web users on Java EE Platform

If your aim is to just retrieve information from a database and then present them to a web user on Java EE platform, probably the easiest way is to use Java Server Pages (JSP) and JSP Standard Tag Library (JSTL) technologies. JSP is a web component model. It heavily uses  HTML, CSS, Javascript technologies to present the model to the web user. JSP is a presentation technology. In design time it is basically an HTML file. Though you can insert any java scriptlet. All JSP components are translated in run-time to a Servlet class and then the translated java codes are compiled into bytecodes by the web container . This process is done when the JSP page is requested for the first time. It is possible to tell the web container to do the translation and compilation during the deployment in order to enhance the response time . JSPs and Servlets are different components in design-time, the same component in run-time. JSP pages are dynamic while Servlets are static components. Whenever you make a change in JSP page, the web container detects the change and re-translate and re-compile the page into bytecode ready to be run on JVM.   

MVC is an architectural design pattern used in both desktop and web applications. Due to its distributed nature, implementation of MVC pattern in web applications is somewhat different from the one used in desktop applications. For example any model update does not directly reflect to the web page in the client machine. It requires a request-response cycle. So observer pattern is not used in traditional web applications. Observer pattern in web applications is usually implemented by employing Ajax-push technology or by using Web sockets of HTML 5. Model in MVC is implemented by JavaBeans component model.

The JavaServer Pages Standard Tag Library (JSTL) is a collection of useful JSP tags which encapsulates core functionality common to many JSP applications. One of these functionalities is found in sql tag library: 
<%@ taglib prefix="sql" uri="http://java.sun.com/jsp/jstl/sql" %>     
In order to use this tag library, first you must define a a data source (connection pool). In our example, we use MySQL database server: 
<sql:setDataSource driver="com.mysql.jdbc.Driver"
                   url="jdbc:mysql://localhost:3306/world"
                   user="root" password="root"/>
Using a connection from the connection pool, we can send a valid SQL statement to the server:
<sql:query var="continents">
   SELECT DISTINCT CONTINENT FROM COUNTRY
</sql:query>
The result set is stored in the variable continents.  Another example is given below:
<c:if test="${not empty param.continent}">
   <sql:query var="countries">
     SELECT * FROM COUNTRY WHERE continent= '${param.continent}'
   </sql:query>
</c:if>
where the result set stored in the variable countries contains countries in the selected continent ${param.continent}.
In the sample application we ask for a continent from the user. User selects the continent and then press the List button. The page displays the countries in the selected continent.  The complete solution is given in the following Jsp code, index.jsp:   

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="sql" uri="http://java.sun.com/jsp/jstl/sql" %>
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<sql:setDataSource driver="com.mysql.jdbc.Driver"
                   url="jdbc:mysql://localhost:3306/world"
                   user="root"
                   password="root"/>
<sql:query var="continents">
    SELECT DISTINCT CONTINENT FROM COUNTRY
</sql:query>
<c:if test="${not empty param.continent}">
    <sql:query var="countries">
        SELECT * FROM COUNTRY WHERE continent= '${param.continent}'
    </sql:query>  
</c:if>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>World Countries</title>
        <script type="text/javascript" src="js/jquery-1.8.3.min.js"></script>
        <style>
            tr.zebraHover { background-color: #FFFACD; }
            tr.striped_even { background-color:  #EFEFEF}
            tr.striped_odd { background-color:  #DFDFDF}            
        </style>
        <script type="text/javascript">
            $(document).ready(
            function () {
                $('tbody tr:even').mouseover(function(){
                    $(this).addClass('zebraHover');
                    $(this).removeClass('striped_even');
                });
                $('tbody tr:even').mouseout(function(){
                    $(this).removeClass('zebraHover');
                    $(this).addClass('striped_even');
                });
                $('tbody tr:odd').mouseover(function(){
                    $(this).addClass('zebraHover');
                    $(this).removeClass('striped_odd');
                });
                $('tbody tr:odd').mouseout(function(){
                    $(this).removeClass('zebraHover');
                    $(this).addClass('striped_odd');
                });
                $('tbody tr:odd').addClass('striped_odd');
                $('tbody tr:even').addClass('striped_even');
            }
            );
        </script>
    </head>
    <body>
        <form action="index.jsp" method="POST">
            <select name="continent">
                <c:forEach items="${continents.rows}" var="row">
                    <option value="${row.continent}">${row.continent}</option>
                </c:forEach>
            </select>
            <input type="submit" value="List"/>
            <br/>
            <c:if test="${not empty countries}">
                <table border="0">
                    <thead>
                    <tr>
                        <c:forEach items="${countries.columnNames}" var="headerName">
                            <th>${headerName}</th>
                        </c:forEach> 
                    </tr>
                    </thead>
                    <tbody>
                        <c:forEach items="${countries.rows}" var="row">
                            <tr>
                                <c:forEach items="${countries.columnNames}" var="columnName">
                                    <td>${row[columnName]}</td>
                                </c:forEach>
                            </tr>
                        </c:forEach>
                    </tbody>
                </table>    
            </c:if> 
        </form>
    </body>
</html>
The solution contains jQuery to add zebra effect to the table. You can download jQuery from http://www.jquery.com. Sample screen shots are given below:


You can download world database following the link. You can read the pdf to learn how to install MySQL and the world database. Changing this solution to Ajax-based application is simple. First we partition index.jsp into search.jsp and countries.jsp. Second, we add jquery code which sends the request asynchronously and makes partial update when the response is received:
 $('#listButton').click(function(){
     var continent= $('#selectContinent').val();
     $.ajax({
         method: "GET",
         url: "countries.jsp",
         data: "continent="+continent,
         success: function(responseData){
             $('#result').fadeOut('fast');
             $('#result').html(responseData).fadeIn('slow');
         }   
     });
  });

countries.jsp sends only the table containing the countries in the selected continent.

search.jsp:

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="sql" uri="http://java.sun.com/jsp/jstl/sql" %>
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<sql:setDataSource driver="com.mysql.jdbc.Driver"
                   url="jdbc:mysql://localhost:3306/world"
                   user="root"
                   password="root"/>
<sql:query var="continents">
    SELECT DISTINCT CONTINENT FROM COUNTRY
</sql:query>

<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>World Countries</title>
        <script type="text/javascript" src="js/jquery-1.8.3.min.js"></script>
        <style>
            tr.zebraHover { background-color: #FFFACD; }
            tr.striped_even { background-color:  #EFEFEF}
            tr.striped_odd { background-color:  #DFDFDF}            
        </style>
        <script type="text/javascript">
            $(document).ready(
            function () {
                $('tbody tr:even').mouseover(function(){
                    $(this).addClass('zebraHover');
                    $(this).removeClass('striped_even');
                });
                $('tbody tr:even').mouseout(function(){
                    $(this).removeClass('zebraHover');
                    $(this).addClass('striped_even');
                });
                $('tbody tr:odd').mouseover(function(){
                    $(this).addClass('zebraHover');
                    $(this).removeClass('striped_odd');
                });
                $('tbody tr:odd').mouseout(function(){
                    $(this).removeClass('zebraHover');
                    $(this).addClass('striped_odd');
                });
                $('tbody tr:odd').addClass('striped_odd');
                $('#result table tbody tr:even').addClass('striped_even');
                $('#listButton').click(function(){
                    var continent= $('#selectContinent').val();
                    $.ajax({
                        method: "GET",
                        url: "countries.jsp",
                        data: "continent="+continent,
                        success: function(responseData){
                            $('#result').fadeOut('fast');
                            $('#result').html(responseData).fadeIn('slow');
                        }   
                    });
                });
            }
        );
        </script>
    </head>
    <body>
        <select id="selectContinent" name="continent">
            <c:forEach items="${continents.rows}" var="row">
                <option value="${row.continent}">${row.continent}</option>
            </c:forEach>
        </select>
        <input id="listButton" type="submit" value="List"/>
        <div id="result">

        </div>
    </body>
</html>

countries.jsp:
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="sql" uri="http://java.sun.com/jsp/jstl/sql" %>
<sql:setDataSource driver="com.mysql.jdbc.Driver"
                   url="jdbc:mysql://localhost:3306/world"
                   user="root"
                   password="root"/>
<c:if test="${not empty param.continent}">
    <sql:query var="countries">
        SELECT * FROM COUNTRY WHERE continent= '${param.continent}'
    </sql:query>  
</c:if>
<c:if test="${not empty countries}">
    <table border="0">
        <thead>
            <tr>
        <c:forEach items="${countries.columnNames}" var="headerName">
            <th>${headerName}</th>
        </c:forEach> 
        </tr>
        </thead>
        <tbody>
        <c:forEach items="${countries.rows}" var="row">
            <tr>
            <c:forEach items="${countries.columnNames}" var="columnName">
                <td>${row[columnName]}</td>
            </c:forEach>
            </tr>
        </c:forEach>
        </tbody>
    </table>    
</c:if>