JDBC之入門篇

什麼是jdbc:

JDBC(Java DataBase Connectivity)就是Java數據庫連接,說白了就是用Java語言來操作數據庫。原來我們操作數據庫是在控制檯使用SQL語句來操作數據庫,JDBC是用Java語言向數據庫發送SQL語句。


jdbc原理:


早期SUN公司的天才們想編寫一套可以連接天下所有數據庫的API,但是當他們剛剛開始時就發現這是不可完成的任務,因爲各個廠商的數據庫服務器差異太大了。後來SUN開始與數據庫廠商們討論,最終得出的結論是,由SUN提供一套訪問數據庫的規範(就是一組接口),並提供連接數據庫的協議標準,然後各個數據庫廠商會遵循SUN的規範提供一套訪問自己公司的數據庫服務器的API出現。SUN提供的規範命名爲JDBC,而各個廠商提供的,遵循了JDBC規範的,可以訪問自己數據庫的API被稱之爲驅動JDBC是接口,而JDBC驅動纔是接口的實現,沒有驅動無法完成數據庫連接!每個數據庫廠商都有自己的驅動,用來連接自己公司的數據庫。



jdbc核心類:(先混個眼熟吧)


DriverManger  Connection  Statement  ResultSet

DriverManger(驅動管理器)的作用有兩個:

l  註冊驅動:這可以讓JDBC知道要使用的是哪個驅動;

l  獲取Connection:如果可以獲取到Connection,那麼說明已經與數據庫連接上了。


Connection對象表示連接,與數據庫的通訊都是通過這個對象展開的:

l  Connection最爲重要的一個方法就是用來獲取Statement對象;


Statement是用來向數據庫發送SQL語句的,這樣數據庫就會執行發送過來的SQL語句:

l  void executeUpdate(String sql):執行更新操作(insert、update、delete等);

l  ResultSet executeQuery(String sql):執行查詢操作,數據庫在執行查詢後會把查詢結果,查詢結果就是


ResultSet;

ResultSet對象表示查詢結果集,只有在執行查詢操作後纔會有結果集的產生。結果集是一個二維的表格,有行有列。操作結果集要學習移動ResultSet內部的“行光標”,以及獲取當前行上的每一列上的數據:

l  boolean next():使“行光標”移動到下一行,並返回移動後的行是否存在;

XXX getXXX(int col):獲取當前行指定列上的值,參數就是列數,列數從1開始,而不是0。


怎麼用:

NO.1 導包:數據庫的驅動包:mysql爲例,mysql-connector-java-5.1.13-bin.jar


NO.2 準備四大參數:driverClassName、url、username、password  


No.3 註冊驅動類 :Class.froName(driverClassName);搞定


No.4 獲取連接 : DriverManger.getConnection(url,username,password);

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;

import org.junit.Test;

public class DemoTwo {
	@Test
	public void fun1() throws ClassNotFoundException, SQLException {
		
		String driverClassName = "com.mysql.jdbc.Driver";
		String url = "jdbc:mysql://localhost:3306/demo";
		
		String user = "root";		
		String password = "123";
		
		Class.forName(driverClassName);
		
		//得到連接
		Connection connection = DriverManager.getConnection(url, user, password);
		
		//創建聲明
		Statement statement = connection.createStatement();
		
//		執行查詢操作
		String sqlString = "select * from bm_list";
		
		ResultSet rs = statement.executeQuery(sqlString);//返回結果集。
		
		/*
		 * rs內部有一個遊標:
		 * 光標默認位置是第一行的前面
		 * rs.next()把光標位置向下移動一行。next()方法返回的boolean表示是否有這一行。
		 * 可利用這個方法對結果集進行遍歷,前提是你需要知道字段名,或者其屬性。
		 */
		//rs.next();
		
//		Object o = rs.getObject(1);
//		System.out.println(o);
		
//		String qq = rs.getString("qq");
//		String name = rs.getString("real_name");
/*		這兩種方法都可以對其進行遍歷。
		for (int i = 0; rs.next(); i++) {
			String qq = rs.getString("qq");
			String name = rs.getString("real_name");
			System.out.println("姓名:"+name+"  qq:"+qq);
		}

		while (rs.next()) {
			String qq = rs.getString("qq");
			String name = rs.getString("real_name");
			System.out.println("姓名:"+name+"  qq:"+qq);
		}
*/		如果列名不知道可以用如下方法獲取。
		//獲取結果集列數和行數!
		
		rs.last();//將光標設置到最後一行
		int row = rs.getRow();//獲取行數
		rs.beforeFirst();//將光標移到初始位置
		
		//獲取結果列的列數。
		ResultSetMetaData rsmd = rs.getMetaData();
		int columnCount = rsmd.getColumnCount();	//獲取結果集列數
		String columnName = rsmd.getColumnName(1);	//獲取第一列的名稱
		
		System.out.println("共有"+row+"行數據,並且有"+columnCount+"列,第1列列名是"+columnName);
		
		
		//獲取所有數據
		while (rs.next()) {
			for (int i = 1; i <= columnCount; i++) {
				//String cName = rsmd.getColumnName(i);//獲得每列的名稱。
				Object o = rs.getObject(i);
				
				System.out.print(o + "  ");
			}
		}
		
		/*
		 * 資源關閉順序:
		 * 想得到的後關閉!
		 */
		rs.close();
		statement.close();
		connection.close();
		
	}
}



