Wednesday, 21 December 2016

Spring Data JPA Using SpringBoot


If you are looking for how to integrate spring data jpa using spring boot, you are at right place.

This tutorial will guide you to create sample application which will use spring data jpa and spring boot.

Let's get started.

What you need :

1. Java 1.8
2. Maven
3. IntelliJ
4. MySQL

Note: You can use any other Java IDE like EClipse etc and skip the project creation steps below which is created specific for IntelliJ.

Step 1: Create project in IntelliJ






































Next Give Artifact Name






































Give Project name






































This will create maven project as shown below
































Step 2: Update pom.xml with below dependancies

xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
         http://maven.apache.org/xsd/maven-4.0.0.xsd">

    <modelVersion>4.0.0</modelVersion>

    <groupId>com.example</groupId>
    <artifactId>spring-data</artifactId>
    <version>1.0-SNAPSHOT</version>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.3.5.RELEASE</version>
        <relativePath />
    </parent>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.10</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>


Step 3: Test mySQL connection

In IntelliJ goto
Views =>  Tool Windows => Database

Open MySql Datasource window and enter database connection details as shown
































Click Test Connection



Step 4: Create application.properties in resources folder which gives jpa connection details

# DataSource settings: set here your own configurations for the database
# connection. In this example we have "spring_db" as database name and
# "root" as username and password.
spring.datasource.url = jdbc:mysql://localhost:3306/spring_db
spring.datasource.username = root
spring.datasource.password = root

# Keep the connection alive if idle for a long time (needed in production)
spring.datasource.testWhileIdle = true
spring.datasource.validationQuery = SELECT 1

# Show or not log for each sql query
spring.jpa.show-sql = true

# Hibernate ddl auto (create, create-drop, update)
spring.jpa.hibernate.ddl-auto = update

# Naming strategy
spring.jpa.hibernate.naming-strategy = org.hibernate.cfg.ImprovedNamingStrategy

# Use spring.jpa.properties.* for Hibernate native properties (the prefix is
# stripped before adding them to the entity manager)

# The SQL dialect makes Hibernate generate better SQL for the chosen database
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect

#change port
server.port=8090
NOTE: 
1. Note that server.port= property is used for changing default tomcat 8080 port.
Using the hibernate configuration ddl-auto = update the database schema will be automatically created (and updated), creating tables and columns, accordingly to java entities found in the project.
See here for other hibernate specific configurations.
You project structure should look something like this


Note: Here Application.java class is at root of all sub-packages. It is because @SpringBootApplication annotation is equivalent to  @Configuration, @EnableAutoConfiguration and @ComponentScan with their default values. And @ComponentScan search component in current & sub packages.
If you have Application.java in different package structure, you have to provide your own custom annotation with proper package for @ComponentScan .

Step 5: Create Application.java with @SpringBootApplication annotation.
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.orm.jpa.EntityScan;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;

//@Configuration
//@EnableAutoConfiguration
//@ComponentScan({"controller"})
@SpringBootApplication
@EnableJpaRepositories({"com.example.model"})
@EntityScan("com/example/model")
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

Note: Many Spring Boot developers (Spring) always have their main class annotated with @Configuration, @EnableAutoConfiguration and @ComponentScan. Since these annotations are so frequently used together (especially if you follow the best practices above), Spring Boot provides a convenient @SpringBootApplication alternative.

Step 6: Create User Entity
package com.example.model;

import javax.persistence.*;
import javax.validation.constraints.NotNull;

@Entity@Table(name="Users")
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long id;
    @NotNull
    private String name;
    @NotNull
    private String email;
    public User() {
    }
    public User(String name, String email) {
        this.name = name;
        this.email = email;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getEmail() {
        return email;
    }
    public void setEmail(String email) {
        this.email = email;
    }
    public long getId() {
        return id;
    }
}





Step 7: Create User Dao
package com.example.model;
import org.springframework.data.repository.CrudRepository;
import javax.transaction.Transactional;
@Transactionalpublic interface UserDao extends CrudRepository {
    public User findByEmail(String email);
}
For More examples click here

Step 8: Create Controller
a. Create MainController
package com.example.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class MainController { 
   @RequestMapping("/")
    public String index() {
        return "This application is created using spring data jpa and spring boot";
    }
}
b. Create UserController
package com.example.controller;
import com.example.model.User;
import com.example.model.UserDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
@RestController
public class UserController {
    @Autowired 
       private UserDao userDao;
    public UserDao getUserDao() {
        return userDao;
    }
    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }
    @RequestMapping(value = "/create/{name}", method = RequestMethod.POST)
    public User create(@PathVariable("name") String name,@RequestParam(name="email") String email) {
        User user = null;
        try {
            user = new User(name,email);
            userDao.save(user);
        }
        catch (Exception ex) {
            ex.printStackTrace();
        }
        return user;
    }

    /**     * GET /get-by-email  --> Return the user by email.     */ 
    @RequestMapping(value = "/get-by-email", method = RequestMethod.GET)
    public User getByEmail(@RequestParam(name="email") String email) {
        User user = null;
        try {
            user = userDao.findByEmail(email);
        }
        catch (Exception ex) {
            ex.printStackTrace();
        }
        return user;
    }
}

