JDBC连接数据库   

•创建一个以JDBC连接数据库的程序,包含7个步骤:   

 1、加载JDBC驱动程序:     

         在连接数据库之前,首先要加载想要连接的数据库的驱动到JVM(Java虚拟机),   

 这通过java.lang.Class类的静态方法forName(String  className)实现。  

例如:

try{   
	//加载MySql的驱动类   
	Class.forName("com.mysql.jdbc.Driver") ;   
}catch(ClassNotFoundException e){   
	System.out.println("找不到驱动程序类 ,加载驱动失败!");   
	e.printStackTrace() ;   
}

成功加载后,会将Driver类的实例注册到DriverManager类中。 


 2、提供JDBC连接的URL   

•连接URL定义了连接数据库时的协议、子协议、数据源标识。   

•书写形式:协议:子协议:数据源标识   

        协议:在JDBC中总是以jdbc开始   

        子协议:是桥连接的驱动程序或是数据库管理系统名称。   

        数据源标识:标记找到数据库来源的地址与连接端口。   

例如:(MySql的连接URL  jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=gbk ;   

         useUnicode=true:表示使用Unicode字符集。

        characterEncoding=gbk:字符编码方式。

        如果characterEncoding设置为 gb2312或GBK,本参数必须设置为true 。

     
 3、创建数据库的连接 

•要连接数据库,需要向java.sql.DriverManager请求并获得Connection对象, 该对象就代表一个数据库的连接。   

•使用 DriverManager的getConnectin( String url , String username , String password )方法

        传入指定的欲连接的数据库的路径、数据库的用户名和密码来获得。

例如:

//连接MySql数据库,用户名和密码都是root   
	String url = "jdbc:mysql://localhost:3306/test" ;    
	String username = "root" ;   
	String password = "root" ;   
	try{   
		Connection con = DriverManager.getConnection(url , username , password ) ;   
	}catch(SQLException se){   
		System.out.println("数据库连接失败!");   
		se.printStackTrace() ;   
	}

 4、创建一个Statement   

•要执行SQL语句,必须获得java.sql.Statement实例,Statement实例分为以下3 种类型:   

      1、执行静态SQL语句。通常通过Statement实例实现。   

      2、执行动态SQL语句。通常通过PreparedStatement实例实现。   

      3、执行数据库存储过程。通常通过CallableStatement实例实现。   

 具体的实现方式:   

Statement stmt = con.createStatement() ;   
PreparedStatement pstmt = con.prepareStatement(sql) ;   
CallableStatement cstmt = con.prepareCall("{CALL demoSp(? , ?)}") ;


 5、执行SQL语句   

Statement接口提供了三种执行SQL语句的方法:executeQuery 、executeUpdate  和execute。   

1、ResultSet executeQuery(String sqlString):执行查询数据库的SQL语句 ,返回一个结果集(ResultSet)对象。   

2、int executeUpdate(String sqlString):用于执行INSERT、UPDATE或   DELETE语句以及SQL DDL语句,如:CREATE TABLE和DROP TABLE等   

3、execute(sqlString):用于执行返回多个结果集、多个更新计数或二者组合的 语句。   

具体实现的代码:

ResultSet rs = stmt.executeQuery("SELECT * FROM ...") ;   
	int rows = stmt.executeUpdate("INSERT INTO ...") ;   
	boolean flag = stmt.execute(String sql) ;

 6、处理结果   

两种情况:   

     1、执行更新返回的是本次操作影响到的记录数。   

      2、执行查询返回的结果是一个ResultSet对象。   

• ResultSet包含符合SQL语句中条件的所有行,并且它通过一套get方法提供了对这些行中数据的访问。

• 使用结果集(ResultSet)对象的访问方法获取数据:   

while(rs.next()){   
	String name = rs.getString("name") ;   
	String pass = rs.getString(1) ; // 此方法比较高效   
}

(列是从左到右编号的,并且从列1开始) 


 7、关闭JDBC对象    

操作完成以后要把所有使用的JDBC对象全都关闭,以释放JDBC资源,关闭顺序和声 明顺序相反:   

     1、关闭记录集   

     2、关闭声明   

     3、关闭连接对象

if(rs != null){   // 关闭记录集   
	try{   
		rs.close() ;   
	}catch(SQLException e){   
		e.printStackTrace() ;   
	}   
}   
if(stmt != null){   // 关闭声明   
	try{   
		stmt.close() ;   
	}catch(SQLException e){   
		e.printStackTrace() ;   
	}   
}   
if(conn != null){  // 关闭连接对象   
	try{   
		conn.close();   
	}catch(SQLException e){   
		e.printStackTrace() ;   
	}   
}

进一步的封装:

package util;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Date;


public class MysqlUtilNew {
	
	private static String driver = "com.mysql.cj.jdbc.Driver";
	private static String dbName = "test";
	private static String passwrod = "test";
	private static String userName = "test";
	private static String url = "jdbc:mysql://dxx.xxxx.cn:3610/" + dbName;

	private static Connection conn = null;

	private PreparedStatement ps = null;
	private ResultSet rs = null;

	static {
		initConn();
	}

	private static void initConn() {
		try {
			Class.forName(driver);
			conn = DriverManager.getConnection(url, userName, passwrod);
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}

	public static void closeConn() {
		// 关闭链接对象
		if (conn != null) {
			try {
				conn.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
	}

	public MysqlUtilNew() {

	}

	public void releaseRes() {
		try {
			if (rs != null) {
				this.rs.close();
			}
			if (ps != null) {
				this.ps.close();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}finally{
			// 关闭记录集
			if (this.rs != null) {
				try {
					rs.close();
				} catch (SQLException e) {
					e.printStackTrace();
				}
			}
			// 关闭声明
			if (this.ps != null) {
				try {
					ps.close();
				} catch (SQLException e) {
					e.printStackTrace();
				}
			}
		}
	}

	public void prePareQuery(String sql) {
		try {
			this.ps = conn.prepareStatement(sql);
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}

	public ResultSet execPreQueryWithParms(Object... objs) {

		try {
			for (int i = 0; i < objs.length; i++) {
				if (objs[i] instanceof Integer) {
					int it = ((Integer) objs[i]).intValue();
					this.ps.setInt(i + 1, it);
				} else if (objs[i] instanceof String) {
					String s = (String) objs[i];
					this.ps.setString(i + 1, s);
				} else if (objs[i] instanceof Double) {
					double d = ((Double) objs[i]).doubleValue();
					this.ps.setDouble(i + 1, d);
				} else if (objs[i] instanceof Float) {
					float f = ((Float) objs[i]).floatValue();
					this.ps.setFloat(i + 1, f);
				} else if (objs[i] instanceof Long) {
					long l = ((Long) objs[i]).longValue();
					this.ps.setLong(i + 1, l);
				} else if (objs[i] instanceof Boolean) {
					boolean b = ((Boolean) objs[i]).booleanValue();
					this.ps.setBoolean(i + 1, b);
				} else if (objs[i] instanceof Date) {
					Date d = (Date) objs[i];
					java.sql.Date date = new java.sql.Date(d.getTime());
					this.ps.setDate(i + 1, (java.sql.Date) date);
				}
			}
			this.rs = ps.executeQuery();	
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return rs;
	}

	public ResultSet execQuery(String sql, Object... objs) {
		this.prePareQuery(sql);
		this.rs = this.execPreQueryWithParms(objs);
		return rs;
	}

	public static void main(String[] args) {
		MysqlUtilNew test = new MysqlUtilNew();
		Object[] params = { 14089 };
		ResultSet rs = test.execQuery(
				"SELECT * FROM conf_location WHERE country = ? LIMIT 1", params);
		try {
			while (rs.next()) {
				System.out.println("country_name : "
						+ rs.getString("country_name"));
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
		test.releaseRes();

		MysqlUtilNew test2 = new MysqlUtilNew();
		Object[] params2 = { 14089 };
		ResultSet rs2 = test.execQuery(
				"SELECT * FROM conf_location WHERE region = ? LIMIT 1", 0);
		try {
			while (rs2.next()) {
				System.out.println("region_name : "
						+ rs2.getString("region_name"));
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
		test2.releaseRes();
	}
}

Maven 依赖:

<dependencies>
	<dependency>
	  <groupId>commons-io</groupId>
	  <artifactId>commons-io</artifactId>
	  <version>2.4</version>
	</dependency>
	
	<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
	<dependency>
	    <groupId>mysql</groupId>
	    <artifactId>mysql-connector-java</artifactId>
	    <version>6.0.6</version>
	</dependency>
  </dependencies>

遇到的问题:

Java与mysql数据库编程中遇见“Before start of result set at com.mysql.jdbc.SQLError.createSQLException” 

        这个Bug是因为在取出ResultSet对象,对其进行操作时,没有采用.next()方法将ResultSet对象的光标移至指定行,

不管Statement对象执行SQL语句是否十分确定能搜出记录,也不可以在没有ResultSet的next()方法之前直接对 ResultSet对象进行取值