Java 数据库开发与实战应用(二) -- JDBC入门

第1章 JDBC的API

JDBC入门

1、搭建开发环境
2、编写程序,在程序中加载数据库驱动
3、建立连接
4、创建用于向数据库发送SQL的Statement对象
5、从代表结果集的ResultSet中取出数据
6、断开与数据库的连接,并释放相关资源

数据库:mysql

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','王五');

jar包:mysql-connector-java-8.0.16.jar
源码:

package com.imooc.jdbc.demo1;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.DriverPropertyInfo;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.sql.Statement;
import java.util.Properties;
import java.util.logging.Logger;

import org.junit.Test;

import com.mysql.cj.jdbc.Driver;

public class JDBCDemo1 {

	@Test
	/**
	 * JDBC资源的释放
	 */
	public void demo2() {
		Connection conn = null;
		Statement stmt = null;
		ResultSet resultset = null;

		try {
			// 1、加载驱动
//			DriverManager.registerDriver(new Driver());//会导致驱动注册两次
			Class.forName("com.mysql.cj.jdbc.Driver");
			// 2、获得连接
			conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/jdbctest ?serverTimezone=UTC", "root",
					"zsn1003");
			// 3、创建执行SQL语句的对象,并且执行SQL
			// 3.1创建执行sql的对象
			String sql = "select * from user";
			stmt = conn.createStatement();
			// 3.2执行sql
			resultset = stmt.executeQuery(sql);
			while (resultset.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);
			}

		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			// 4、释放资源
			if (resultset != null) {
				try {
					resultset.close();
				} catch (SQLException sqlEx) {

				}
				resultset = null;
			}

			if (stmt != null) {
				try {
					stmt.close();
				} catch (SQLException sqlEx) {

				}
				stmt = null;
			}

			if (conn != null) {
				try {
					conn.close();
				} catch (SQLException sqlEx) {

				}
				conn = null;//垃圾回收机制要更早回收对象
			}

		}

	}
}




DriverManager

DriverManager:驱动管理类
 ◆ 主要作用
  ◆ 一、注册驱动
   ◆ 实际开发中注册驱动会使用如下的方式:
   class.forName("com.mysql.jdbc.Driver");
   ◆ 因为之前的方式会导致驱动注册两次

  ◆ 二、获得连接
   ◆ Connection getConnection(String url,String username,String password);
    ◆ url写法:jdbc:mysql://localhost:3306/jdbc
     ◆ jdbc:协议
     ◆ mysql:子协议
     ◆ localhost:主机名
     ◆ 3306:端口
    ◆ url简写:jdbc:mysql:///jdbc




Connection
Connection :连接对象
 ◆ 主要作用
  ◆ 一、创建执行SQL语句的对象
   ◆ Statement createStatement():执行SQL语句,有SQL注入的漏洞存在
   ◆ PreparedStatement PrepareStatement(String sql):预编译SQL语句,解决了SQL注入的漏洞
   ◆ CallableStatement PrepareCall(String sql):执行SQL中存储过程

  ◆ 二、进行事务管理
   ◆ setAutoCommit(boolean autoCommit):设置事务是否自动提交
   ◆ commit():事务提交
   ◆ rollback():事务回滚




Statement
Statement :执行SQL
 ◆ 主要作用
  ◆ 一、执行SQL语句
   ◆ boolean execute(String sql):执行SQL
   ◆ ResultSet execute(String sql):执行SQL中的select
   ◆ int executeUpdate(String sql):执行SQL中的insert/update/delete

  ◆ 二、执行批处理操作
   ◆ addBatch(String sql):添加到批处理
   ◆ executeBatch():执行批处理
   ◆ clearBatch():清空批处理




***ResultSet ***
ResultSet :结果集
 ◆ 结果集:其实就是查询语句(select)查询的结果的封装
 ◆ 主要作用
  ◆ 结果集获取查询到的结果的
   ◆ next()
   ◆ 针对不同的类型的数据可以使用getXXX()获取数据,通用获取数据的方法:getObject()




JDBC的资源释放
◆ Jdbc程序运行完后,切记要释放程序在运行过程中,创建的那些与数据库进行交互的对象,这些对象通常是ResiltSet,Statement和Connection对象。

◆ 特别是Connection对象,它非常稀有的资源,用完后必须马上释放,如果Connection不能及时、正确的关闭,极易导致系统宕机。Connection的使用原则是尽量晚的创建,尽量早的释放




第2章 JDBC的CRUD操作

保存代码的实现
1、向数据库中保存记录
2、修改数据库中的记录
3、删除数据库中的记录
4、查询数据库中的记录

package com.imooc.jdbc.demo1;

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

import org.junit.Test;