如何防止SQL攻擊:

preparedStatement(預編譯聲明)

查詢api可以知道preparedStatement接口是接口Statement的子接口,使用它有以下好處:

l  防止SQL攻擊;

l  提高代碼的可讀性,以可維護性;

l  提高效率。


使用方法及代碼規範化:

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

import org.junit.Test;

public class MyPreparadStatementTest {
	/**
	 * 使用preparadStatement(預編譯聲明)進行的增刪改查!
	 */
	@Test
	public void insert() {
		Connection con = null;
		PreparedStatement pStatement = null;
		
		try {
			Class.forName("com.mysql.jdbc.Driver");
			con = DriverManager.getConnection("jdbc:mysql://localhost:3306/jdbctest", "root", "123");
			//使用sql模板,問好對應下面setXXX();的第一個參數,從1開始。。
			String sql = "insert into test1 values(?,?,?,?)";
			
			pStatement = con.prepareStatement(sql);
			
			pStatement.setInt(1, 3);
			pStatement.setString(2, "吾王");
			pStatement.setString(3, "18");
			pStatement.setString(4, "898989898");
			
			//調用execute(),可以執行添加、修改、刪除操作。
			pStatement.executeUpdate();
			
		} catch (Exception e) {
			throw new RuntimeException(e);
		}finally{
				try {
					if(pStatement != null)pStatement.close();
					if(con != null)con.close();
					
				} catch (SQLException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
		}
		
	}
	
	@Test
	public void update() {
		Connection con = null;
		PreparedStatement pStatement = null;
		
		try {
			Class.forName("com.mysql.jdbc.Driver");
			con = DriverManager.getConnection("jdbc:mysql://localhost:3306/jdbctest", "root", "123");
			
			String sql = "update test1 set name = ?,qq = ?,age = ? where id = ?";
			
			pStatement = con.prepareStatement(sql);
			
			pStatement.setString(2, "898989898");
			pStatement.setString(1, "saber");
			pStatement.setString(3, "16");
			pStatement.setInt(4, 3);
			
			pStatement.executeUpdate();
			
		} catch (Exception e) {
			throw new RuntimeException(e);
		}finally{
				try {
					if(pStatement != null)pStatement.close();
					if(con != null)con.close();
					
				} catch (SQLException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
		}
		
	}
	@Test
	public void delete() {
		Connection con = null;
		PreparedStatement pStatement = null;
		
		try {
			Class.forName("com.mysql.jdbc.Driver");
			con = DriverManager.getConnection("jdbc:mysql://localhost:3306/jdbctest", "root", "123");
			
			String sql = "delete from test1 where id = ?";
			
			pStatement = con.prepareStatement(sql);
			
			pStatement.setInt(1, 1);
			
			pStatement.executeUpdate();
			
		} catch (Exception e) {
			throw new RuntimeException(e);
		}finally{
				try {
					if(pStatement != null)pStatement.close();
					if(con != null)con.close();
					
				} catch (SQLException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
		}
		
	}
	@Test
	public void query() {
		Connection con = null;
		PreparedStatement pStatement = null;
		ResultSet rs = null;
		
		try {
			Class.forName("com.mysql.jdbc.Driver");
			con = DriverManager.getConnection("jdbc:mysql://localhost:3306/jdbctest", "root", "123");
			
			String sql = "select * from test1 where name = ? or age = ?";
			
			pStatement = con.prepareStatement(sql);
			
			pStatement.setString(1, "saber");
			pStatement.setString(2, "18");
			
			rs = pStatement.executeQuery();
		
			
			//獲取列。。遍歷結果集
			ResultSetMetaData metaData = rs.getMetaData();
			int count = metaData.getColumnCount();
			
			while (rs.next()) {
				for (int i = 1; i <= count; i++) {
					Object object = rs.getObject(i);
					System.out.println("查詢結果是:"+object);
				}
			}
			
			
		} catch (Exception e) {
			throw new RuntimeException(e);
		}finally{
				try {
					/*
					 * 資源關閉順序:
					 * 先得到的後關閉!
					 * 一定要關閉資源!
					 */
					if(rs != null)rs.close();
					if(pStatement != null)pStatement.close();
					if(con != null)con.close();
					
				} catch (SQLException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
		}
		
	}
}




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章