Java学习总结(十九)——JDBC操作数据库,预编译的使用,事务,常见的连接池

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java学习总结(十九)——JDBC操作数据库,预编译的使用,事务,常见的连接池相关的知识,希望对你有一定的参考价值。

一.JDBC操作数据库

1. JDBC(Java DataBase Connection,java数据库连接),由一些接口和类构成的API。

图示:

 技术分享图片

2. JDBC操作数据库的步骤:

(1)注册驱动

(2)建立连接(Connectoin)

(3)创建执行SQL的语句(Statement)

(4)执行SQL语句(通过StatementPreparedStatement

(5)处理执行结果(resultSet

(6)释放资源

3. 建立连接:

(1)Connection conn=DriverManager.getConnection(url,user,password);

(2)Url格式:Jdbc:子协议://主机名:端口/数据库名? 属性名=属性值&......

3User(用户名),password(密码)可以用,“属性名=属性值”方式告诉数据库

4)其他参数如:

useUnicode=true&characterEncoding=GBK

4. 执行sql时:

(1)增,删,改用executeUpdate()方法

(2)查询时使用executeQuery()方法

1(向数据库中添加元素):

(1)创建工程,引入数据库连接jar包,并建立环境连接;

技术分享图片

(2)编写代码(往):

package org.jdbc.insert;

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

public class InsertDemo {

	public static void main(String[] args) {
		Connection conn = null;
		Statement stat = null;
		try {
			// 1.建立驱动,加载驱动程序
			Class.forName("com.mysql.jdbc.Driver");
			// 2.建立连接,与数据库进行连接
			conn = DriverManager.getConnection(
					"jdbc:mysql://localhost:3306/mydb?characterEncoding=utf8",
					"root", "qitao1996");
			// 3.编写待执行的sql语句,以及sql语句执行对象
			String sql = "insert into students(id,name,age,score) values(15,'丁明君',22,93.2),(16,'小昭',18,94.7)";
			stat = conn.createStatement();
			// 4.执行sql语句,并返回影响数据库表中的行数
			int count = stat.executeUpdate(sql);
			// 5.处理运行结果
			if (count > 0) {
				System.out.println("数据添加成功,影响了表中" + count + "行数据!!!!!");
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				// 6.释放资源
				conn.close();
				stat.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
	}

}

 

 

3运行结果:

技术分享图片

2(查询数据库中元素,并打印到控制台):

1)编写代码:

package org.jdbc.select;

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

public class QueryDemo {

	public static void main(String[] args) {
		Connection conn=null;
		Statement stat=null;
		ResultSet rs=null;
		try {
			Class.forName("com.mysql.jdbc.Driver");//建立驱动
			//建立连接
			conn=DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb?user=root&password=qitao1996");
			String sql="select * from students";//编写sql语句
			stat=conn.createStatement();//创建执行
			rs= stat.executeQuery(sql);//执行sql语句,并返回查询到的结果集
			System.out.println("获取到的学生信息为:");
			System.out.println("学号	姓名	年龄	成绩");
			//遍厉获取查询到的结果集
			while(rs.next()){
				int id=rs.getInt("id");
				String name=rs.getString("name");
				int age=rs.getInt("age");
				double score=rs.getDouble("score");
				System.out.println(id+"	"+name+"	"+age+"	"+score);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}finally{
			try {
				conn.close();
				stat.close();
				rs.close();//释放资源
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
	}

}

 

2)运行结果:

技术分享图片

5. 批处理:

1)应用addBatch()方法添加批处理语句

2)使用executeBatch方法执行批处理

3(分别编写增,删,改语句各一条一次执行):

(1)编写代码:

package org.jdbc.batch;

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

public class BatchDemo {

	public static void main(String[] args) {
		Connection conn=null;
		Statement stat=null;
		try {
			Class.forName("com.mysql.jdbc.Driver");//建立驱动
			//建立连接
			conn=DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb","root","qitao1996");
			stat=conn.createStatement();
			//下面添加批处理语句
			stat.addBatch("insert into students(id,name,age,score) values(12,'荆轲',20,97.2 )");
			stat.addBatch("delete from students where id=7");
			stat.addBatch("update students set id=10 where id=9");
			int[] array=stat.executeBatch();//执行批处理命令
			int i=1;
 			for(int count:array){
				System.out.println("第"+i+"条语句执行影响行数为"+count);
				i++;
			}
		} catch (Exception e) {
			e.printStackTrace();
		}finally{
			try {
				conn.close();
				stat.close();
				
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
	}

}


 

(2)运行结果:

技术分享图片

二.PreparedStatement的使用

1. preparedStatement是Statement的子接口,属于预处理操作

2. 获取PreparedStatement的方法:

使用Connection对象的PreparedStatement preparedstatement(String sql)

3. 使用PreparedStatement的好处:

(1)对于相同结构的SQL,可以提高执行效率:

@@1.在创建PreparedStatement对象时就指定了sql语句,该语句将立即被发送给DBMS进行编译

@@2.预编译的语句被存储在DBMS的缓存中,下次执行相同的SQL语句时,则可以从缓存中取出来。

(2)可以有效地预防SQL注入:

在使用参数化查询的情况下,数据库系统(DBMS)不会将参数的内容视为SQL指令的一部分来处理,而是在数据库完成SQL指令的编译后,才套用参数运行,即使参数中含有恶意的指令,也不会被数据库所运行

根据以前所学,我们先来编写一个获取JDBC连接的对象的工具类方便后续代码使用:

(1)首先在src目录下新建一个properties属性文件

技术分享图片

内容:

 

driverclass=com.mysql.jdbc.Driver
user=root
password=qitao1996
url=jdbc:mysql://127.0.0.1:3306/boke18


(2)编写工具类代码

package org.jdbc.util;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;

//操作数据库的工具类
public class DBUtil {

	// 私有化构造方法
	private DBUtil() {
	}

	private static String url = null;
	private static String user = null;
	private static String password = null;

	static {
		try {
			Class.forName("com.mysql.jdbc.Driver");
			Properties pro = new Properties();
			pro.load(new FileInputStream("src/jdbc.properties"));
			url = pro.getProperty("url");
			user = pro.getProperty("user");
			password = pro.getProperty("password");
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	// 读取外部属性文件获取连接对象,需手动输入url
	public static Connection getConnection1(String url) {
		Properties pro = new Properties();
		Connection conn = null;
		InputStream input = null;
		try {
			input = new FileInputStream("E:" + File.separator
					+ "JDBC.properties");
			pro.load(input);
			conn = DriverManager.getConnection(url, pro);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return conn;

	}

	// 读取工程下的配置文件,获取连接对象参数,不需手动输入url
	public static Connection getConnection2() throws SQLException {
		Connection conn = DriverManager.getConnection(url, user, password);
		return conn;
	}

	// 释放全部资源
	public static void closeAll(Connection conn, Statement stat, ResultSet rs)
			throws SQLException {
		if (conn != null) {
			conn.close();
		}
		if (stat != null) {
			stat.close();
		}
		if (rs != null) {
			rs.close();
		}
	}

	// 释放所用资源
	public static void closePart(Connection conn, Statement stat)
			throws SQLException {
		if (conn != null) {
			conn.close();
		}
		if (stat != null) {
			stat.close();
		}
	}
}

 

 

1(根据拼串来模拟SQL注入):

(1)利用上述工具类编写代码:

package org.jdbc.inject;

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

import org.jdbc.util.DBUtil;

public class SqlInjectDemo {

	public static void main(String[] args) {
		Statement stat=null;
		ResultSet rs=null;
		Connection conn=null;
		try {
			conn=DBUtil.getConnection2();
			stat=conn.createStatement();
			String username="西施";
			String password="xyz' or '1=1";
			String sql="select * from user where username='"+username+"' and password='"+password+"'";
			System.out.println(sql);
			rs=stat.executeQuery(sql);
			if(rs.next()){
				System.out.println("恭喜你登录,成功");
			}else{
				System.out.println("很遗憾,你的用户名或密码输入错误,登录失败");
			}
		} catch (Exception e) {
			e.printStackTrace();
		}finally{
			try {
				DBUtil.closeAll(conn, stat, rs);
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
	}

}


 

 

(2)运行结果:

技术分享图片

我们来查询user表中元素,看看是否出现了sql注入现象

技术分享图片

对比可以知道,在这个例子中就出现了SQL注入,导致我们程序的不安全性

2(现在我们来使用预编译的方法防止SQL的注入):

1)编写代码:

package org.jdbc.inject;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import org.jdbc.util.DBUtil;

public class StopInject {

	public static void main(String[] args) {
		PreparedStatement ps = null;
		ResultSet rs = null;
		Connection conn = null;
		String sql = "select * from user where username=? and password=? ";// 编写预编译sql
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		try {
			conn = DBUtil.getConnection2();
			ps = conn.prepareStatement(sql);
			System.out.print("请输入用户名:");
			String username = br.readLine();
			System.out.print("请输入密码:");
			String password = br.readLine();
			ps.setString(1, username);
			ps.setString(2, password);
			rs = ps.executeQuery();// 执行sql语句
			if (rs.next()) {
				System.out.println("恭喜你,登录成功....");
			} else {
				System.out.println("你的用户名或密码输入错误,登录失败....");
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				DBUtil.closeAll(conn, ps, rs);
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}

	}

}


2)运行结果:

当用户名密码都正确时:

技术分享图片

利用拼串,鼓故意写错密码时:

技术分享图片

由此我们清楚地发现预编译有效地防止了SQL注入现象

3(使用预编译向表中添加和查询元素):

(1)编写代码:

package org.jdbc.inject;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import org.jdbc.bean.User;
import org.jdbc.util.DBUtil;

public class InsertDemo {
	// 获取类中可以共用的对象
	private static Connection conn = null;
	private static PreparedStatement ps = null;
	private static ResultSet rs = null;
	// 代码运行时即开始连接数据库
	static {
		try {
			conn = DBUtil.getConnection2();
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}

	// 添加元素
	public static void main(String[] args) {
		String sql = "insert into user(username,password) values(?,?)";
		try {
			// 将SQL发送到DBMS中,进行预编译,将预编译好的SQL存储于DBMS的缓冲区中
			ps = conn.prepareStatement(sql);
			for (int i = 1; i <= 5; i++) {
				ps.setString(1, "貂蝉" + i);
				ps.setString(2, "64262" + i);
				ps.executeUpdate();
			}
			System.out.println("数据库中批量添加元素成功...");
			System.out.println("查看表中元素");
			userInsert();// 调用对象添加方法
			selectAll();// 调用查询方法
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			try {
				DBUtil.closePart(conn, ps);// 释放资源
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
	}

	// 查询元素
	public static void selectAll() {
		List<User> list = new ArrayList<User>();
		String sql = "select * from user";
		try {
			ps = conn.prepareStatement(sql);
			rs = ps.executeQuery();// 执行sql
			System.out.println("查询user表得:");
			System.out.println("编号	用户名	密码");
			// 遍厉打印元素
			User user = new User();
			while (rs.next()) {
				int id = rs.getInt("id");
				String username = rs.getString("username");
				String password = rs.getString("password");
				System.out.println(id + "	" + username + "	" + password);
				user = new User(id, username, password);
				list.add(user);// 将对象添加到集合中
			}
			for (User user1 : list) {
				System.out.println(user1);
			}
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			try {
				DBUtil.closeAll(conn, ps, rs);
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
	}

}

 

 

(2)运行结果:

 技术分享图片

4(我们将查询到的数据封装到JavaBean中):

(1)首先编写JavaBean,用来封装数据

package org.jdbc.bean;

public class User {
	private int id;
	private String username;
	private String password;

	public User(){
	}

	public User(String username, String password) {
		this.username = username;
		this.password = password;
	}


	public User(int id, String username, String password) {
		this.id = id;
		this.username = username;
		this.password = password;
	}

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getUsername() {
		return username;
	}

	public void setUsername(String username) {
		this.username = username;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	@Override
	public String toString() {
		return "User [id=" + id + ", username=" + username + ", password="
				+ password + "]";
	}
	

}


 

 

(2)我们将例3中查询方法稍作修改,将元素封装到List集合中:

List<User> list = new ArrayList<User>();
		String sql = "select * from user";
		try {
			ps = conn.prepareStatement(sql);
			rs = ps.executeQuery();// 执行sql
			System.out.println("查询user表得:");
			System.out.println("编号	用户名	密码");
			// 遍厉打印元素
			User user = new User();
			while (rs.next()) {
				int id = rs.getInt("id");
				String username = rs.getString("username");
				String password = rs.getString("password");
				System.out.println(id + "	" + username + "	" + password);
				user = new User(id, username, password);
				list.add(user);// 将对象添加到集合中
			}
			for (User user1 : list) {
				System.out.println(user1);
			}

(3)运行结果: 

 技术分享图片

5(将Java中的对象添加到数据库中去):

(1)编写代码(以上述代码为基础,添加一个添加对象的方法):

// 将JavaBean中的对象添加到数据库中
	public static void userInsert() {
		List<User> list = new ArrayList<User>();
		User user = new User();
		for (int j = 1; j <= 5; j++) {
			user = new User("武则天" + j, "75332" + j);
			list.add(user);
		}
		String sql = "insert into user(username,password) values(?,?)";
		int count = 0;
		try {
			ps = conn.prepareStatement(sql);
			for (User user2 : list) {
				ps.setString(1, user2.getUsername());
				ps.setString(2, user2.getPassword());
				count = ps.executeUpdate();
			}
			if (count > 0) {
				System.out.println("添加元素成功..");
			} else {
				System.out.println("添加元素失败..");
			}
		} catch (SQLException e) {
			e.printStackTrace();
		} // 查询完毕后,由查询方法释放资源
	}


 

(2)运行结果:

技术分享图片

三.事务

1. 概念:数据库事务(Database Transaction),是指作为单个逻辑工作单元执行的那一系列操作,要么全部成功,要么全部失败

2. 事务的四个特性:

(1)原子性:原子性是指事务是一个不可分割的单位,事务中的操作要么都发生,要么都失败

(2)一致性:事务必须使数据库从一个一致性的状态变换到另一个一致性的状态

(3)隔离性:事务的隔离级别是指一个事务的执行不被其他事务所干扰,即一个事务内部的操作及使用的数据对并发的 其他事务是隔离的,并发执行的各个事务之间不能互相干扰

(4)持久性:持久性是指一个事务一旦被提交,它对数据库中的数据改变就是永久性的,接下来的其他操作和数据库故障不应该对其有任何的影响

3. 事务的隔离级别

前提概念:

(1)脏读(dirty read):一个事务读取到了另一个事务未提交的数据(脏数据)的现象

(2)不可重复读:一个事务两次读取到的数据不一致的现象

(3)幻读:一个事务在读取数据时,另一个事务添加了数据记录,则第一个事务读取到了新添加的数据(与第一次读取到的数据比较)

级别分类:

(1)读未提交级别(read uncommitted):读取到了另一个事务还未提交的数据,可能发生脏读,不可重复读,幻读。

(2)读提交级别(read committed):只能读取其他事务已经提交的数据,可能会发生不可重复读,幻读

(3)可重复提交级别(repeatable read,MySQL默认隔离级别):在一个事务中可以重复读取相同的数据在InnoDB数据库存储引擎(此存储引擎支持事务)中,已经解决了幻读问题。

(4)串行化级别(serialzable): 最安全,但并发效率低。

4. 隔离级别多线程并发读取数据时的正确性

隔离级别 

脏读 

不可重复读 

幻读 

读未提交(Read uncommitted

V

V

V

读已提交(Read committed

x

V

V

可重复读(Repeatable read

x

x

V

可串行化(Serializable 

x

x

x

V:可能出现,X:不会出现

5. Java对事务的支持

(1)当一个连接对象被创建时,默认情况下是自动提交事务:每次执行一个 SQL 语句时,如 果执行成功,就会向数据库自动提交,而不能回滚

     为了让多个 SQL 语句作为一个事务执行:

(2)调用 Connection 对象的 setAutoCommit(false); 以取消自动提交事务

(3)在所有的 SQL 语句都成功执行后,调用 commit(); 方法提交事务

(4)在出现异常时,调用 rollback(); 方法回滚事务

(5)若此时 Connection 没有被关闭, 则需要恢复其自动提交状态

1(模拟银行账户对事物进行深入理解,具有转账,查询功能):

(1)编写代码:

package org.jdbc.transcation;
 
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Scanner;
 
import org.jdbc.util.DBUtil;
 
public class AccountDemo {
// 主方法控制运行方向
public static void main(String[] args) {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
Scanner scan = new Scanner(System.in);
while (true) {
System.out.print("请输入你的选择(1 转账	2 查询	3退出):");
int chioce;
try {
chioce = scan.nextInt();
switch (chioce) {
case 1:
System.out.print("请输入转出账户的姓名:");
String fromName = br.readLine();
System.out.print("请输入转入账户姓名:");
String toName = br.readLine();
System.out.print("请输入转账金额:");
int money = scan.nextInt();
boolean flag = transFerMoney(fromName, toName, money);
if (flag) {
System.out.println("转账成功");
} else {
System.out.println("sorry,ATM发生故障,转账失败!");
}
break;
case 2:
System.out.print("请选择 (1:查询全部账户	2:个人账户):");
int chioce1 = scan.nextInt();
switch (chioce1) {
case 1:
selectAll();
break;
case 2:
System.out.print("请输入查询账户姓名:");
String balName = br.readLine();
selectPart(balName);
break;
}
break;
case 3:
System.out.println("谢谢你的光临,再见!!");
System.exit(0);
}
} catch (IOException e) {
e.printStackTrace();
}
}
 
}
 
// 转钱方法
public static boolean transFerMoney(String fromName, String toName,
int money) {
boolean flag = false;
PreparedStatement ps = null;
Connection conn = null;
try {
conn = DBUtil.getConnection2();
conn.setAutoCommit(false);// 取消自动提交
String sql1 = "update account set balance=balance-? where name=?";
String sql2 = "update account set balance=balance+? where name=?";
ps = conn.prepareStatement(sql1);
ps.setInt(1, money);
ps.setString(2, fromName);// 转出
ps.executeUpdate();
ps.close();
 
ps = conn.prepareStatement(sql2);
ps.setInt(1, money);
ps.setString(2, toName);// 转入
ps.executeUpdate();
conn.commit();// 提交事务
flag = true;
} catch (SQLException e) {
e.printStackTrace();
} finally {
try {
DBUtil.closePart(conn, ps);
} catch (SQLException e) {
e.printStackTrace();
}
}
return flag;
 
}
 
// 全部账户查询方法
public static void selectAll() {
PreparedStatement ps = null;
Connection conn = null;
ResultSet rs = null;
try {
conn = DBUtil.getConnection2();// 建立连接
String sql = "select * from account";
ps = conn.prepareStatement(sql);
rs = ps.executeQuery();
System.out.println("全部账户查询结果为:");
System.out.println("编号	姓名	账户余额");
while (rs.next()) {
int id = rs.getInt("id");
String name = rs.getString("name");
int balance = rs.getInt("balance");
System.out.println(id + "	" + name + "	" + balance);
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
try {
DBUtil.closeAll(conn, ps, rs);
} catch (SQLException e) {
e.printStackTrace();
}
}
}
 
// 查询单人账户
public static void selectPart(String balName) {
PreparedStatement ps = null;
Connection conn = null;
ResultSet rs = null;
try {
conn = DBUtil.getConnection2();// 建立连接
String sql3 = "select * from account where name=?";
ps = conn.prepareStatement(sql3);
ps.setString(1, balName);
rs = ps.executeQuery();
System.out.println(balName + "账户查询结果为:");
System.out.println("编号	姓名	账户余额");
while (rs.next()) {
int id = rs.getInt("id");
String name = rs.getString("name");
int balance = rs.getInt("balance");
System.out.println(id + "	" + name + "	" + balance);
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
try {
DBUtil.closeAll(conn, ps, rs);
} catch (SQLException e) {
e.printStackTrace();
}
}
}
 
}


 


 

(2)运行结果:

请输入你的选择(1 转账 2 查询 3退出):2

请选择 (1:查询全部账户 2:个人账户):1

全部账户查询结果为:

编号 姓名 账户余额

1 项羽 35000000

2 刘邦 20000000

3 李世民 50000000

4 赵匡胤 24000000

请输入你的选择(1 转账 2 查询 3退出):1

请输入转出账户姓名:项羽

请输入转入账户姓名:刘邦

请输入转账金额:3000

转账成功

请输入你的选择(1 转账 2 查询 3退出):2

请选择 (1:查询全部账户 2:个人账户):2

请输入查询账户姓名:刘邦

刘邦账户查询结果为:

编号 姓名 账户余额

2 刘邦 20003000

请输入你的选择(1 转账 2 查询 3退出):1

请输入转出账户姓名:项羽

请输入转入账户姓名:李世民

请输入转账金额:3000

转账成功

请输入你的选择(1 转账 2 查询 3退出):2

请选择 (1:查询全部账户 2:个人账户):1

全部账户查询结果为:

编号 姓名 账户余额

1 项羽 34994000

2 刘邦 20003000

3 李世民 50003000

4 赵匡胤 24000000

请输入你的选择(1 转账 2 查询 3退出):3

谢谢你的光临,再见!!

 

四.常见的数据库连接池

1.连接池:存储,并高效管理数据库连接对象的容器连接池,一般用于短暂的频繁的去建立链接,去操作数据库,比较节省资源,我们根据数据库建立一次链接,底层来说还是比较耗费资源的

2.DBCP的使用:

1)导入DBCP的两个jar包,以及数据库驱动jar包;

2)编码:

方式一(硬编码):

package org.jdbc.dbcpdemo;

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

import org.apache.commons.dbcp.BasicDataSource;

public class DBCPDemo1 {

	public static void main(String[] args) throws SQLException {
		BasicDataSource ds = new BasicDataSource();
		// 1.设置参数
		ds.setDriverClassName("com.mysql.jdbc.Driver");
		ds.setUrl("jdbc:mysql://localhost:3306/boke18");
		ds.setUsername("root");
		ds.setPassword("qitao1996");
		// 2.获取连接对象
		Connection conn = ds.getConnection();
		String sql = "insert into user(username,password) values(?,?)";
		PreparedStatement ps = conn.prepareStatement(sql);
		ps.setString(1, "平昭阳公主");
		ps.setString(2, "987654");
		int count = 0;
		count = ps.executeUpdate();
		if (count != 0) {
			System.out.println("添加成功..");
		} else {
			System.out.println("添加失败..");
		}
		conn.close();
		ps.close();

	}

}


 

运行结果:

技术分享图片

方式二(配置文件的方式):

加入配置文件:dbcp.properties

代码:

package org.jdbc.dbcpdemo;

import java.io.FileInputStream;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.util.Properties;
import javax.sql.DataSource;
import org.apache.commons.dbcp.BasicDataSourceFactory;

public class DBCPDemo2 {

	public static void main(String[] args) throws Exception {
		//用属性集合读取属性文件
		Properties pro=new Properties();
		pro.load(new FileInputStream("src/dbcp.properties"));
		//传入属性集合
		@SuppressWarnings("static-access")
		DataSource ds=new BasicDataSourceFactory().createDataSource(pro);
		Connection conn=ds.getConnection();
		String sql = "insert into user(username,password) values(?,?)";
		PreparedStatement ps = conn.prepareStatement(sql);
		ps.setString(1, "窦漪房");
		ps.setString(2, "789654");
		int count = 0;
		count = ps.executeUpdate();
		if (count != 0) {
			System.out.println("添加成功..");
		} else {
			System.out.println("添加失败..");
		}
		conn.close();
		ps.close();
	}

}

 

 

运行结果:

技术分享图片

3.c3p0的使用:

1)导入jar

编码方式一(硬编码):

核心代码:

  

 ComboPooledDataSource ds = new ComboPooledDataSource();
        //设置参数
        ds.setDriverClass("com.mysql.jdbc.Driver");
        ds.setJdbcUrl("jdbc:mysql://127.0.0.1:3306/mydb");
        ds.setUser("root");
        ds.setPassword("123456");
        //获取链接对象
        Connection conn = ds.getConnection();
        String sql = "insert into users values(?,?)";
        PreparedStatement statement = conn.prepareStatement(sql);
        statement.setString(1, "找六2");
        statement.setString(2, "654321");
        statement.executeUpdate();
        conn.close();
        ds.close();

 

编码方式二(读取配置文件):

package org.jdbc.c3p0demo;

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

import com.mchange.v2.c3p0.ComboPooledDataSource;

public class C3P0Demo {

	public static void main(String[] args) throws SQLException {
		ComboPooledDataSource ds=new ComboPooledDataSource("myoracle");
		Connection conn=ds.getConnection();
		String sql = "insert into user(username,password) values(?,?)";
		PreparedStatement ps=conn.prepareStatement(sql);
		ps.setString(1, "梁红玉");
		ps.setString(2, "678954");
		int count=0;
		count= ps.executeUpdate();
		if(count!=0){
			System.out.println("添加成功..");
		}else{
			System.out.println("添加失败..");
		}
		ps.close();
		conn.close();
	}
}


 

运行结果:

技术分享图片

4. DButils的使用:

(1)代码:

 

package org.jdbc.dbutils;

import java.sql.SQLException;
import java.util.List;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.jdbc.bean.User;
import com.mchange.v2.c3p0.ComboPooledDataSource;

public class DButilsDemo {

	public static void main(String[] args) throws SQLException {
		// dbutils 封装了操作对象 配合C3P0一起使用
		ComboPooledDataSource ds = new ComboPooledDataSource();
		QueryRunner runner = new QueryRunner(ds);
		// runner.update() 执行增删改
		// runner.query() 执行查询语句
		String sql = "insert into user(name,password) values('小周后','abcdefef')";
		sql= "insert into user(name,password) values(?,?)";
		sql = "select * from user";
		// runner.update(sql); 执行增删改
		// runner.update(sql,100,"ggggg");
		// 执行查询语句,查询出来的数据,封装好返回
		List<User> querys = runner.query(sql, new BeanListHandler<User>(
				User.class));
		System.out.println(querys);
		ds.close();
	}

}


 

 

(2)运行结果:

技术分享图片

                        【本次总结完毕】

 


以上是关于Java学习总结(十九)——JDBC操作数据库,预编译的使用,事务,常见的连接池的主要内容,如果未能解决你的问题,请参考以下文章

第九周java学习总结

20145207《Java程序设计》第9周学习总结

20145207《Java程序设计》第9周学习总结

20165210 Java第七周学习总结

第十四周课程总结

20155208徐子涵 2016-2017-2 《Java程序设计》第9周学习总结