Saturday, 3 January 2015

Processing SQL Statements with JDBC

Processing SQL Statements with JDBC


We have to follow following steps in any SQL statement with JDBC:

1. Establishing a connection.
2. Create a statement.
3. Execute the query.
4. Process the ResultSet object.
5. Close the connection.

1. Establishing Connections
Establish a connection with the data source you want to use.
A data source can be a DBMS, a legacy file system, or some other source of data with a corresponding JDBC driver.
This connection is represented by a Connection object.

2. Creating Statements
A Statement is an interface that represents a SQL statement.
You execute Statement objects and they generate ResultSet objects which is a table of data representing a database result set.
You need a Connection object to create a Statement object.

There are three different kinds of statements:
Statement: Used to implement simple SQL statements with no parameters.
PreparedStatement: (Extends Statement.) Used for precompiling SQL statements that might contain input parameters.
CallableStatement: (Extends PreparedStatement.) Used to execute stored procedures that may contain both input and output parameters.


3.Executing Queries
To execute a query, call an execute method from Statement such as the following:

execute: Returns true if the first object that the query returns is a ResultSet object. Use this method if the query could return one or more ResultSet objects. Retrieve the ResultSet objects returned from the query by repeatedly calling Statement.getResultSet.
executeQuery: Returns one ResultSet object.
executeUpdate: Returns an integer representing the number of rows affected by the SQL statement. Use this method if you are using INSERT, DELETE, or UPDATE SQL statements.

4. Processing ResultSet Objects

You access the data in a ResultSet object through a cursor.
This cursor is a pointer that points to one row of data in the ResultSet object.
Initially, the cursor is positioned before the first row. You call various methods defined in the ResultSet object to move the cursor.

5. Closing Connections
When you are finished using a Statement, call the method Statement.close to immediately release the resources it is using.
When you call this method, its ResultSet objects are closed.

Example:

    public void doSqlQuery(String query)
    {

    Statement stmt = null;
    try
{
            stmt = con.createStatement();
            ResultSet rs = stmt.executeQuery(query);
            while (rs.next())
            {
                String name= rs.getString("name");
                int ID = rs.getInt("ID");
                float price = rs.getFloat("PRICE");
            }
         }
         catch (SQLException e )
         {
             e.printStackTrace();
         }
         finally
         {
             if (stmt != null)
             {
                 stmt.close();
             }
         }
      }


Prepared Statement:

The Prepared Statement is a slightly more powerful version of a Statement, and should always be at least as quick and easy to handle as a Statement.
The Prepared Statement may be parametrized Most relational databases handles a JDBC / SQL query in four steps:
1.Parse the incoming SQL query
2. Compile the SQL query
3. Plan/optimize the data acquisition path
4. Execute the optimized query / acquire and return data

A Statement will always proceed through the four steps above for each SQL query sent to the database.
A Prepared Statement pre-executes steps (1) - (3) in the execution process above. Thus, when creating a Prepared Statement some pre-optimization is performed immediately. The effect is to lessen the load on the database engine at execution time.

Advantages of a Prepared Statement:


1. Precompilation and DB-side caching of the SQL statement leads to overall faster execution and the ability to reuse the same SQL statement in batches.

2. Automatic prevention of SQL injection attacks by builtin escaping of quotes and other special characters.


Why do we use connection pool:
Reason :Creating a new database connection is very costly.

Explanation:
Think about the amount of memory being allocated per DB Connection. What things must be allocated? According to MySQL 5.0 Certification Study Guide, page 357:
The server maintains several buffers for each client connection. One is used as a communications buffer for exchanging information with the client. Other buffers are maintained per client for reading tables and performing join and sort operations.
What settings govern the per-connection buffers?
join_buffer_size
sort_buffer_size
read_buffer_size
read_rnd_buffer_size
tmp_table_size / max_heap_table_size
net_buffer_length / max_allowed_packet
thread_stack
It takes time to allocate and deallocate these buffers when a connection comes into being. Don't forget to multiple the sum of those values by max_connections. As a side note, please refrain from usingmysql_pconnect as PHP and MySQL's persistent connections do not get along well. Here are two informative links on this topic:
Open bug on PHP Not Cleanly Closing MySQL Connections on Apache Death.
Requesting a Persistent ssh Connection.
In heavy-read, heavy-write environment, such as OLTP, this would be expensive in terms of RAM usage and possible inhibition due to swapping in the OS. On a low-write, low_read website, I would not worry as much.

for above terms use link : http://dev.mysql.com/doc/refman/5.5/en/server-system-variables.html#sysvar_join_buffer_size