Now Run your Application.java & test 
Get Any rest client plugin for browser 
Url for create : http://localhost:8090/create/John?email=john@gmail.com
(In above url, name is @PathVariable & email is @RequestParam)
Check record in database select your database Open mysql command prompt
You can also call GET endpoint to see result GET URL : http://localhost:8090/get-by-email?email=john@gmail.com
Now you have your running spring-data application 
Thanks for visiting... :)
Code for above application is present at https://github.com/aliqamer/springDataJpa

Thursday, 22 September 2016

Merge Sort



The merge sort algorithm closely follows the divide-and-conquer paradigm. Intuitively,
it operates as follows.

Divide: Divide the n-element sequence to be sorted into two subsequences of n=2
elements each.
Conquer: Sort the two subsequences recursively using merge sort.
Combine: Merge the two sorted subsequences to produce the sorted answer.

The recursion “bottoms out” when the sequence to be sorted has length 1, in which
case there is no work to be done, since every sequence of length 1 is already in
sorted order.
The key operation of the merge sort algorithm is the merging of two sorted
sequences in the “combine” step.

MERGE-SORT (A, l, r)
1                    if l < r
2                          mid =  [ (l + r) / 2 ]
3                          SORT (A, l , m )
4                          SORT (A, m + 1,  r)
5                          MERGE (A, l, m, r)




/** * Created by Ali on 9/21/2016. */

class MergeSort {
    public static void main(String args[]) {
        int arr[] = {12, 11, 13, 5, 6, 7};
        System.out.println("Given Array");
        printArray(arr);

        MergeSort ob = new MergeSort();
        ob.sort(arr, 0, arr.length-1);
        System.out.println("\nSorted array");
        printArray(arr);
    }
    
// Merges two subarrays of arr[]. First subarray is arr[l..m] Second subarray is arr[m+1..r]    

void merge(int arr[], int l, int m, int r) {
        int n1 = m - l + 1;
        int n2 = r - m;

        int[] L = new int[n1];
        int[] R = new int[n2];

        for (int i = 0; i < n1; i++) {
            L[i] = arr[l + i];
        }
        for (int j = 0; j < n2; j++) {
            R[j] = arr[m + 1 + j];
        }

        int k = l;
        int i=0 , j=0;
        while(i < n1 && j < n2) {
            if(L[i] < R[j]) {
                arr[k++] = L[i++];
            }else {
                arr[k++] = R[j++];
            }
        }

        while(i < n1){
            arr[k++] = L[i++];
        }
        while(j < n2){
            arr[k++] = R[j++];
        }
    }

    void sort(int arr[], int l, int r){

        if(l < r) {
            int m = (l+r)/2;

            sort(arr, l , m);
            sort(arr, m+1, r);

            merge(arr, l, m, r);
        }
    }

    private static void printArray(int[] arr) {
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i] + " ");
        }
    }
}


Time complexity of Merge Sort is O(nLogn) in all 3 cases (worst, average and best) as merge sort always divides the array in two halves and take linear time to merge two halves.
Auxiliary Space: O(n)
Algorithmic Paradigm: Divide and Conquer
Stable: Yes

Applications of Merge Sort
  1. Merge Sort is useful for sorting linked lists in O(nLogn) time.In case of linked lists the case is different mainly due to difference in memory allocation of arrays and linked lists. Unlike arrays, linked list nodes may not be adjacent in memory. Unlike array, in linked list, we can insert items in the middle in O(1) extra space and O(1) time. Therefore merge operation of merge sort can be implemented without extra space for linked lists.
    In arrays, we can do random access as elements are continuous in memory. Let us say we have an integer (4-byte) array A and let the address of A[0] be x then to access A[i], we can directly access the memory at (x + i*4). Unlike arrays, we can not do random access in linked list. Quick Sort requires a lot of this kind of access. In linked list to access i’th index, we have to travel each and every node from the head to i’th node as we don’t have continuous block of memory. Therefore, the overhead increases for quick sort. Merge sort accesses data sequentially and the need of random access is low.

Tuesday, 6 September 2016

Insertion Sort

It is a simple Sorting algorithm which sorts the array by shifting elements one by one. Following are some of the important characteristics of Insertion Sort.
  1. It is better than Selection Sort and Bubble Sort algorithms.
  2. Its space complexity is less, like Bubble Sorting, insertion sort also requires a single additional memory space.
  3. It is Stable, as it does not change the relative order of elements with equal keys

