JDBC全称为:Java DataBase Connectivity(Java数据库连接)
#创建数据库
create database jdbctest;
use jdbctest;
create table user(
uid int primary key auto_increment,
username varchar(20),
password varchar(20),
name varchar(20)
);
insert into user values (null,'aaa','111','张三');
insert into user values (null,'bbb','222','李四');
insert into user values (null,'ccc','333','王五');
//DriverManager.registerDriver(new Driver());
Class.forName("com.mysql.jdbc.Driver");
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/jdbctest","root","123456");
String sql = "select * from user";
Statement stmt = conn.createStatement();
ResultSet result = stmt.executeQuery(sql);
while(result.next()){
int uid = resultSet.getInt("uid");
String username = resultSet.getString("username");
String password = resultSet.getString("password");
String name = resultSet.getString("name");
System.out.println(uid+" "+username+" "+password+" "+name);
}
result.close();
stmt.close();
conn.close();
主要作用
注册驱动
实际开发中注册驱动会使用如下的方式:
Class.forName("com.mysql.jdbc.Driver");
因为之前的方式会导致驱动注册两次
获得连接
Connection getConnection(String url,String username,String password);
jdbc:mysql:///jdbc
Statement createStatement()
执行SQL语句,有SQL注入的漏洞存在PreparedStatement prepareStatement(String sql)
预编译SQL语句,解决SQL注入的漏洞CallableStatement prepareCall(String sql)
执行SQL中存储过程setAutoCommit(boolean autoCommit)
设置事务是否自动提交commit()
事务提交rollback()
事务回滚Boolean execute(String sql)
执行SQL,执行select语句返回true,否则返回falseResultSet executeQuery(String sql)
执行SQL中的select语句int executeUpdate(String sql)
执行SQL中的insert/update/delete语句addBatch(String sql)
添加批处理executeBatch()
执行批处理clearBatch()
清理批处理next()
判断是否有下一行记录,如果有则将光标移到下一行getObject()
JDBC程序运行完后,切记要释放程序在运行过程中,创建的那些与数据库进行交互的对象,这些对象通常是ResultSet,Statement和Connection对象
特别是Connectiion对象,它是非常稀有的资源,用完后必须马上释放,如果Connection不能及时、正确的关闭,极易导致系统宕机。Connection的使用原则是尽量晚创建,尽量早的释放。
在finally中释放资源
if(rs!=null){
try{
rs.close();
}catch(SQLException e){
e.printStackTrace();
}
rs = null;//close后,资源还没有被回收。如果手动将其置为null则垃圾回收机制更早回收对象。
}
if(stmt!=null){
try{
stmt.close();
}catch(SQLException e){
e.printStackTrace();
}
stmt = null;
}
if(conn!=null){
try{
conn.close();
}catch(SQLException e){
e.printStackTrace();
}
conn = null;
}
public void demo1 () {
Connection conn = null;
Statement stmt = null;
try {
//注册驱动
Class.forName("com.mysql.jdbc.Driver");
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/jdbctest","root","123456");
stmt = conn.createStatement();
String sql = "insert into user values(null,'eee','123','孙柳')";
int i = stmt.executeUpdate(sql);
if(i>0) {
System.out.println("保存成功!");
}
}catch(Exception e) {
e.printStackTrace();
}finally {
//释放资源
if(stmt!=null){
try{
stmt.close();
}catch(SQLException e){
e.printStackTrace();
}
stmt = null;
}
if(conn!=null){
try{
conn.close();
}catch(SQLException e){
e.printStackTrace();
}
conn = null;
}
}
}
public void demo2() {
Connection conn = null;
Statement stmt = null;
try {
//注册驱动
Class.forName("com.mysql.jdbc.Driver");
//获得连接
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/jdbctest","root","123456");
//创建执行SQL语句的对象
stmt = conn.createStatement();
//编写SQL语句
String sql = "update user set username = 'qqq',password='456',name='赵六' where uid = 4";
//执行SQL语句
int i = stmt.executeUpdate(sql);
if(i>0) {
System.out.println("修改成功!");
}
}catch(Exception e) {
e.printStackTrace();
}finally {
//释放资源
if(stmt!=null){
try{
stmt.close();
}catch(SQLException e){
e.printStackTrace();
}
stmt = null;
}
if(conn!=null){
try{
conn.close();
}catch(SQLException e){
e.printStackTrace();
}
conn = null;
}
}
}
public void demo3() {
Connection conn = null;
Statement stmt = null;
try {
//注册驱动
Class.forName("com.mysql.jdbc.Driver");
//获得连接
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/jdbctest","root","123456");
//创建执行SQL语句的对象
stmt = conn.createStatement();
//编写SQL语句
String sql = "DELETE FROM user WHERE uid = 5";
//执行SQL语句
int i = stmt.executeUpdate(sql);
if(i>0) {
System.out.println("删除成功!");
}
}catch(Exception e) {
e.printStackTrace();
}finally {
//释放资源
if(stmt!=null){
try{
stmt.close();
}catch(SQLException e){
e.printStackTrace();
}
stmt = null;
}
if(conn!=null){
try{
conn.close();
}catch(SQLException e){
e.printStackTrace();
}
conn = null;
}
}
}
//查询多条记录
public void demo4() {
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
try {
Class.forName("com.mysql.jdbc.Driver");
conn = DriverManager.getConnection("jdbc:mysql:///jdbctest","root","123456");
stmt = conn.createStatement();
String sql = "SELECT * FROM user";
rs = stmt.executeQuery(sql);
while(rs.next()) {
int uid = rs.getInt("uid");
String username = rs.getString("username");
String password = rs.getString("password");
String name = rs.getString("name");
System.out.println("uid:"+uid+" username:"+username+" password:"+password+" name:"+name);
}
}catch(Exception e) {
e.printStackTrace();
}finally {
if(rs!=null){
try{
rs.close();
}catch(SQLException e){
e.printStackTrace();
}
rs = null;//close后,资源还没有被回收。如果手动将其置为null则垃圾回收机制更早回收对象。
}
if(stmt!=null){
try{
stmt.close();
}catch(SQLException e){
e.printStackTrace();
}
stmt = null;
}
if(conn!=null){
try{
conn.close();
}catch(SQLException e){
e.printStackTrace();
}
conn = null;
}
}
}
//查询一条记录
public void demo5() {
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
try {
Class.forName("com.mysql.jdbc.Driver");
conn = DriverManager.getConnection("jdbc:mysql:///jdbctest","root","123456");
stmt = conn.createStatement();
String sql = "SELECT * FROM user where uid = 2";
rs = stmt.executeQuery(sql);
if(rs.next()) {
int uid = rs.getInt("uid");
String username = rs.getString("username");
String password = rs.getString("password");
String name = rs.getString("name");
System.out.println("uid:"+uid+" username:"+username+" password:"+password+" name:"+name);
}
}catch(Exception e) {
e.printStackTrace();
}finally {
if(rs!=null){
try{
rs.close();
}catch(SQLException e){
e.printStackTrace();
}
rs = null;//close后,资源还没有被回收。如果手动将其置为null则垃圾回收机制更早回收对象。
}
if(stmt!=null){
try{
stmt.close();
}catch(SQLException e){
e.printStackTrace();
}
stmt = null;
}
if(conn!=null){
try{
conn.close();
}catch(SQLException e){
e.printStackTrace();
}
conn = null;
}
}
}
为了简化JDBC的开发,可以将一些重复的代码进行提取
定义JDBCUtils.java工具类
import java.io.IOException;
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 JDBCUtils {
private static final String driverClass;
private static final String url;
private static final String username;
private static final String password;
static {
//加载属性文件并解析
Properties props = new Properties();
//获得属性文件的输入流
//通常采用类加载器方式的进行获取
InputStream is = JDBCUtils.class.getClassLoader().getResourceAsStream("jdbc.properties");
try {
props.load(is);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
driverClass=props.getProperty("driverClass");
url=props.getProperty("url");
username=props.getProperty("username");
password=props.getProperty("password");
}
/**
* 注册驱动
*/
public static void loadDriver() throws ClassNotFoundException{
Class.forName(driverClass);
}
/**
* 获得连接的方法
* @return
* @throws SQLException
* @throws ClassNotFoundException
*/
public static Connection getConnection() throws SQLException, ClassNotFoundException {
loadDriver();
Connection conn = DriverManager.getConnection(url,username,password);
return conn;
}
/**
* 资源释放
* @param stmt
* @param conn
* @throws SQLException
*/
public static void release(Statement stmt, Connection conn) throws SQLException {
if(stmt != null) {
try {
stmt.close();
}catch(SQLException e) {
e.printStackTrace();
}
stmt = null;
}
if(conn != null) {
try {
conn.close();
}catch(SQLException e) {
e.printStackTrace();
}
conn = null;
}
}
/**
* 资源释放
* @param rs
* @param stmt
* @param conn
*/
public static void release(ResultSet rs,Statement stmt,Connection conn) {
if(rs != null) {
try {
rs.close();
}catch(SQLException e) {
e.printStackTrace();
}
rs = null;
}
}
}
定义Properties文件
driverClass=com.mysql.jdbc.Driver
url=jdbc:mysql:///jdbctest
username=root
password=123456
定义测试文件
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import org.junit.Test;
public class JDBCDemo3 {
@Test
//保存记录
public void demo1() throws SQLException {
Connection conn = null;
Statement stmt = null;
try {
//获得连接
conn = JDBCUtils.getConnection();
//创建执行
stmt = conn.createStatement();
//编写sql语句
String sql = "insert into user values (null,'ppp','123','小六')";
int num = stmt.executeUpdate(sql);
if(num > 0) {
System.out.println("保存成功!");
}
}catch(Exception e) {
e.printStackTrace();
}finally {
JDBCUtils.release(stmt, conn);
}
}
}
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import org.junit.Test;
public class JDBCDemo4 {
public static boolean login(String username, String password) {
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
boolean flag=false;
//获得连接
try {
conn = JDBCUtils.getConnection();
//创建执行
stmt = conn.createStatement();
//编写sql语句
String sql ="select * from user where username='"+username+"' and password = '"+password+"'";
//执行sql语句
rs = stmt.executeQuery(sql);
//判断结果集中是否有数据
if(rs.next()) {
flag = true;
}else {
flag = false;
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}finally {
JDBCUtils.release(rs,stmt, conn);
}
return flag;
}
@Test
public void demo1() {
if(JDBCDemo4.login("aaa ' or '1=1", "suibianxie")) {//SQL注入方式
System.out.println("登录成功");
}else {
System.out.println("登录失败");
}
}
}
SQL注入漏洞的解决
使用预处理对象preparedStatement
preparedStatement是Statement的子接口,它的实例对象可以通过调用Connection.preparedStatement(sql)
方法获得,相对于Statement对象而言
避免SQL注入漏洞的方法
public static boolean login2(String username,String password) {
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
boolean flag = false;
try {
//获得连接
conn = JDBCUtils.getConnection();
//编写SQL
String sql = "select * from user where username = ? and password = ?";
//预处理SQL
pstmt = conn.prepareStatement(sql);
//设置参数
pstmt.setString(1, username);
pstmt.setString(2, password);
//执行SQL
rs = pstmt.executeQuery();
//判断结果集
if(rs.next()) {
flag = true;
}else {
flag = false;
}
}catch(Exception e) {
e.printStackTrace();
}finally {
JDBCUtils.release(rs, pstmt, conn);
}
return flag;
}
PreparedStatement的使用
保存数据
public void demo1() throws SQLException {
Connection conn = null;
PreparedStatement pstmt = null;
try {
//获得连接
conn = JDBCUtils.getConnection();
//编写SQL
String sql = "insert into user values (null,?,?,?)";
//预处理SQL
pstmt = conn.prepareStatement(sql);
//设置具体的参数值
pstmt.setString(1, "qqq");
pstmt.setString(2, "123");
pstmt.setString(3, "张武");
//执行sql语句
int num = pstmt.executeUpdate();
if(num>0) {
System.out.println("保存成功!");
}
}catch(Exception e) {
e.printStackTrace();
}finally {
JDBCUtils.release(pstmt, conn);
}
}
修改数据
public void demo2() throws SQLException {
Connection conn = null;
PreparedStatement pstmt = null;
try {
//获得连接
conn = JDBCUtils.getConnection();
//编写SQL
String sql = "update user set username = ?, password = ?, name = ? where uid =?";
//预处理SQL
pstmt = conn.prepareStatement(sql);
//设置参数
pstmt.setString(1, "www");
pstmt.setString(2, "123456");
pstmt.setString(3, "张柳");
pstmt.setInt(4, 9);
//执行SQL
int num = pstmt.executeUpdate();
if(num>0) {
System.out.println("修改成功");
}
}catch(Exception e) {
e.printStackTrace();
}finally {
JDBCUtils.release(pstmt, conn);
}
}
删除数据
public void demo3() throws SQLException {
Connection conn = null;
PreparedStatement pstmt = null;
try {
//获得连接
conn = JDBCUtils.getConnection();
//编写SQL
String sql = "delete from user where uid = ?";
//预处理SQL
pstmt = conn.prepareStatement(sql);
//设置参数
pstmt.setInt(1, 9);
//执行SQL
int num = pstmt.executeUpdate();
if(num>0) {
System.out.println("删除成功");
}
}catch(Exception e) {
e.printStackTrace();
}finally {
JDBCUtils.release(pstmt, conn);
}
}
查询所有数据
public void demo4() throws SQLException {
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
try {
//获得连接
conn = JDBCUtils.getConnection();
//编写SQL
String sql = "select * from user";
//预处理SQL
pstmt = conn.prepareStatement(sql);
//执行SQL
rs = pstmt.executeQuery();
while(rs.next()) {
System.out.println(rs.getInt("uid")+" "+rs.getString("username")+" "+rs.getString("password")+" "+rs.getString("name"));
}
}catch(Exception e) {
e.printStackTrace();
}finally {
JDBCUtils.release(rs,pstmt, conn);
}
}
连接池
C3P0连接池的使用
手动设置连接池操作
package com.imooc.jdbc;
import java.beans.PropertyVetoException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import org.junit.Test;
import com.mchange.v2.c3p0.ComboPooledDataSource;
/**
* 连接池的测试类
* @author wangzhe
*
*/
public class DataSourceDemo1 {
@Test
/**
* 手动设置连接池
*/
public void demo1() throws PropertyVetoException {
//创建连接池
ComboPooledDataSource dataSource = new ComboPooledDataSource();
//设置连接池参数
dataSource.setDriverClass("com.mysql.jdbc.Driver");
dataSource.setJdbcUrl("jdbc:mysql:///jdbctest");
dataSource.setUser("root");
dataSource.setPassword("123456");
dataSource.setMaxPoolSize(20);//设置最大连接池个数
dataSource.setInitialPoolSize(3);//设置初始化连接池个数
//获得连接
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
try {
//获得连接
conn = dataSource.getConnection();//从连接池中获得
//编写SQL
String sql = "select * from user";
//预编译SQL
pstmt = conn.prepareStatement(sql);
//设置参数:无参数
//执行SQL
rs = pstmt.executeQuery();
while(rs.next()) {
System.out.println(rs.getInt("uid")+" "+rs.getString("username")+" "+rs.getString("password")+" "+rs.getString("name"));
}
}catch(Exception e) {
e.printStackTrace();
}finally {
JDBCUtils.release(rs, pstmt, conn);
}
}
}
使用配置文件的方式
//c3p0的配置文件:c3p0-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<c3p0-config>
<default-config>
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql:///jdbctest
<property name="user">root</property>
<property name="password">123456</property>
<property name="initialPoolSize">5</property>
<property name="maxPoolSize">20</property>
</default-config>
</c3p0-config>
//使用配置文件的方式
@Test
public void demo2() throws PropertyVetoException {
//创建连接池
ComboPooledDataSource dataSource = new ComboPooledDataSource();//自动找classpath下的配置文件
//获得连接
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
try {
//获得连接
conn = dataSource.getConnection();//从连接池中获得
//编写SQL
String sql = "select * from user";
//预编译SQL
pstmt = conn.prepareStatement(sql);
//设置参数:无参数
//执行SQL
rs = pstmt.executeQuery();
while(rs.next()) {
System.out.println(rs.getInt("uid")+" "+rs.getString("username")+" "+rs.getString("password")+" "+rs.getString("name"));
}
}catch(Exception e) {
e.printStackTrace();
}finally {
JDBCUtils.release(rs, pstmt, conn);
}
}