JavaEE JDBC

Az előző példát fogjuk tovább alakítani. Úgy alakítjuk át, hogy adatbázisba fogjuk menteni az adatokat. Ehhez a JDBC-t fogjuk használni.

Szükségünk van egy java mysql-connector-java-5.1.26-bin.jar nevű fájlra, ami a mysql adatbázishoz kapcsolódást fogja segíteni. Az adatbázis drivereket innen tudjuk letölteni: https://www.mysql.com/products/connector/

Ezt a fájlt másoljuk be a WebContent\WEB-INF\lib mappába és a projekten jobb gomb properties a megjelenő ablakban javabuildpath, libraries fül. Add external jars gomb-nál kell betallózni a letöltött jdbc drivert. Ezután hozzákezdhetünk átalakítani a programunkat.

De még mielőtt nekiugrunk csináljunk egy adatbázist ProjectCar néven és abban egy táblát car néven:
CREATE TABLE `car` (
  `carId` varchar(8) COLLATE utf8_hungarian_ci NOT NULL,
  `color` varchar(20) COLLATE utf8_hungarian_ci NOT NULL,
  `fuel` varchar(10) COLLATE utf8_hungarian_ci NOT NULL,
  `performance` int(11) NOT NULL,
  PRIMARY KEY (`carId`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_hungarian_ci;


Az org.project.car.Car osztályunkat is módosítjuk. Csak annyit teszünk, hogy a performance változó típusát string-ről int-re cseréljük, mert az mégis csak szám:
 
package org.project.car;

public class Car {
	private String carId;
	private String color;
	private String fuel;
	private int performance;
	
	public String getCarId() {
		return carId;
	}
	public void setCarId(String carId) {
		this.carId = carId;
	}
	public String getColor() {
		return color;
	}
	public void setColor(String color) {
		this.color = color;
	}
	public String getFuel() {
		return fuel;
	}
	public void setFuel(String fuel) {
		this.fuel = fuel;
	}
	public int getPerformance() {
		return performance;
	}
	public void setPerformance(int performance) {
		this.performance = performance;
	}
	
}

Az org.project.car.service.CarService osztályon is csak az int-re történő átállás miatt módosítottunk egy kicsit:
 
package org.project.car.service;

import java.util.HashMap;

import org.project.car.Car;

public class CarService {
	HashMap<String, Car> cars = new HashMap<String, Car>();
	
	//check parameters are not empty
	public boolean check(String carId,String color, String fuel, int performance){

		if(carId == null || carId.trim() == "" || color == null || color.trim() == ""  
				|| fuel == null || fuel.trim() == "" || performance == 0 ){

			return false;
		} 
		else{ 
			// set new car parameters for cars hashmap 

			Car car = new Car();
			car.setCarId(carId);
			car.setColor(color);
			car.setFuel(fuel);
			car.setPerformance(performance);
			cars.put(carId,car); 

			return true;
		}
	}
	
	// get car parameters
	public Car getCarDetails(String carId){

		Car car = new Car();
		car.setCarId(carId);
		car.setColor(cars.get(carId).getColor());
		car.setFuel(cars.get(carId).getFuel());
		car.setPerformance(cars.get(carId).getPerformance());
		
		return car;
	}
}

Ezután csináljunk is valami érdekeset pl kapcsolódjuk az adatbázishoz. Ehhez készítünk egy új osztályt ami a kapcsolódást fogja elvégezni:


A tartalom a következő:
 
package org.project.database.connection;

import java.sql.Connection;
import java.sql.DriverManager;

public class Database {

        // connect database
	public static Connection getConnection() throws Exception{
		
		try{
			String  driver = "com.mysql.jdbc.Driver";
			String url = "jdbc:mysql://192.168.1.105:3306/ProjectCar";
			String username = "root";
			String password = "jelszó";
			Class.forName(driver);
			Connection conn = DriverManager.getConnection(url,username,password);
			System.out.println("connected");
			return conn;
			
		}catch(Exception e){
			System.out.println(e);
		}
		return null;
	}
	
}

Érdemes odafigyelni az ip címre(ha localhost van akkor könnyű helyzetben vagyunk), jelszavakra stb. Ezt a getConnection metódust fogjuk meghívni, ha kapcsolódni szeretnénk az adatbázishoz.

Készítsünk egy új osztályt ami az adatbázis műveleteket fogja nekünk megvalósítani:


A tartalom:
 
package org.project.database;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import org.project.database.connection.Database;

public class Queries {
	
	// Inserting data into the database
	public static void insertCar(String carId,String color, String fuel, int performance) throws Exception{
		
		PreparedStatement Stmt = null;		
		Connection Conn = null;
		
		try {
			Conn = Database.getConnection();

                        String sql = "insert into car (carId,color,fuel,performance) values (?,?,?,?);";
                        Stmt = Conn.prepareStatement(sql);
			
			Stmt.setString(1,carId);
			Stmt.setString(2,color);
			Stmt.setString(3,fuel);
			Stmt.setInt(4,performance);
			
			Stmt.executeUpdate();
			
			System.out.println("Insert complete");
			
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			//	e.printStackTrace();
			System.out.println(e);
		}
		
		return;
	}
}


Az insertCar metódus paraméterként megkapja az adatokat amiket megadtunk. Kapcsolódik az adatbázishoz és beszúrja az adatokat az adatbázisba.

Ezután már csak a CarServlet fájlt kell módosítanunk, hogy meghívja az insertCar metódust a megfelelő adatokkal:
 
package org.project.car.servlet;

import java.io.IOException;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.project.car.Car;
import org.project.car.service.CarService;
import org.project.database.Queries;

/**
 * Servlet implementation class CarServlet
 */
@WebServlet("/Form2")
public class CarServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		String carId, color, fuel;
		int performance;
		
		carId = request.getParameter("carId");
		color = request.getParameter("color");
		fuel = request.getParameter("fuel");
		performance = Integer.parseInt(request.getParameter("performance"));

		CarService carService = new CarService();		
		boolean result = carService.check(carId,color,fuel,performance);

		if (result){
			// get data
			Car car = carService.getCarDetails(carId);
			
			try {
				// Inserting data into the database
				Queries.insertCar(car.getCarId(),car.getColor(),car.getFuel(),car.getPerformance());
				
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
			// create view
			request.setAttribute("car", car); 
			RequestDispatcher dispatcher = request.getRequestDispatcher("Process.jsp");
			dispatcher.forward(request, response);

			return;
		}
		else {
			response.sendRedirect("Form.jsp");
			return;			
		}
	}

}

Ezután ha a Form.jsp-n az adatokat begépeljük, akkor a gomb megnyomása után bekerül az adatbázisba egy új rekord.

Jelenlegi struktúra:



Ha nem sikerülne kapcsolódni a mysql adatbázishoz, akkor a következő "szép" hibaüzenetekkel találkozhatunk:

Ha nincs engedélyezve a távoli elérés a mysql szerveren:
com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure
Last packet sent to the server was 1 ms ago.


megoldás: /etc/mysql/my.cnf -ben a bind-address paramétert kikell kommentelni. Ha van a skip-network paramétert is kommenteljük ki.

ha nincs engedélyezve a user:
java.sql.SQLException: null,  message from server: "Host '192.168.1.102' is not allowed to connect to this MySQL server"

ha nem jó a jelszó:
java.sql.SQLException: Access denied for user 'root'@'192.168.1.102' (using password: YES)

A mysql konzoljában, webes felületén vagy ahol tetszik, futassuk le a következő sql parancsot:
 
GRANT ALL PRIVILEGES ON *.* TO 'root'@'192.168.1.102' IDENTIFIED BY 'jelszó' WITH GRANT OPTION;
flush privileges;

A megfelelő paramétereket átkell írni, a root a mysql-es felhasználó amivel csatlakozni szeretnénk, az ip a kliens gép ip-je a jelszó pedig a mysql-es jelszó. Azért élesben gondoljuk meg mennyi jogot osztunk a felhasználóinknak és milyen ip-kre adunk engedélyt.

Ezután ha update, delete query-ket akarunk írni, akkor csak átkell írni az sql változóban az sql parancsot. Még nézzünk egy egy select-et is. A Queries osztályba hoztam létre egy plusz metódust:
public static void selectCar() throws Exception{
		Connection Conn = null;
		ResultSet results = null;
		PreparedStatement Stmt = null;
		
		try {
			Conn = Database.getConnection();
			
			// prepare statement
			Stmt = Conn.prepareStatement("select * from car where color = ?");
									
			// set parameters
  			Stmt.setString(1,"piros");
					
 			// execute sql query
 			results = Stmt.executeQuery();
			
			System.out.println("Insert complete");
			 while (results.next()) {
				 System.out.println("results: " + 
						 results.getString(results.findColumn("carId")) + " " +
				 		 results.getString(results.findColumn("color")) + " " +
				 		 results.getString(results.findColumn("fuel")) + " " +
				 		 results.getString(results.findColumn("performance"))
				 ); 
			 }
			
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			//	e.printStackTrace();
			System.out.println(e);
		}

PrepareStatement-et használunk, rá szűrünk arra, hogy csak a piros színű autók adatait szeretnénk visszakapni. A ResultSet -ben fogjuk megkapni az eredményt és itt most csak a konzolra íratjuk ki az eredményt.


https://www.youtube.com/watch?v=8-iQDUl10vM&index=1&list=PLEAQNNR8IlB4R7NfqBY1frapYo97L6fOQ
2015.08.15.