一篇文章入门JDBC!!!Fighting!!!!

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程序员资料,自取哦!!
可及的小屋

发布了48 篇原创文章 · 获赞 9 · 访问量 2405

猜你喜欢

转载自blog.csdn.net/jjy19971023/article/details/104366105