public class JDBCDemo2 {
	@Test
	/**
	 * 保存、修改和删除操作
	 */
	public void demo1() {
		Connection conn = null;
		Statement stmt = null;
		try {
			// 注册驱动
			Class.forName("com.mysql.cj.jdbc.Driver");
			// 获得连接
			conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/jdbctest ?serverTimezone=UTC", "root",
					"zsn1003");
			// 获得执行SQL语句的对象
			stmt = conn.createStatement();
			// 编写SQL
			//String sql = "insert into user values(null,'eee','123','张三')";//保存
			//String sql = "update user set username='qqq',password='456',name='赵六'  where uid=4";//修改
				String sql = "delete from user where uid=4";//删除
			// 执行SQL
			int i = stmt.executeUpdate(sql);
			if (i > 0) {
				System.out.println("success!");
			}
		} 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;
			}

		}
	}
}



第3章 JDBC工具类的抽取

JDBC的工具类的抽取
为了简化JDBC的开发,可以将一些重复的代码进行提取。

package com.imooc.jdbc.utils;

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

/**
 * JDBC的工具类
 * 
 * @author Administrator
 *
 */
public class JDBCUtils {
	private static final String driverClass;
	private static final String url;
	private static final String username;
	private static final String password;

	static {
		driverClass = "com.mysql.cj.jdbc.Driver";
		url = "jdbc:mysql://localhost:3306/jdbctest ?serverTimezone=UTC";
		username = "root";
		password = "zsn1003";
	}

	/**
	 * 注册驱动
	 * 
	 * @throws ClassNotFoundException
	 */
	public static void loadDriver() throws ClassNotFoundException {
		Class.forName(driverClass);
	}

	/**
	 * 获得连接的方法
	 * 
	 * @throws Exception
	 */
	public static Connection getConnection() throws Exception {

		loadDriver();

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

		return conn;
	}

	/**
	 * 资源释放
	 */
	public static void release(Statement stmt, Connection conn) {
		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 static void release(ResultSet rs, Statement stmt, Connection conn) {
		if (rs != null) {
			try {
				rs.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
			rs = 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.properties

driverClass = com.mysql.cj.jdbc.Driver
url = jdbc:mysql://localhost:3306/jdbctest?serverTimezone=UTC
username = root
password = zsn1003

	static {
//		driverClass = "com.mysql.cj.jdbc.Driver";
//		url = "jdbc:mysql://localhost:3306/jdbctest ?serverTimezone=UTC";
//		username = "root";
//		password = "zsn1003";

		// 加载属性文件并解析
		Properties props = new Properties();
		// 如何获得属性文件的输入流?
		// 通常情况下使用类的加载器的方式进行获取
		InputStream is = JDBCUtils.class.getClassLoader().getResourceAsStream("jdbc.properties");
		try {
			props.load(is);
		} catch (IOException e) {
			e.printStackTrace();
		}

		driverClass = props.getProperty("driverClass");
		url = props.getProperty("url");
		username = props.getProperty("username");
		password = props.getProperty("password");

	}



第4章 SQL注入漏洞

JDBC的SQL注入漏洞的演示


package com.imooc.jdbc.demo2;

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

import org.junit.Test;

import com.imooc.jdbc.utils.JDBCUtils;

public class JDBCDemo4 {
	@Test
	/**
	 * 测试SQL注入漏洞的方法
	 */
	public void demo1() {
		//boolean flag = JDBCDemo4.login("aaa'or'1=1", "qqqqqqqwewqe");
		//boolean flag = JDBCDemo4.login("aaa' -- ", "qqqqqqqwewqe");

		if (flag == true) {
			System.out.println("ok");
		} else {
			System.out.println("no");
		}

	}
	
	/**
	 * 演示JDBC的注入的漏洞
	 * 
	 * @author Administrator
	 *
	 */
	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();
			String sql = "select * from user where username='" + username + "' and password='" + password + "'";
			rs = stmt.executeQuery(sql);
			if (rs.next()) {
				flag = true;
			} else {
				flag = false;
			}

		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			JDBCUtils.release(rs, stmt, conn);
		}
		return flag;
	}
}

JDBC的SQL注入漏洞的解决

	/**
	 * 避免JDBC的注入的漏洞
	 */
	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;
	}





第5章 PreparedStatement的使用

PreparedStatement的使用:保存操作

package com.imooc.jdbc.demo2;

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

import org.junit.Test;

import com.imooc.jdbc.utils.JDBCUtils;

/**
 * PreparedStatement的使用
 * 
 * @author Administrator
 *
 */
public class JDBCDemo5 {
	@Test
	/**
	 * 保存数据
	 */
	public void demo1() {
		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 i = pstmt.executeUpdate();

			if (i > 0) {
				System.out.println("yes");
			} else {
				System.out.println("no");
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			JDBCUtils.release(pstmt, conn);
		}
	}

}

PreparedStatement的使用:修改操作

	@Test
	/**
	 * 修改数据
	 */
	public void demo2() {
		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, "qqq");
			pstmt.setString(2, "123");
			pstmt.setString(3, "张六");
			pstmt.setInt(4, 6);
			// 执行SQL
			int i = pstmt.executeUpdate();

			if (i > 0) {
				System.out.println("yes");
			} else {
				System.out.println("no");
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			JDBCUtils.release(pstmt, conn);
		}
	}

PreparedStatement的使用:删除操作