The process of handshake spanning across multiple machines (if your db server is hosted over the network) which takes place on creating (establishing) a new connection makes it expensive. Thats why its recommended to use a connection pool, or in your case the session. This could include host lookup, initial connection, and subsequent control commands.

Checked v/s unchecked exception

Exception in java:there are three types of Exceptions:

1. Checked Exception
2. Unchecked Exception
3. Error


Checked Exception:
These are exceptional conditions that a well-written application should anticipate and recover from.
All exceptions directly inherited from Exception class are checked exception.
Please note: checked Exception is not concerned with compiler time.
We can only get compile time error and not compile time exception.

For example: FileNotFoundException: it can possible that user have entered a wrong name: possibility to enter correct name.
  
Unchecked Exception:These are exceptional conditions that are internal to the application, and that the application usually cannot anticipate or recover from.
These usually indicate programming bugs, such as logic errors or improper use of an API.
Example: NullPointerException: Let say we want to call a function for from object.But let say object is not initialized, we should not initialized that object because it can be possible that reference is of interface and it may be inherited by n number of classes/ interface.Now which implementation to initialize, how to decide that.

Error:These are exceptional conditions that are external to the application, and that the application usually cannot anticipate or recover from.
Example: OutOfMemoryException .If JVM memory get overflow, what a programmer can do... there is no way to recover.

The Java compiler forces you to either catch checked exceptions or declare them in the method signature. It was supposed to improve program safety.

Keep in mind:
java.lang.Exception is referred to as "Checked Exception"
java.lang.RuntimeException is referred to as "Unchecked Exception"

Tuesday, 13 May 2014

Using Log4j on Eclipse

Log4j is a Reliable, Fast and Flexible Logging Framework (APIs) written in Java which is distributed under the Apache Software License.


What do you require to use log4j in eclipse project : apache-logging-log4j.jar (http://logging.apache.org/log4j/1.2/download.html )

You will get zip file for the jar. Unzip and save tge jar file in a directory and import the jar file in project.
Right click on the project and click properties.
Now click on java build path and click on Add External jars.
Add the external jar for the log4j logging.
Now you wizard should looks like this.(must have apache-logging-log4j.jar entry)





Java Files
1. StudentActivities.java

package firstLog;

import org.apache.log4j.Logger;

public class StudentActivities
{
static Logger log = Logger.getLogger(StudentActivities.class);
public void takeadmission()
{
log.info("Student has taken admission");
firstYear();
}
private void firstYear()
{
log.info("student in first year");
secondYear();
}

private void secondYear()
{
log.info("student ins second year");
thirdYear();
}

private void thirdYear()
{
log.info("student in third year");
fourthYear();
}

private void fourthYear()
{
log.info("student in fourth year");
professional();
}

private void professional()
{
log.info("Now he is a professional");
}
}

2. Run.java

// Using JUnit to run the program (can be replaced by a class with main method)

package firstLog;

import org.junit.Test;

public class Run
{
@Test
public void testStudentActivities()
{
StudentActivities studentActivities = new StudentActivities(); 
studentActivities.takeadmission();
}

}


3. log4j.properties (should be in project's src folder)


# This sets the global logging level and specifies the appenders
log4j.rootLogger=INFO, theConsoleAppender, FILE

# settings for the console appender
log4j.appender.theConsoleAppender=org.apache.log4j.ConsoleAppender
log4j.appender.theConsoleAppender.layout=org.apache.log4j.PatternLayout
log4j.appender.theConsoleAppender.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n
log4j.appender.FILE=org.apache.log4j.RollingFileAppender
log4j.appender.FILE.File=logs/log.txt
log4j.appender.FILE.layout=org.apache.log4j.PatternLayout
log4j.appender.FILE.layout.conversionPattern=%m%n

log4j.appender.FILE.Append=true

Now project explorer should looks like this:



Run the program and you can see the logs in /logs/log.txt

Hope this helps you :)



Thursday, 17 April 2014

Static Import

Static import
Introduced in  Java 5
Import statement was enhanced to provide greater keystroke-reduction capabilities.
 Static import is use when you want to access Class static members.
Example:
File: First.java
import static staticImport.Second.*;

public class First
{
       public static void main(String[] args)
       {
              System.out.println(firstVar);
              printfirstVar();
       }

}

File : Second.java

public class Second
{
              final static int  firstVar= 34;
             
              static void printfirstVar()
              {
                     System.out.println(firstVar);
              }
}

Output:
34
34

Problem:
Ambiguity of static members:
If we import from two classes which use same static variables then compiler will in ambiguity to decide which variable class variable to use.


Example:
File:First.java

import static staticImport.Second.*;
import static staticImport.Third.*;

public class First
{
       public static void main(String[] args)
       {
              System.out.println(firstVar);         // Error since compile not able to decide which firstVar we want to use, either of Second.java or Third.java
             

printfirstVar();                   // Error: reason is same as above
       }

}

File: second.java
public class Second
{
       final static int  firstVar= 34;
             
       static void printfirstVar()
       {
              System.out.println(firstVar);
       }
}

File: Third.java
public class Third
{
       final static int  firstVar= 34;
      
       static void printfirstVar()
       {
              System.out.println(firstVar);
       }
}


Monday, 14 April 2014

Java Serialization Example

A simple example of serialization concept in java having logging concept so that you can track object before and after serialization.


Class1 : Person.java

import java.io.Serializable;

public class Person implements Serializable
{
private static final long serialVersionUID = 1L;
String name;
int age;

Person(String name, int age)
{
this.name = name;
this.age=  age;
}

public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}

public String toString()
{
return name + " " +age;
}
}

