2020、02、07下午面试的HW,说我毕业后有半年的空档(我一开始就跟hr说了),不要我了。
唉
为何呢?
我觉得面试官的题目我都回答的差不多,两道编程题也完成了。
也许人家就是想逗逗我吧。
呵呵呵
进入正题吧
所有的jar包自己找吧
缺啥补啥,真有需要的新手。加我公众号,后台私信我,我给你发。或者过两天公众号就有了呢。谁知道呢?就像这疫情。谁知道呢?
首先是基础概念部分
JDBC入门篇
1、搭建开发环境
2、编写程序,在程序中加载数据驱动
3、建立连接
4、创建用于向数据库发送sql的Statement对象
5、从代表结果集的ResultSet中取出数据
6、断开与数据库的连接,并释放相关资源
代码演示
所用的表
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','张1'),(null,'bbb','222','张2'),(null,'ccc','333','张3');
public class jdbcDemo1 {
@Test
/**
* jdbc入门程序
*/
public void demo1(){
try {
//1、加载驱动
//DriverManager.registerDriver(new Driver());
Class.forName("com.mysql.jdbc.Driver");
//2、获得连接
Connection conn=DriverManager.getConnection("jdbc:mysql://localhost:3306/jdbctest", "root", "root");
//3、创建执行sql语句的对象,并执行sql
String sql="select * from user";
Statement stmt=conn.createStatement();
//执行sql
ResultSet 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+" "+username+" "+password+" "+name);
}
//4、释放资源
rs.close();
stmt.close();
conn.close();
} catch (Exception e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
}
}
JDBC的API
DriverManager:驱动管理类
*主要作用:
*一、注册驱动:
实际开发中会用 Class.forName(“com.mysql.jdbc.Driver”)来注册驱动;
因为之前的驱动会使得驱动注册两次
DriverManager.registerDriver(new Driver());
*二、获得连接:
Connection getConnection(String url,String username,String password )
url写法:jdbc:mysql://localhost:3306/数据库名
jdbc :协议
mysql:子协议
localhost:主机名
3306:端口号
连接自己的本机的数据库url的写法jdbc:mysql:///数据库名
Connection:连接对象
主要作用:
一、创建执行sql语句的对象
Statement createStatement();执行sql语句,有sql注入的漏洞存在
PreparedStatement prepareStatement(String sql);预编译sql语句,解决了sql注入的漏洞
CallableStatement prepareCall(String sql);执行sql中的存储过程
二、进行事务的管理
setAutoCommit(boolean autoCommit);设置事务是否自动提交
commit():事务提交
rollback():事务回滚
Statement :执行SQL
主要作用:
一、执行sql语句
boolean execute(String sql):执行sql,执行select返回true,否则返回false
ResultSet executeQuery(String sql):执行sql中的select语句
int executeUpdate(String sql):执行sql中的insert、update、delete语句
二、执行批处理操作
addBatch(String sql):添加批处理
executeBatch():执行批处理
clearBatch():清空批处理
ResultSet :结果集
就是select语句查询结果的封装
获取查询到的结果
主要作用:
next()是否有下一条记录
针对不同类型的数据可以使用getXXX()获取数据
通用的获取数据的方法:getObject();
jdbc的资源释放
jdbc程序运行完后,切记要释放程序在运行过程中创建的那些与数据库进行交互的对象
这些对象通常是ResultSet,Statement,和Connection对象。
jdbc的CRUD操作
1、向数据库中保存记录
2、修改数据库中的记录
3、删除数据库中的记录
4、查询数据库中的记录
public class jdbcDemo2 {
@Test
/*
* 查询一条记录
*/
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", "root");
stmt=conn.createStatement();
String sql="select * from user where uid=2";
rs=stmt.executeQuery(sql);
if(rs.next()){
System.out.println(rs.getInt("uid")+" "+rs.getString("username")+" "+rs.getString("password")+" "+rs.getString("name"));
}
} catch (Exception e) {
e.printStackTrace();
}finally{
if(rs!=null){
try {
rs.close();
} catch (SQLException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
rs=null;
}
if(stmt!=null){
try {
stmt.close();
} catch (SQLException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
stmt =null;
}
if(conn!=null){
try {
conn.close();
} catch (SQLException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
conn =null;
}
}
}
@Test
/*
* 查询所有记录
*/
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", "root");
stmt=conn.createStatement();
String sql="select * from user";
rs=stmt.executeQuery(sql);
while(rs.next()){
System.out.println(rs.getInt("uid")+" "+rs.getString("username")+" "+rs.getString("password")+" "+rs.getString("name"));
}
} catch (Exception e) {
e.printStackTrace();
}finally{
if(rs!=null){
try {
rs.close();
} catch (SQLException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
rs=null;
}
if(stmt!=null){
try {
stmt.close();
} catch (SQLException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
stmt =null;
}
if(conn!=null){
try {
conn.close();
} catch (SQLException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
conn =null;
}
}
}
@Test
/*
* 删除操作
*/
public void demo3(){
Connection conn=null;
Statement stmt=null;
try {
Class.forName("com.mysql.jdbc.Driver");
conn=DriverManager.getConnection("jdbc:mysql:///jdbctest", "root", "root");
stmt=conn.createStatement();
String sql="delete from user where uid=4";
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) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
stmt =null;
}
if(conn!=null){
try {
conn.close();
} catch (SQLException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
conn =null;
}
}
}
@Test
/**
* jdbc修改操作
*/
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","root");
//获得执行sql语句的对象
stmt=conn.createStatement();
//编写sql
String sql="update user set username='uuuu',password='555',name='张四' where uid=4";
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) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
stmt =null;
}
if(conn!=null){
try {
conn.close();
} catch (SQLException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
conn =null;
}
}
}
@Test
/**
* jdbc保存操作
*/
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","root");
//获得执行sql语句的对象
stmt=conn.createStatement();
//编写sql
String sql="insert into user values(null,'eer','123','er13')";
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) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
stmt =null;
}
if(conn!=null){
try {
conn.close();
} catch (SQLException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
conn =null;
}
}
}
}
JDBC工具类的抽取
jdbc.properties
driverClass=com.mysql.jdbc.Driver
url=jdbc:mysql:///jdbctest
username=root
password=root
/**
* JDBC 工具类
*
*/
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()
.getSystemResourceAsStream("jdbc.properties");
try {
props.load(is);
} catch (IOException e) {
// TODO 自动生成的 catch 块
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);
}
/*
* 获得连接的方法
*/
public static Connection getConnection() throws SQLException,
ClassNotFoundException {
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) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
stmt = null;
}
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
conn = null;
}
}
public static void release(ResultSet rs, Statement stmt, Connection conn) {
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
rs = null;
}
if (stmt != null) {
try {
stmt.close();
} catch (SQLException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
stmt = null;
}
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
conn = null;
}
}
}
public class JDBCDemo3 {
@Test
// 保存记录
public void demo1() {//测试上述工具类
Connection conn = null;
Statement stmt = null;
try {
conn = JDBCUtils.getConnection();
stmt = conn.createStatement();
String sql = "Insert into user values(null,'asdf','1245','00b')";
int num = stmt.executeUpdate(sql);
if (num > 0) {
System.out.println("插入成功");
}
} catch (Exception e) {
e.printStackTrace();
} finally {
JDBCUtils.release(stmt, conn);
}
}
}
jdbc的sql注入漏洞
sql注入漏洞的解决
PreparedStatement是Statement的子接口,它的实例对象可以通过调用
Connection.preparedStatement(sql)方法获得,相对于Statement对象而言:
PreparedStatement可以避免SQL注入的问题
Statement会使数据库频繁编译sql,可能造成数据库缓冲区的溢出
PreparedStatement可对Sql进行预编译,从而提高数据库的执行效率
并且PreparedStatement对于sql中的参数,允许使用占位符的形式进行替换,简化Sql语句的编写。
代码演示sql注入和解决
/*
* 演示JDBC的注入漏洞
*/
public class JDBCDemo4 {
@Test
/*
* 测试sql注入漏洞的方法 在输入用户名时输入了sql的关键字
*/
public void demo1() {
JDBCDemo4 j4 = new JDBCDemo4();
System.out.println(j4.login("aaa' or '1=1", "asddadasd"));
System.out.println(j4.login("aaa' -- ", "asddadasd"));
System.out.println(j4.login("aaa' # ", "asddadasd"));
System.out.println(j4.login2("aaa' or '1=1", "asddadasd"));
System.out.println(j4.login2("aaa' -- ", "asddadasd"));
System.out.println(j4.login2("aaa' # ", "asddadasd"));
}
/**
* 避免sql注入漏洞的方法
*/
public boolean login2(String username, String password) {
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
boolean flag = false;
try {
conn = JDBCUtils.getConnection();
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;
}
} catch (Exception e) {
e.printStackTrace();
} finally {
JDBCUtils.release(rs, pstmt, conn);
}
return flag;
}
/**
* 产生sql注入的方法
*
* @param username
* @param password
* @return
*/
public 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();// TODO: handle exception
} finally {
JDBCUtils.release(rs, stmt, conn);
}
return flag;
}
}
PreparedStatement的CRUD相关操作
jdbc的CRUD操作
1、向数据库中保存记录
2、修改数据库中的记录
3、删除数据库中的记录
4、查询数据库中的记录
/**
* PreparedStatement的使用
*
*
*
*/
public class JDBCDemo5 {
@Test
/*
* 查询单个记录
*/
public void demo5() {
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
try {
conn = JDBCUtils.getConnection();
String sql = "select * from user where uid=?";
pstmt = conn.prepareStatement(sql);
pstmt.setInt(1,6);
rs = pstmt.executeQuery();
if (rs.next()) {
System.out.println(rs.getInt("uid") + " "
+ rs.getString("username") + " "
+ rs.getString("password") + " "
+ rs.getString("name") + " ");
}
} catch (Exception e) {
e.printStackTrace();// TODO: handle exception
} finally {
JDBCUtils.release(pstmt, conn);
}
}
@Test
/*
* 查询所有数据
*/
public void demo4() {
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
try {
conn = JDBCUtils.getConnection();
String sql = "select *from user";
pstmt = conn.prepareStatement(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();// TODO: handle exception
} finally {
JDBCUtils.release(pstmt, conn);
}
}
@Test
/*
* 删除数据
*/
public void demo3() {
Connection conn = null;
PreparedStatement pstmt = null;
try {
conn = JDBCUtils.getConnection();
String sql = "delete from user where uid=?";
pstmt = conn.prepareStatement(sql);
pstmt.setInt(1, 10);
int i = pstmt.executeUpdate();
if (i > 0)
System.out.println("success");
else
System.out.println("false");
} catch (Exception e) {
e.printStackTrace();// TODO: handle exception
} finally {
JDBCUtils.release(pstmt, conn);
}
}
@Test
/*
* 修改数据
*/
public void demo2() {
Connection conn = null;
PreparedStatement pstmt = null;
try {
conn = JDBCUtils.getConnection();
String sql = "update user set username =?,password=?,name=? where uid=?";
pstmt = conn.prepareStatement(sql);
pstmt.setString(1, "gggg");
pstmt.setString(2, "ggg222");
pstmt.setString(3, "个速度");
pstmt.setInt(4, 8);
int i = pstmt.executeUpdate();
if (i > 0)
System.out.println("success");
else
System.out.println("false");
} catch (Exception e) {
e.printStackTrace();// TODO: handle exception
} finally {
JDBCUtils.release(pstmt, conn);
}
}
@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, "popo");
pstmt.setString(2, "gpgpgp");
pstmt.setString(3, "78120llp");
// 执行sql
int i = pstmt.executeUpdate();
if (i > 0)
System.out.println("保存成功");
else
System.out.println("保存失败");
} catch (Exception e) {
e.printStackTrace();
} finally {
JDBCUtils.release(pstmt, conn);
}
}
}
数据库的连接池
连接池是创建和管理一个连接的缓冲池的技术,这些连接准备好被任何需要他们的线程使用
应用程序直接获取连接的缺点
用户每次请求都需要与数据库获得连接,而数据库的创建连接通常需要消耗较大的资源,创建时间也较长。极大的浪费数据库的资源,并且极易造成数据库服务器内存溢出。
C3P0连接池
C3P0 连接池的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>
<property name="user">root</property>
<property name="password">root</property>
<property name="initialPoolSize">5</property>
<property name="maxPoolSize">20</property>
</default-config>
</c3p0-config>
//抽取为工具类
import com.mchange.v2.c3p0.ComboPooledDataSource;
public class JDBCUtils2 {
private static final ComboPooledDataSource dataSource = new ComboPooledDataSource();
/*
* 获得连接的方法
*/
public static Connection getConnection() throws SQLException,
ClassNotFoundException {
Connection conn = dataSource.getConnection();
return conn;
}
/*
* 资源的释放
*/
public static void release(Statement stmt, Connection conn) {
if (stmt != null) {
try {
stmt.close();
} catch (SQLException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
stmt = null;
}
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
conn = null;
}
}
public static void release(ResultSet rs, Statement stmt, Connection conn) {
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
rs = null;
}
if (stmt != null) {
try {
stmt.close();
} catch (SQLException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
stmt = null;
}
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
conn = null;
}
}
}
/*
* 连接池的测试类
*/
public class DataSourceDemo1 {
@Test
/**
* 使用配置文件的方式
*/
public void demo2() {
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
try {// 创建连接池
// ComboPooledDataSource dataSource = new
// ComboPooledDataSource();
// 获得连接
// conn = dataSource.getConnection();
conn = JDBCUtils2.getConnection();
String sql = "select * from user";
pstmt = conn.prepareStatement(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 {
JDBCUtils2.release(rs, pstmt, conn);
}
}
@Test
/**
* 手动设置连接池
*/
public void demo1() {
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
try {// 创建连接池
ComboPooledDataSource dataSource = new ComboPooledDataSource();
// 设置连接池
dataSource.setDriverClass("com.mysql.jdbc.Driver");
dataSource.setJdbcUrl("jdbc:mysql:///jdbctest");
dataSource.setUser("root");
dataSource.setPassword("root");
dataSource.setMaxPoolSize(20);
dataSource.setInitialPoolSize(2);
// 获得连接
conn = dataSource.getConnection();
String sql = "select * from user";
pstmt = conn.prepareStatement(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);
}
}
}
最后宣传下我个人的微信公众号,微信搜索:可及的小屋,有志向整副业,娱乐的程序员们,欢迎您的到来。谢谢。
100G程序员资料,自取哦!!