	@Test
	/**
	 * 删除数据
	 */
	public void demo3() {
		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, 6);
			// 执行SQL
			int i = pstmt.executeUpdate();

			if (i > 0) {
				System.out.println("yes");
			} else {
				System.out.println("no");
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			JDBCUtils.release(pstmt, conn);
		}
	}

PreparedStatement的使用:查询操作




第6章 连接池C3P0

连接池的概述
连接池是创建和管理一个连接的缓冲池的技术,这些连接准备好被任何需要它们的线程使用。

在这里插入图片描述

在这里插入图片描述

C3P0连接池的使用
C3P0连接池的使用
jar包:c3p0-0.9.1.2.jar

手动设置连接池

@Test
	/**
	 * 手动设置连接池
	 */
	public void demo1() {
		// 创建连接池
		ComboPooledDataSource dataSource = new ComboPooledDataSource();
		// 获得连接
		Connection conn = null;
		PreparedStatement pstmt = null;
		ResultSet rs = null;

		try {
			// 设置连接池的参数
			dataSource.setDriverClass("com.mysql.cj.jdbc.Driver");
			dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/jdbctest?serverTimezone=UTC");
			dataSource.setUser("root");
			dataSource.setPassword("zsn1003");
			dataSource.setMaxPoolSize(20);
			dataSource.setInitialPoolSize(3);
			// 获得连接
			conn = dataSource.getConnection();
			// 编写SQL
			String sql = "select * from user";
			// 预编译SQL
			pstmt = conn.prepareStatement(sql);
			// 执行SQL
			rs = pstmt.executeQuery();

			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 + "  " + username + "  " + password + "  " + name);
			}

		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			JDBCUtils.release(rs, pstmt, conn);
		}

	}


使用配置文件
配置文件:c3p0-config.xml

<?xml version="1.0" encoding="UTF-8"?>
<c3p0-config>

  <default-config>
    <property name="driverClass">com.mysql.cj.jdbc.Driver</property>
	<property name="jdbcUrl">jdbc:mysql://localhost:3306/jdbctest?serverTimezone=UTC</property>
	<property name="user">root</property>
	<property name="password">zsn1003</property>
	<property name="initialPoolSize">5</property>
	<property name="maxPoolSize">20</property>
  </default-config>
  
</c3p0-config>

@Test
	/**
	 * 使用配置文件的方式
	 */
	public void demo2() {
		// 创建连接池
		//ComboPooledDataSource dataSource = new ComboPooledDataSource();
		// 获得连接
		Connection conn = null;
		PreparedStatement pstmt = null;
		ResultSet rs = null;

		try {
			// 获得连接
			//conn = dataSource.getConnection();
			conn = JDBCUtils2 .getConnection();
			// 编写SQL
			String sql = "select * from user";
			// 预编译SQL
			pstmt = conn.prepareStatement(sql);
			// 执行SQL
			rs = pstmt.executeQuery();

			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 + "  " + username + "  " + password + "  " + name);
			}

		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			JDBCUtils.release(rs, pstmt, conn);
		}

	}

工具类修改

package com.imooc.jdbc.utils;

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;

import com.mchange.v2.c3p0.ComboPooledDataSource;

/**
 * JDBC的工具类
 * 
 * @author Administrator
 *
 */
public class JDBCUtils2 {
	private static final ComboPooledDataSource dataSource = new ComboPooledDataSource();

	/**
	 * 获得连接的方法
	 * 
	 * @throws Exception
	 */
	public static Connection getConnection() throws Exception {

		Connection conn = dataSource.getConnection();

		return conn;
	}

	/**
	 * 资源释放
	 */
	public static void release(Statement stmt, Connection conn) {
		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 static void release(ResultSet rs, Statement stmt, Connection conn) {
		if (rs != null) {
			try {
				rs.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
			rs = 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;
		}
	}
}






◆◆◆◆ 下载地址:MySQL 32位.(64位同样适用)◆◆◆◆




笔记跟源码来源:慕课网,Java实战课程 链接: 慕课网.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值