JDBC连接
工作好久了,突然涉及到数据源开发,一下子懵逼了,后来查资料,才得以完成工作,今天过来记录以下:
1.首先来了解以下JDBC
JDBC全称:Java Database Connection
sun公司为了简化、统一对数据库的操作,定义了一套Java操作数据库的接口的规范,这样各个数据库厂商可以自己定义自己的实现
2.JDBC入门案例
package com.jdbc;
import com.mysql.jdbc.Driver;
import java.sql.*;
/**
* jdbc的几个步骤
* 1.注册驱动
* 2.获取连接
* 3.获取发送sql的对象
* 4.处理结果
* 5.关闭资源
* */
public class JDBC {
public void demo1() throws SQLException {
//注册驱动
DriverManager.registerDriver(new Driver());
//获取连接
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/user","root","root");
//获取发送sql的对象(这里涉及到两个可选对象Statement/PreparedStatement)
Statement stat = conn.createStatement();
//处理结果
ResultSet rs = stat.executeQuery("select * from user ");
while(rs.next()){
System.out.println(rs.getInt("id") + "--" + rs.getString("name"));
}
//关闭资源
rs.close();
stat.close();
conn.close();
}
public static void main(String[] args) throws SQLException {
new JDBC().demo1();
}
}
3、我们先来分析一下上面的程序
JDBC中DriverManager用于加载驱动、并创建与数据库的链接
我们在代码上述代码中使用了
//注册驱动
DriverManager.registerDriver(new Driver());
这里的new Driver()是mysql的驱动jar包,但是很少有人会这么写,为啥?
请看下面的分析!
package com.mysql.jdbc;
import java.sql.DriverManager;
import java.sql.SQLException;
public class Driver extends NonRegisteringDriver implements java.sql.Driver {
public Driver() throws SQLException {
}
static {
try {
DriverManager.registerDriver(new Driver());
} catch (SQLException var1) {
throw new RuntimeException("Can't register driver!");
}
}
}
看到红色的代码吗?这是刚刚进入那个new Driver()看到的mysql的驱动类的代码,这里面又进行注册了一遍了
所以一般我们都会使用Class.forName("com.mysql.jdbc.Driver")来加载驱动类
我们来看看一个完整的案例:
public void demo2() throws ClassNotFoundException, SQLException {
//注册驱动
Class.forName("com.mysql.jdbc.Driver");
//获取连接
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/user","root","root");
//获取发送sql的对象
Statement stat = conn.createStatement();
//row受影响的行数
int row = stat.executeUpdate("insert into user(id,name) values(32000,'hello')");
if(row > 0){
System.out.println("受影响的行数: " + row);
}
//关闭资源,资源一定要从后往前关,至于原因自己想想
stat.close();
conn.close();
}
4、我们再来分析一下Statement,前面的demo1我们使用了executeQuery,demo2使用了executeUpdate方法
相信都看出来了,第一个方法(executeQuery)是用来查询用的,executeUpdate方法是用来执行增删改的,当然还有一个综合方法execute方法,我们看下面的示例:
public void demo3() throws ClassNotFoundException, SQLException {
//注册驱动
Class.forName("com.mysql.jdbc.Driver");
//获取连接
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/user","root","root");
//获取发送sql的对象
Statement stat = conn.createStatement();
//如果是true就相当于执行的executeQuery反之就是executeUpdate
boolean e = stat.execute("update user set name='信息' where id = 1");
ResultSet rs = null;
if(e){
rs = stat.getResultSet();
while(rs.next()){
System.out.println(rs.getInt("id") + "---" + rs.getString("name"));
}
} else {
int row = stat.getUpdateCount();
System.out.println("受影响的行数: " + row);
}
//关闭资源
if(null != rs){
rs.close();
}
if(null != stat){
stat.close();
}
if(null != conn){
conn.close();
}
}
5、前面每次都要写数据连接的重复代码以及关闭资源的操作,下面我们将其封装
import java.io.InputStream;
import java.sql.*;
import java.util.Properties;
public class JDBCUtils {
private static String url;
private static String username;
private static String password;
private static String driver;
static {
Properties properties = new Properties();
InputStream in = JDBCUtils.class.getClassLoader().getResourceAsStream("jdbc.properties");
try {
properties.load(in);
url = (String) properties.get("url");
username = (String) properties.get("username");
password = (String) properties.get("password");
driver = (String) properties.get("driver");
Class.forName(driver);
} catch (Exception e) {
e.printStackTrace();
}
}
public static Connection getConnection(){
Connection conn = null;
try {
conn = DriverManager.getConnection(url,username,password);
}catch (Exception e){
e.printStackTrace();
}
return conn;
}
public static void releaseResource(ResultSet rs,Statement stat,Connection conn){
try {
if(null != rs){
rs.close();
}
rs = null;//将对象置为null,GC回收
if(null != stat){
stat.close();
}
stat = null;
if(null != conn){
conn.close();
}
conn = null;
}catch (Exception e){
e.printStackTrace();
}
}
public static void releaseResource(ResultSet rs, PreparedStatement ps,Connection conn){
try {
if(null != rs){
rs.close();
}
rs = null;
if(null != ps){
ps.close();
}
ps = null;
if(null != conn){
conn.close();
}
conn = null;
}catch (Exception e){
e.printStackTrace();
}
}
6、下面我们用用我们的工具类以及使用另外一个PreparedStatement,为什么用PreparedStatement呢?因为可以防止SQL注入的问题啦
public void demo4() throws SQLException {
Connection conn = JDBCUtils.getConnection();
//这里使用了PrepareStatement
PreparedStatement ps = conn.prepareStatement("update user set name=? where id = ?");
ps.setString(1,"你好");
ps.setInt(2,1);
int row = ps.executeUpdate();
if(row > 0){//使用工具类一下子代码精简了很多
System.out.println("受影响的行数: " + row);
}
}
7、下面是批处理的示例
/**
* 下面是一个批处理的示例
*
* */
public void demo5() throws SQLException {
Connection conn = JDBCUtils.getConnection();
PreparedStatement ps = conn.prepareStatement("insert into user (id,name) values (?,?)");
for(int i = 1;i <= 10000;i++){
ps.setInt(1,i);
ps.setString(2,i+"");
ps.addBatch();
if(i % 500 == 0){
ps.executeBatch();
ps.clearBatch();
}
}
JDBCUtils.releaseResource(null,ps,conn);
}
8、下面是一个完整的事务控制的示例
/**
* 完整的jdbc示例
*
*
* */
public void demo6(){
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
conn = JDBCUtils.getConnection();
//开启事务
conn.setAutoCommit(false);
ps = conn.prepareStatement("update user set name=? where id = ?");
ps.setString(1,"kkk");
ps.setInt(2,1);
int rows = ps.executeUpdate();
conn.commit();
if(rows > 0){
System.out.println("受影响的行数: " + rows);
}
}catch (Exception e){
e.printStackTrace();
} finally {
JDBCUtils.releaseResource(rs,ps,conn);
}
}
浙公网安备 33010602011771号