How Insertion Sorting Works

Insertion Sort Fig-1
/**
 * Created by Ali on 9/5/2016.   
 * Uses: Insertion sort is uses when number of elements is small. 
 * Or when input array is almost sorted, only few elements are misplaced in complete big array. 
**/

public class InsertionSort {
    public static void main(String str[]) {
        int[] arr = new int[]{10,54,2,100,200,121,99,150,51,181};
        InsertionSort obj = new InsertionSort();
        int[] sortedArray = obj.insertionSort(arr);
        for (int i = 0; i < sortedArray.length; i++) {
            System.out.print(sortedArray[i] + " ");
        }
    }

    private int[] insertionSort(int[] arr) {
        for(int i=1; i < arr.length; i++) {
            int key = arr[i];
            int j = i - 1;
            while(j>=0 && arr[j] > key){
                arr[j+1] = arr[j];
                j--;
            }
            arr[j+1] = key;
        }
        return arr;
    }
}




Time Complexity: O(n*n)
Auxiliary Space: O(1)
Boundary Cases: Insertion sort takes maximum time to sort if elements are sorted in reverse order. And it takes minimum time (Order of n) when elements are already sorted.

Thursday, 1 September 2016

Bubble Sort



Bubble Sort is the simplest sorting algorithm that works by repeatedly swapping the adjacent elements if they are in wrong order.

How Bubble Sorting Works


/** Created by Ali on 9/1/2016.
  * Bubble Sort that works by repeatedly swapping the adjacent elements 
  * if they are in wrong order.
  */
public class BubbleSort {

    public static void main(String str[]){
        int[] arr = new int[]{10,54,2,100,200,121,99,150,51,181};
        BubbleSort obj = new BubbleSort();
        int[] sortedArray = obj.bubbleSort(arr);
        for (int i = 0; i < sortedArray.length; i++) {
            System.out.print(sortedArray[i] + " ");
        }
    }

    private int[] bubbleSort(int[] unsortedArray) {
        int length = unsortedArray.length;
        for (int i = 0; i < length-1; i++) {
            for(int j = 0; j < length-i-1; j++) {
                if(unsortedArray[j] > unsortedArray[j+1]) {
                    swap(unsortedArray, j , j+1);
                }
            }
        }
        return unsortedArray;
    }

    // An optimized version of Bubble Sort    
    private int[] bubbleSortOptimized(int unsortedArray[]) {
        int i, j;
        int length = unsortedArray.length;
        boolean swapped;
        for (i = 0; i < length-1; i++) {
            swapped = false;
            for (j = 0; j < length-i-1; j++) {
                if (unsortedArray[j] > unsortedArray[j+1]) {
                    swap(unsortedArray, j , j+1);
                    swapped = true;
                }
            }
            // IF no two elements were swapped by inner loop, then break            if (swapped == false)
                break;
        }
        return unsortedArray;
    }

    private void swap(int[] array, int i1, int i2) {
        int temp;
        temp = array[i1];
        array[i1] = array[i2];
        array[i2] = temp;
    }
}




Worst and Average Case Time Complexity: O(n*n). Worst case occurs when array is reverse sorted.
Best Case Time Complexity: O(n). Best case occurs when array is already sorted.
Auxiliary Space: O(1)

Wednesday, 31 August 2016

Selection Sort


The selection sort algorithm sorts an array by repeatedly finding the minimum element (considering ascending order) from unsorted part and putting it at the beginning of an array.

How Selection Sorting Works




/*
 * Created by Ali on 8/31/2016. 
 * Selection Sort 
 */
public class SelectionSort {

    public static void main(String str[]){

        int[] arr = new int[]{10,54,2,100,200,121,99,150,51,181};
        SelectionSort obj = new SelectionSort();
        int[] sortedArray = obj.selectionSort(arr);
        for (int i = 0; i < sortedArray.length; i++) {
            System.out.print(sortedArray[i] + " ");
        }
    }

    private int[] selectionSort(int[] unsortedArray) {
        int minIndex=0, temp=0;
        for(int i=0;i<unsortedArray.length;i++){
            minIndex = i;
            for(int j=i+1; j<unsortedArray.length; j++){
                if(unsortedArray[j] < unsortedArray[minIndex]){
                    minIndex = j;
                }
            }
            if(minIndex != i){
                temp = unsortedArray[minIndex];
                unsortedArray[minIndex] = unsortedArray[i];
                unsortedArray[i] = temp;
            }
        }
        return unsortedArray;
    }
}

Time Complexity: O(n*n) as there are two nested loops.

Auxiliary Space: O(1)
The good thing about selection sort is it never makes more than O(n) swaps and can be useful when memory write is a costly operation.