Class 2: First.java (Serialization part )

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.util.logging.FileHandler;
import java.util.logging.Logger;
import java.util.logging.SimpleFormatter;

public class First {

private static final Logger logger = Logger.getLogger(First.class.getName());
public static void main(String[] args)
{
SimpleFormatter simpleFormatter = new SimpleFormatter();
Person p =new Person("shubham", 24);
try
{
FileHandler log = new FileHandler("D:\\My\\java\\try\\src\\serialization\\log.txt", true);
log.setFormatter(simpleFormatter);
logger.addHandler(log);
logger.info("Object to be serialize   " + p.toString());
FileOutputStream fileOutputStream = new FileOutputStream("D:\\My\\java\\try\\src\\serialization\\abc.ser");
ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);
objectOutputStream.writeObject(p);
objectOutputStream.close();
}
catch (FileNotFoundException e)
{
e.printStackTrace();
} catch (IOException e)
{
e.printStackTrace();
}
}
}


Class 3: Second.java (Deserialization )

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.util.logging.FileHandler;
import java.util.logging.Logger;
import java.util.logging.SimpleFormatter;

public class Second {

private static final Logger logger = Logger.getLogger(Second.class.getName());
static SimpleFormatter simpleFormatter = new SimpleFormatter();

public static void main(String[] args)
{
try
{
FileHandler log = new FileHandler("D:\\My\\java\\try\\src\\serialization\\log.txt", true);
log.setFormatter(simpleFormatter);
logger.addHandler(log);

FileInputStream fileInputStream = new FileInputStream("abc.ser");
ObjectInputStream objectOutputStream = new ObjectInputStream(fileInputStream);
Person p = (Person) objectOutputStream.readObject();
objectOutputStream.close();
logger.info("Object deserialized is "+p.toString());
}
catch (FileNotFoundException e)
{
e.printStackTrace();
} catch (IOException e)
{
e.printStackTrace();
}
catch (ClassNotFoundException e)
{
e.printStackTrace();
}
}
}

Thursday, 10 April 2014

Remote debugging using Tomcat with eclipse


Remote debugging using Tomcat with eclipse
The Java debugger has a client/server design so that it can be used to debug programs that run locally (on the same workstation as the debugger) or remotely (on another computer on the network).
Local debugging:
Local debugging is the simplest and most common kind of debugging.  After you have finished editing and building your Java program, you can launch the program on your workstation using the menu item on the workbench.  Launching the program in this way will establish a connection between the debugger client and the Java program that you are launching.  You may then use breakpoints, stepping, or expression evaluation to debug your program.
Remote debugging:
The client/server design of the Java debugger allows you to launch a Java program from computer on your network and debug it from the workstation running the platform.  This is particularly useful when you are developing a program for a device that cannot host the development platform.  It is also useful when debugging programs on dedicated machines such as web servers. 
Steps:
  1. Stop your tomcat if it is in running mode.
  2. Go to Tomcat/webapp/bin. You will find a file catalina.bat (windows)/ catalina.sh (UNIX and Linux).
  3. Catalina.sh have this entry:
JPDA_ADDRESS = 8080
This port number is use for remote debugging. 8080 is default port and you can change it if required.
Write this command on UNIX command interpreter: catalina.sh jpda start
You will see something like this “INFO: Server startup in 4955 ms”.
Now, go to eclipse
Click on debug pick list icon and you will menu like this:



Now select Debug Configurations…
You well get a new window like this:



Now right click on “Remote Java Application” and select “new”.
Debug configuration window now looks like this:



Select an entry for Name field.
Select desired project from Browse button.
Enter Host: (Host name of the machine where tomcat will run.) and valid port number.
Select Apply and click Debug.  
Now you can debug your application as you usually debug on local machine.

[Note: Remote debugging may be quite slow as compared to debugging on local machine]

Sources: http://help.eclipse.org/