浅学JDBC 笔记记录
一、
1. JDBC的概念
2. JDBC快速入门
import java.sql.*;
public class JDBCDemo01 {
public static void main(String[] args) throws ClassNotFoundException, SQLException {
//1. 导入jar包 此处使用maven依赖引入
//2. 注册驱动
// 此步骤可以跳过 源码中已经填充
// Class.forName("com.mysql.jdbc.Driver");
//3. 获取连接
Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/db8", "root", "root");
//4. 获取执行者对象
Statement stat = con.createStatement();
//5. 执行sql语句,并且接受sql语句返回结果
String sql="select * from account";
ResultSet rs = stat.executeQuery(sql);
//6.处理结果
while (rs.next()){
System.out.println(rs.getInt("id")+"\t"+rs.getString("name")+"\t"+rs.getString("money"));
}
//7.释放相关资源
con.close();
stat.close();
rs.close();
}
}
上面使用的类进行详解
2.1 DriverManager
2.2 Connection
2.3 Statement
2.4 ResultSet
3. JDBC入门案例使用
数据准备
create database db1;
use db1;
#创建Student表
create table student(
id int primary key auto_increment,
name varchar(20),
age int,
birthday Date
);
#添加数据
insert into student values (null,'张三',23,'1999-09-23'),(null,'李四',24,'1998-08-10'),(null,'王五',25,'1996-06-06')
,(null,'赵六',26,'1994-10-20');
实体类
package domain;
import java.util.Date;
public class Student {
private Integer id;
private String name;
private Integer age;
private Date birthday;
public Student() {
}
public Student(Integer id, String name, Integer age, Date birthday) {
this.id = id;
this.name = name;
this.age = age;
this.birthday = birthday;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
@Override
public String toString() {
return "domain.Student{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
", birthday=" + birthday +
'}';
}
}
3.1 查询所有学生信息
dao:
public interface StudentDao {
ArrayList<Student> findAll();
}
daoImpl:
public class StudentDaoImpl implements StudentDao{
//查询所有学生信息
@Override
public ArrayList<Student> findAll() {
ArrayList<Student> list=new ArrayList();
Connection con =null;
Statement statement =null;
ResultSet resultSet =null;
try {
//1.注册驱动
Class.forName("com.mysql.jdbc.Driver");
//2.获取连接
con = DriverManager.getConnection("jdbc:mysql://localhost:3306/db1", "root", "root");
//3.获取执行者对象
statement = con.createStatement();
//4.执行sql语句。并且接受返回的结果集
String sql="select * from student";
resultSet = statement.executeQuery(sql);
//5.处理结果集
while (resultSet.next()){
Integer id=resultSet.getInt("id");
String name=resultSet.getString("name");
Integer age=resultSet.getInt("age");
Date date=resultSet.getDate("birthday");
//封装Student对象
Student student=new Student(id,name,age,date);
//将Student保存到集合对象
list.add(student);
}
} catch (Exception e) {
e.printStackTrace();
}finally {
if (con!=null){
try {
con.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (statement!=null){
try {
statement.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (resultSet!=null){
try {
resultSet.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
return list;
}
}
service:
public interface StudentService {
//查询所有学生信息
ArrayList<Student> findAll();
}
serviceImpl:
public class StudentServiceImpl implements StudentService{
private StudentDao dao=new StudentDaoImpl();
@Override
public ArrayList<Student> findAll() {
return dao.findAll();
}
}
controller:
package controller;
import domain.Student;
import org.junit.Test;
import service.StudentService;
import service.StudentServiceImpl;
import java.util.ArrayList;
public class StudentController {
private StudentService service=new StudentServiceImpl();
@Test
public void findAll(){
ArrayList<Student> list = service.findAll();
for (Student student:list){
System.out.println(student);
}
}
}
成功:
3.2 根据id查询学生信息&&新增学生信息&&修改学生信息&&删除学生信息
dao:
package dao;
import domain.Student;
import java.util.ArrayList;
/**
Dao层接口
*/
public interface StudentDao {
//查询所有学生信息
ArrayList<Student> findAll();
//条件查询,根据id获取学生信息
Student findById(Integer id);
//新增学生信息
int insert(Student stu);
//修改学生信息
int update(Student stu);
//删除学生信息
int delete(Integer id);
}
daoImpl:
package dao;
import domain.Student;
import java.sql.*;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
public class StudentDaoImpl implements StudentDao{
//查询所有学生信息
@Override
public ArrayList<Student> findAll() {
ArrayList<Student> list=new ArrayList();
Connection con =null;
Statement statement =null;
ResultSet resultSet =null;
try {
//1.注册驱动
Class.forName("com.mysql.jdbc.Driver");
//2.获取连接
con = DriverManager.getConnection("jdbc:mysql://localhost:3306/db1?useSSL=false", "root", "root");
//3.获取执行者对象
statement = con.createStatement();
//4.执行sql语句。并且接受返回的结果集
String sql="select * from student";
resultSet = statement.executeQuery(sql);
//5.处理结果集
while (resultSet.next()){
Integer id=resultSet.getInt("id");
String name=resultSet.getString("name");
Integer age=resultSet.getInt("age");
Date date=resultSet.getDate("birthday");
//封装Student对象
Student student=new Student(id,name,age,date);
//将Student保存到集合对象
list.add(student);
}
} catch (Exception e) {
e.printStackTrace();
}finally {
if (con!=null){
try {
con.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (statement!=null){
try {
statement.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (resultSet!=null){
try {
resultSet.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
return list;
}
//条件查询,根据id获取学生信息
@Override
public Student findById(Integer id) {
Student student=new Student();
Connection con =null;
Statement statement =null;
ResultSet resultSet =null;
try {
//1.注册驱动
Class.forName("com.mysql.jdbc.Driver");
//2.获取连接
con = DriverManager.getConnection("jdbc:mysql://localhost:3306/db1?useSSL=false", "root", "root");
//3.获取执行者对象
statement = con.createStatement();
//4.执行sql语句。并且接受返回的结果集
String sql="select * from student where id='"+id+"'";
resultSet = statement.executeQuery(sql);
//5.处理结果集
while (resultSet.next()){
Integer sid=resultSet.getInt("id");
String name=resultSet.getString("name");
Integer age=resultSet.getInt("age");
Date date=resultSet.getDate("birthday");
//封装Student对象
student=new Student(sid,name,age,date);
}
} catch (Exception e) {
e.printStackTrace();
}finally {
if (con!=null){
try {
con.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (statement!=null){
try {
statement.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (resultSet!=null){
try {
resultSet.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
return student;
}
//新增学生信息
@Override
public int insert(Student stu) {
Connection con =null;
Statement statement =null;
int result=0;
try {
//1.注册驱动
Class.forName("com.mysql.jdbc.Driver");
//2.获取连接
con = DriverManager.getConnection("jdbc:mysql://localhost:3306/db1?useSSL=false", "root", "root");
//3.获取执行者对象
statement = con.createStatement();
//4.执行sql语句。并且接受返回的结果集
Date birthday = stu.getBirthday();
SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
String date = sdf.format(birthday);
String sql="insert into student values('"+stu.getId()+ "','"+stu.getName()+"','"+stu.getAge()+"','"+date+"')";
result = statement.executeUpdate(sql);
//5.处理结果集
} catch (Exception e) {
e.printStackTrace();
}finally {
if (con!=null){
try {
con.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (statement!=null){
try {
statement.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
return result;
}
//修改学生信息
@Override
public int update(Student stu) {
Connection con =null;
Statement statement =null;
int result=0;
try {
//1.注册驱动
Class.forName("com.mysql.jdbc.Driver");
//2.获取连接
con = DriverManager.getConnection("jdbc:mysql://localhost:3306/db1?useSSL=false", "root", "root");
//3.获取执行者对象
statement = con.createStatement();
//4.执行sql语句。并且接受返回的结果集
Date birthday = stu.getBirthday();
SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
String date = sdf.format(birthday);
String sql="update student set id='"+stu.getId()+"',name='"+stu.getName()+"',age='"+stu.getAge()+"',birthday='"+date+"' where id='"+stu.getId()+"'";
result = statement.executeUpdate(sql);
//5.处理结果集
} catch (Exception e) {
e.printStackTrace();
}finally {
if (con!=null){
try {
con.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (statement!=null){
try {
statement.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
return result;
}
//删除学生信息
@Override
public int delete(Integer id) {
Connection con =null;
Statement statement =null;
int result=0;
try {
//1.注册驱动
Class.forName("com.mysql.jdbc.Driver");
//2.获取连接
con = DriverManager.getConnection("jdbc:mysql://localhost:3306/db1?useSSL=false", "root", "root");
//3.获取执行者对象
statement = con.createStatement();
//4.执行sql语句。并且接受返回的结果集
String sql="delete from student where id='"+id+"'";
result = statement.executeUpdate(sql);
} catch (Exception e) {
e.printStackTrace();
}finally {
if (con!=null){
try {
con.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (statement!=null){
try {
statement.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
return result;
}
}
service:
package service;
import domain.Student;
import java.util.ArrayList;
public interface StudentService {
//查询所有学生信息
ArrayList<Student> findAll();
//条件查询,根据id获取学生信息
Student findById(Integer id);
//新增学生信息
int insert(Student stu);
//修改学生信息
int update(Student stu);
//删除学生信息
int delete(Integer id);
}
serviceImpl:
package service;
import dao.StudentDao;
import dao.StudentDaoImpl;
import domain.Student;
import java.util.ArrayList;
public class StudentServiceImpl implements StudentService{
private StudentDao dao=new StudentDaoImpl();
@Override
public ArrayList<Student> findAll() {
return dao.findAll();
}
@Override
public Student findById(Integer id) {
return dao.findById(id);
}
@Override
public int insert(Student stu) {
return dao.insert(stu);
}
@Override
public int update(Student stu) {
return dao.update(stu);
}
@Override
public int delete(Integer id) {
return dao.delete(id);
}
}
controller:
package controller;
import com.sun.xml.internal.bind.v2.model.core.ID;
import domain.Student;
import org.junit.Test;
import service.StudentService;
import service.StudentServiceImpl;
import java.util.ArrayList;
import java.util.Date;
public class StudentController {
private StudentService service=new StudentServiceImpl();
//查询所有学生信息
@Test
public void findAll(){
ArrayList<Student> list = service.findAll();
for (Student student:list){
System.out.println(student);
}
}
//条件查询,根据id获取学生信息
@Test
public void findById(){
Student student=service.findById(1);
System.out.println(student);
}
//新增学生信息
@Test
public void insert(){
Student student=new Student(5,"李薇",88,new Date());
int result = service.insert(student);
if (result!=0){
System.out.println("添加成功");
}else {
System.out.println("添加失败");
}
}
//修改学生信息
@Test
public void update(){
Student stu = service.findById(5);
stu.setName("李兔兔");
int result = service.update(stu);
if (result!=0){
System.out.println("更新成功");
}else {
System.out.println("更行失败");
}
}
//删除学生信息
@Test
public void delete(){
int result = service.delete(5);
if (result!=0){
System.out.println("删除成功");
}else {
System.out.println("删除失败");
}
}
}
4. JDBC工具类
4.1 工具类编写
config.properties配置类
driverClass=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/db1?useSSL=false
username=root
password=root
工具类
package utils;
import java.io.InputStream;
import java.sql.*;
import java.util.Properties;
/**
* JDBC 工具类
*/
public class JDBCUtils {
//1.私有构造方法
private JDBCUtils() {
}
//2.声明所需要的配置变量
private static String driverClass;
private static String url;
private static String username;
private static String password;
private static Connection con;
//3. 提供静态代码块读取配置文件的信息 注册驱动
static {
try {
InputStream is = JDBCUtils.class.getClassLoader().getResourceAsStream("config.properties");
Properties prop = new Properties();
prop.load(is);
driverClass = prop.getProperty("driverClass");
url = prop.getProperty("url");
username = prop.getProperty("username");
password = prop.getProperty("password");
//注册驱动
Class.forName(driverClass);
} catch (Exception e) {
e.printStackTrace();
}
}
// 4. 提供获取数据库连接方法
public static Connection getConnection() {
try {
con = DriverManager.getConnection(url, username, password);
} catch (SQLException e) {
e.printStackTrace();
}
return con;
}
//5. 提供释放资源的方法
public static void close(Connection con, Statement stat, ResultSet res) {
if (con != null) {
try {
con.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (stat != null) {
try {
stat.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (res != null) {
try {
res.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
public static void close(Connection con, Statement stat) {
if (con != null) {
try {
con.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (stat != null) {
try {
stat.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
此处出现一个问题:项目启动报空指针,config.properties放入resources中重新加载target中就好了。
5. SQL注入攻击
select * from user where loginname=‘aaa’ and password=‘bbb’ or ‘1’=‘1’;
SQL注入:简单理解就是 数据库中有一个账号和密码 为 张三 123456
而当用户输入 123’ or ‘1’='1 执行或命令为true也会返回数据
竟然返回了数据
解决办法:使用预编译执行者对象
6. JDBC事务管理
7. JDBC连接池
package utils;
import javax.sql.DataSource;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.logging.Logger;
public class MyDataSource implements DataSource {
//1.准备容器,用于保存多个连接对象
private static List<Connection> pool= Collections.synchronizedList(new ArrayList<>());
//2.定义静态代码块 通过工具类获取10个连接对象
static {
for (int i = 0; i < 10; i++) {
Connection con = JDBCUtils.getConnection();
pool.add(con);
}
}
//3.重写getConnection(),用户获取一个连接对象使用
@Override
public Connection getConnection() throws SQLException {
if (pool.size()>0){
Connection connection = pool.remove(0);
return connection;
}else{
throw new RuntimeException("连接池数量用尽!");
}
}
//4.定义getSize()用来返回连接池大小
public int getSize(){
return pool.size();
}
@Override
public Connection getConnection(String username, String password) throws SQLException {
return null;
}
@Override
public <T> T unwrap(Class<T> iface) throws SQLException {
return null;
}
@Override
public boolean isWrapperFor(Class<?> iface) throws SQLException {
return false;
}
@Override
public PrintWriter getLogWriter() throws SQLException {
return null;
}
@Override
public void setLogWriter(PrintWriter out) throws SQLException {
}
@Override
public void setLoginTimeout(int seconds) throws SQLException {
}
@Override
public int getLoginTimeout() throws SQLException {
return 0;
}
@Override
public Logger getParentLogger() throws SQLFeatureNotSupportedException {
return null;
}
}
7.1 继承方式归还连接
虽然继承重写了close方法但是工具类中没有使用子类的对象。
package utils;
import com.mysql.jdbc.JDBC4Connection;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;
import java.util.Properties;
public class MyConnection1 extends JDBC4Connection {
private Connection connection;
private List<Connection> pool;
public MyConnection1(String hostToConnectTo, int portToConnectTo, Properties info, String databaseToConnectTo, String url,Connection connection,List<Connection> pool) throws SQLException {
super(hostToConnectTo, portToConnectTo, info, databaseToConnectTo, url);
this.connection=connection;
this.pool=pool;
}
@Override
public void close() throws SQLException {
pool.add(connection);
}
}
7.2 装饰设计模式归还连接
虽然归还了但是要重写很多方法
package utils;
import java.sql.*;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.Executor;
public class MyConnection2 implements Connection {
private Connection connection;
private List<Connection> pool;
public MyConnection2(Connection connection, List<Connection> pool) {
this.connection = connection;
this.pool = pool;
}
@Override
public void close() throws SQLException {
pool.add(connection);
}
@Override
public Statement createStatement() throws SQLException {
return connection.createStatement();
}
@Override
public PreparedStatement prepareStatement(String sql) throws SQLException {
return connection.prepareStatement(sql);
}
@Override
public CallableStatement prepareCall(String sql) throws SQLException {
return connection.prepareCall(sql);
}
@Override
public String nativeSQL(String sql) throws SQLException {
return connection.nativeSQL(sql);
}
@Override
public void setAutoCommit(boolean autoCommit) throws SQLException {
connection.setAutoCommit(autoCommit);
}
@Override
public boolean getAutoCommit() throws SQLException {
return connection.getAutoCommit();
}
@Override
public void commit() throws SQLException {
connection.commit();
}
@Override
public void rollback() throws SQLException {
connection.rollback();
}
@Override
public boolean isClosed() throws SQLException {
return connection.isClosed();
}
@Override
public DatabaseMetaData getMetaData() throws SQLException {
return connection.getMetaData();
}
@Override
public void setReadOnly(boolean readOnly) throws SQLException {
connection.setReadOnly(readOnly);
}
@Override
public boolean isReadOnly() throws SQLException {
return connection.isReadOnly();
}
@Override
public void setCatalog(String catalog) throws SQLException {
connection.setCatalog(catalog);
}
@Override
public String getCatalog() throws SQLException {
return connection.getCatalog();
}
@Override
public void setTransactionIsolation(int level) throws SQLException {
connection.setTransactionIsolation(level);
}
@Override
public int getTransactionIsolation() throws SQLException {
return connection.getTransactionIsolation();
}
@Override
public SQLWarning getWarnings() throws SQLException {
return connection.getWarnings();
}
@Override
public void clearWarnings() throws SQLException {
connection.clearWarnings();
}
@Override
public Statement createStatement(int resultSetType, int resultSetConcurrency) throws SQLException {
return connection.createStatement(resultSetType, resultSetConcurrency);
}
@Override
public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
return connection.prepareStatement(sql, resultSetType, resultSetConcurrency);
}
@Override
public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
return connection.prepareCall(sql, resultSetType, resultSetConcurrency);
}
@Override
public Map<String, Class<?>> getTypeMap() throws SQLException {
return connection.getTypeMap();
}
@Override
public void setTypeMap(Map<String, Class<?>> map) throws SQLException {
connection.setTypeMap(map);
}
@Override
public void setHoldability(int holdability) throws SQLException {
connection.setHoldability(holdability);
}
@Override
public int getHoldability() throws SQLException {
return connection.getHoldability();
}
@Override
public Savepoint setSavepoint() throws SQLException {
return connection.setSavepoint();
}
@Override
public Savepoint setSavepoint(String name) throws SQLException {
return connection.setSavepoint(name);
}
@Override
public void rollback(Savepoint savepoint) throws SQLException {
connection.rollback(savepoint);
}
@Override
public void releaseSavepoint(Savepoint savepoint) throws SQLException {
connection.releaseSavepoint(savepoint);
}
@Override
public Statement createStatement(int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
return connection.createStatement(resultSetType, resultSetConcurrency, resultSetHoldability);
}
@Override
public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
return connection.prepareStatement(sql, resultSetType, resultSetConcurrency, resultSetHoldability);
}
@Override
public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
return connection.prepareCall(sql, resultSetType, resultSetConcurrency, resultSetHoldability);
}
@Override
public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) throws SQLException {
return connection.prepareStatement(sql, autoGeneratedKeys);
}
@Override
public PreparedStatement prepareStatement(String sql, int[] columnIndexes) throws SQLException {
return connection.prepareStatement(sql, columnIndexes);
}
@Override
public PreparedStatement prepareStatement(String sql, String[] columnNames) throws SQLException {
return connection.prepareStatement(sql, columnNames);
}
@Override
public Clob createClob() throws SQLException {
return connection.createClob();
}
@Override
public Blob createBlob() throws SQLException {
return connection.createBlob();
}
@Override
public NClob createNClob() throws SQLException {
return connection.createNClob();
}
@Override
public SQLXML createSQLXML() throws SQLException {
return connection.createSQLXML();
}
@Override
public boolean isValid(int timeout) throws SQLException {
return connection.isValid(timeout);
}
@Override
public void setClientInfo(String name, String value) throws SQLClientInfoException {
connection.setClientInfo(name, value);
}
@Override
public void setClientInfo(Properties properties) throws SQLClientInfoException {
connection.setClientInfo(properties);
}
@Override
public String getClientInfo(String name) throws SQLException {
return connection.getClientInfo(name);
}
@Override
public Properties getClientInfo() throws SQLException {
return connection.getClientInfo();
}
@Override
public Array createArrayOf(String typeName, Object[] elements) throws SQLException {
return connection.createArrayOf(typeName, elements);
}
@Override
public Struct createStruct(String typeName, Object[] attributes) throws SQLException {
return connection.createStruct(typeName, attributes);
}
@Override
public void setSchema(String schema) throws SQLException {
connection.setSchema(schema);
}
@Override
public String getSchema() throws SQLException {
return connection.getSchema();
}
@Override
public void abort(Executor executor) throws SQLException {
connection.abort(executor);
}
@Override
public void setNetworkTimeout(Executor executor, int milliseconds) throws SQLException {
connection.setNetworkTimeout(executor, milliseconds);
}
@Override
public int getNetworkTimeout() throws SQLException {
return connection.getNetworkTimeout();
}
@Override
public <T> T unwrap(Class<T> iface) throws SQLException {
return connection.unwrap(iface);
}
@Override
public boolean isWrapperFor(Class<?> iface) throws SQLException {
return connection.isWrapperFor(iface);
}
}
7.3 适配器设计模式归还连接
import java.sql.*;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.Executor;
public abstract class MyAdapter implements Connection {
private Connection connection;
public MyAdapter(Connection connection) {
this.connection = connection;
}
@Override
public Statement createStatement() throws SQLException {
return connection.createStatement();
}
@Override
public PreparedStatement prepareStatement(String sql) throws SQLException {
return connection.prepareStatement(sql);
}
@Override
public CallableStatement prepareCall(String sql) throws SQLException {
return connection.prepareCall(sql);
}
@Override
public String nativeSQL(String sql) throws SQLException {
return connection.nativeSQL(sql);
}
@Override
public void setAutoCommit(boolean autoCommit) throws SQLException {
connection.setAutoCommit(autoCommit);
}
@Override
public boolean getAutoCommit() throws SQLException {
return connection.getAutoCommit();
}
@Override
public void commit() throws SQLException {
connection.commit();
}
@Override
public void rollback() throws SQLException {
connection.rollback();
}
@Override
public boolean isClosed() throws SQLException {
return connection.isClosed();
}
@Override
public DatabaseMetaData getMetaData() throws SQLException {
return connection.getMetaData();
}
@Override
public void setReadOnly(boolean readOnly) throws SQLException {
connection.setReadOnly(readOnly);
}
@Override
public boolean isReadOnly() throws SQLException {
return connection.isReadOnly();
}
@Override
public void setCatalog(String catalog) throws SQLException {
connection.setCatalog(catalog);
}
@Override
public String getCatalog() throws SQLException {
return connection.getCatalog();
}
@Override
public void setTransactionIsolation(int level) throws SQLException {
connection.setTransactionIsolation(level);
}
@Override
public int getTransactionIsolation() throws SQLException {
return connection.getTransactionIsolation();
}
@Override
public SQLWarning getWarnings() throws SQLException {
return connection.getWarnings();
}
@Override
public void clearWarnings() throws SQLException {
connection.clearWarnings();
}
@Override
public Statement createStatement(int resultSetType, int resultSetConcurrency) throws SQLException {
return connection.createStatement(resultSetType, resultSetConcurrency);
}
@Override
public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
return connection.prepareStatement(sql, resultSetType, resultSetConcurrency);
}
@Override
public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
return connection.prepareCall(sql, resultSetType, resultSetConcurrency);
}
@Override
public Map<String, Class<?>> getTypeMap() throws SQLException {
return connection.getTypeMap();
}
@Override
public void setTypeMap(Map<String, Class<?>> map) throws SQLException {
connection.setTypeMap(map);
}
@Override
public void setHoldability(int holdability) throws SQLException {
connection.setHoldability(holdability);
}
@Override
public int getHoldability() throws SQLException {
return connection.getHoldability();
}
@Override
public Savepoint setSavepoint() throws SQLException {
return connection.setSavepoint();
}
@Override
public Savepoint setSavepoint(String name) throws SQLException {
return connection.setSavepoint(name);
}
@Override
public void rollback(Savepoint savepoint) throws SQLException {
connection.rollback(savepoint);
}
@Override
public void releaseSavepoint(Savepoint savepoint) throws SQLException {
connection.releaseSavepoint(savepoint);
}
@Override
public Statement createStatement(int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
return connection.createStatement(resultSetType, resultSetConcurrency, resultSetHoldability);
}
@Override
public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
return connection.prepareStatement(sql, resultSetType, resultSetConcurrency, resultSetHoldability);
}
@Override
public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
return connection.prepareCall(sql, resultSetType, resultSetConcurrency, resultSetHoldability);
}
@Override
public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) throws SQLException {
return connection.prepareStatement(sql, autoGeneratedKeys);
}
@Override
public PreparedStatement prepareStatement(String sql, int[] columnIndexes) throws SQLException {
return connection.prepareStatement(sql, columnIndexes);
}
@Override
public PreparedStatement prepareStatement(String sql, String[] columnNames) throws SQLException {
return connection.prepareStatement(sql, columnNames);
}
@Override
public Clob createClob() throws SQLException {
return connection.createClob();
}
@Override
public Blob createBlob() throws SQLException {
return connection.createBlob();
}
@Override
public NClob createNClob() throws SQLException {
return connection.createNClob();
}
@Override
public SQLXML createSQLXML() throws SQLException {
return connection.createSQLXML();
}
@Override
public boolean isValid(int timeout) throws SQLException {
return connection.isValid(timeout);
}
@Override
public void setClientInfo(String name, String value) throws SQLClientInfoException {
connection.setClientInfo(name, value);
}
@Override
public void setClientInfo(Properties properties) throws SQLClientInfoException {
connection.setClientInfo(properties);
}
@Override
public String getClientInfo(String name) throws SQLException {
return connection.getClientInfo(name);
}
@Override
public Properties getClientInfo() throws SQLException {
return connection.getClientInfo();
}
@Override
public Array createArrayOf(String typeName, Object[] elements) throws SQLException {
return connection.createArrayOf(typeName, elements);
}
@Override
public Struct createStruct(String typeName, Object[] attributes) throws SQLException {
return connection.createStruct(typeName, attributes);
}
@Override
public void setSchema(String schema) throws SQLException {
connection.setSchema(schema);
}
@Override
public String getSchema() throws SQLException {
return connection.getSchema();
}
@Override
public void abort(Executor executor) throws SQLException {
connection.abort(executor);
}
@Override
public void setNetworkTimeout(Executor executor, int milliseconds) throws SQLException {
connection.setNetworkTimeout(executor, milliseconds);
}
@Override
public int getNetworkTimeout() throws SQLException {
return connection.getNetworkTimeout();
}
@Override
public <T> T unwrap(Class<T> iface) throws SQLException {
return connection.unwrap(iface);
}
@Override
public boolean isWrapperFor(Class<?> iface) throws SQLException {
return connection.isWrapperFor(iface);
}
}
import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;
public class MyConnection3 extends MyAdapter{
private Connection connection;
private List<Connection> pool;
public MyConnection3(Connection connection,List<Connection> pool) {
super(connection);
this.connection=connection;
this.pool=pool;
}
@Override
public void close() throws SQLException {
pool.add(connection);
}
}
7.4 动态代理方式归还连接
public interface StuInterface {
void eat(String name);
void study();
}
public class Student implements StuInterface{
public void eat(String name){
System.out.println("学生吃"+name);
}
public void study(){
System.out.println("在家自学");
}
}
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class Test {
public static void main(String[] args) {
Student student=new Student();
// student.eat("米饭");
// student.study();
/**
*要求不改动Student类中的方法 调用study方法输出 在家 玩 ;使用动态代理
*/
StuInterface proxyInstance = (StuInterface) Proxy.newProxyInstance(student.getClass().getClassLoader(), new Class[]{StuInterface.class}, new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if (method.getName().equals("study")) {
System.out.println("在家玩");
return null;
} else {
return method.invoke(student, args);
}
}
});
proxyInstance.eat("米饭");
proxyInstance.study();
}
}
import javax.sql.DataSource;
import java.io.PrintWriter;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.logging.Logger;
public class MyDataSource implements DataSource {
//1.准备容器,用于保存多个连接对象
private static List<Connection> pool= Collections.synchronizedList(new ArrayList<>());
//2.定义静态代码块 通过工具类获取10个连接对象
static {
for (int i = 0; i < 10; i++) {
Connection con = JDBCUtils.getConnection();
pool.add(con);
}
}
//3.重写getConnection(),用户获取一个连接对象使用
@Override
public Connection getConnection() throws SQLException {
if (pool.size()>0){
Connection connection = pool.remove(0);
Connection connection1= (Connection) Proxy.newProxyInstance(connection.getClass().getClassLoader(), new Class[]{Connection.class}, new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if (method.getName().equals("close")){
pool.add(connection);
return null;
}else{
return method.invoke(connection,args);
}
}
});
return connection1;
}else{
throw new RuntimeException("连接池数量用尽!");
}
}
/* @Override
public Connection getConnection() throws SQLException {
if (pool.size()>0){
Connection connection = pool.remove(0);
MyConnection3 myConnection=new MyConnection3(connection,pool);
return myConnection;
}else{
throw new RuntimeException("连接池数量用尽!");
}
}*/
//4.定义getSize()用来返回连接池大小
public int getSize(){
return pool.size();
}
@Override
public Connection getConnection(String username, String password) throws SQLException {
return null;
}
@Override
public <T> T unwrap(Class<T> iface) throws SQLException {
return null;
}
@Override
public boolean isWrapperFor(Class<?> iface) throws SQLException {
return false;
}
@Override
public PrintWriter getLogWriter() throws SQLException {
return null;
}
@Override
public void setLogWriter(PrintWriter out) throws SQLException {
}
@Override
public void setLoginTimeout(int seconds) throws SQLException {
}
@Override
public int getLoginTimeout() throws SQLException {
return 0;
}
@Override
public Logger getParentLogger() throws SQLFeatureNotSupportedException {
return null;
}
}
8. C3P0连接池使用
会自动加载配置文件的
import com.mchange.v2.c3p0.ComboPooledDataSource;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class C3p0Test {
public static void main(String[] args) throws SQLException {
//1. 创建c3p0的连接池对象
DataSource dataSource = new ComboPooledDataSource();
//2.通过连接池对象获取数据库连接
Connection connection = dataSource.getConnection();
//3.执行操作
String sql = "select * from student";
PreparedStatement pst = connection.prepareStatement(sql);
ResultSet rs = pst.executeQuery();
while (rs.next()) {
System.out.println(rs.getInt("id")
+ " " + rs.getString("name")
+ " " + rs.getInt("age")
+ "");
}
connection.close();
pst.close();
rs.close();
}
}
9. Druid连接池使用
import com.alibaba.druid.pool.DruidDataSourceFactory;
import javax.sql.DataSource;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.Properties;
/**
* @PackageName:com.jou.druid
* @ClassName: DruidTest
* @Description:
* @Author: soulcoder zhufanzhi
* @date: 2023/6/7 10:50
**/
public class DruidTest {
public static void main(String[] args) throws Exception {
//获取配置文件的流对象
InputStream is = DruidTest.class.getClassLoader().getResourceAsStream("druid.properties");
//1. 通过properties集合,加载配置文件
Properties prop = new Properties();
try {
prop.load(is);
} catch (IOException e) {
e.printStackTrace();
}
//2.通过Druid连接池工厂类获取数据库连接池对象
DataSource dataSource = DruidDataSourceFactory.createDataSource(prop);
//3.通过连接池对象获取数据库连接进行使用
Connection connection = dataSource.getConnection();
//4.使用
String sql = "select * from student";
PreparedStatement pst = connection.prepareStatement(sql);
ResultSet rs = pst.executeQuery();
while (rs.next()) {
System.out.println(rs.getInt("id")
+ " " + rs.getString("name")
+ " " + rs.getInt("age")
+ "");
}
connection.close();
pst.close();
rs.close();
}
}
9.1 连接池工具类
import com.alibaba.druid.pool.DruidDataSourceFactory;
import javax.sql.DataSource;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
public class DataSourceUtils {
//1.私有构造方法
private DataSourceUtils(){}
//2.声明数据源变量
private static DataSource dataSource;
//3.提供静态代码块,完成配置文件的加载和获取数据库连接池对象
static {
try {
//完成配置文件的加载
InputStream is = DataSourceUtils.class.getClassLoader().getResourceAsStream("druid.properties");
Properties prop=new Properties();
prop.load(is);
//获取数据库连接池对象
dataSource= DruidDataSourceFactory.createDataSource(prop);
} catch (Exception e) {
e.printStackTrace();
}
}
//4.提供一个获取数据库连接的方法
public static Connection getConnection(){
Connection con=null;
try {
con=dataSource.getConnection();
} catch (SQLException e) {
e.printStackTrace();
}
return con;
}
//5.提供一个获取数据库连接池对象的方法
public static DataSource getDataSource(){
return dataSource;
}
//6.释放资源
public static void close(Connection connection, Statement statement, ResultSet resultSet){
if (connection!=null){
try {
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (statement!=null){
try {
statement.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (resultSet!=null){
try {
resultSet.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
public static void close(Connection connection, Statement statement){
if (connection!=null){
try {
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (statement!=null){
try {
statement.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
9.2 工具类使用
import com.jou.sqlpool.utils.DataSourceUtils;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class DruidTest2 {
public static void main(String[] args) throws SQLException {
//1. 通过连接池工具获取一个数据库连接
Connection connection= DataSourceUtils.getConnection();
String sql = "select * from student";
PreparedStatement pst = connection.prepareStatement(sql);
ResultSet rs = pst.executeQuery();
while (rs.next()) {
System.out.println(rs.getInt("id")
+ " " + rs.getString("name")
+ " " + rs.getInt("age")
+ "");
}
DataSourceUtils.close(connection,pst,rs);
}
}
10.JDBC框架
10.1 获取数据源
import com.alibaba.druid.pool.DruidDataSourceFactory;
import javax.sql.DataSource;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
public class DataSourceUtils {
//1.私有构造方法
private DataSourceUtils(){}
//2.声明数据源变量
private static DataSource dataSource;
//3.提供静态代码块,完成配置文件的加载和获取数据库连接池对象
static {
try {
//完成配置文件的加载
InputStream is = DataSourceUtils.class.getClassLoader().getResourceAsStream("druid.properties");
Properties prop=new Properties();
prop.load(is);
//获取数据库连接池对象
dataSource= DruidDataSourceFactory.createDataSource(prop);
} catch (Exception e) {
e.printStackTrace();
}
}
//4.提供一个获取数据库连接的方法
public static Connection getConnection(){
Connection con=null;
try {
con=dataSource.getConnection();
} catch (SQLException e) {
e.printStackTrace();
}
return con;
}
//5.提供一个获取数据库连接池对象的方法
public static DataSource getDataSource(){
return dataSource;
}
//6.释放资源
public static void close(Connection connection, Statement statement, ResultSet resultSet){
if (connection!=null){
try {
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (statement!=null){
try {
statement.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (resultSet!=null){
try {
resultSet.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
public static void close(Connection connection, Statement statement){
if (connection!=null){
try {
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (statement!=null){
try {
statement.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
10.2 JDBC模板
import javax.sql.DataSource;
import java.sql.*;
public class JDBCTemplate {
//1. 定义参数变量 (数据源、连接对象、执行者对象、结果集对象)
private DataSource dataSource;
private Connection con;
private PreparedStatement pst;
private ResultSet rs;
//2.通过有参构造为数据源赋值
public JDBCTemplate(DataSource dataSource){
this.dataSource=dataSource;
}
//3.定义update方法,参数 sql语句,sql语句的参数 ?占位符
public int update(String sql,Object... objs){
//4.定义一个int变量,用于接受增删改后影响的行数
int result=0;
try {
//5.通过数据源获取一个数据库连接
con=dataSource.getConnection();
//6.通过数据库连接对象获取执行者对象,并对sql语句进行预编译
pst = con.prepareStatement(sql);
//7.通过执行者对象获取参数的源信息对象
ParameterMetaData parameterMetaData = pst.getParameterMetaData();
//8.通过参数源信息对象获取参数个数
int parameterCount = parameterMetaData.getParameterCount();
//9.判断参数数量是否一致
if (parameterCount!=objs.length){
throw new RuntimeException("参数个数不匹配");
}
//10.为sql语句占位符赋值
for (int i = 0; i < objs.length; i++) {
pst.setObject(i+1,objs[i]);
}
//11.执行sql语句并接受结果
result=pst.executeUpdate();
} catch (Exception e) {
e.printStackTrace();
}finally {
//12.释放资源
DataSourceUtils.close(con,pst);
}
//13.返回结果
return result;
}
}
10.3 更新测试
import com.jou.jdbc.utils.DataSourceUtils;
import com.jou.jdbc.utils.JDBCTemplate;
import org.junit.Test;
public class JDBCTemplateTest {
private JDBCTemplate template=new JDBCTemplate(DataSourceUtils.getDataSource());
@Test
public void insert() {
//新增数据的测试
String sql="insert into student values(?,?,?,?)";
Object[] params={6,"关羽",58,"1995-10-12"};
int result = template.update(sql, params);
if (result!=0){
System.out.println("添加成功");
}else{
System.out.println("添加失败");
}
}
}
10.4 查询方法_将一条记录封装为实体类对象返回
import java.sql.ResultSet;
//用于处理结果集
public interface ResultSetHandler<T> {
<T> T handler(ResultSet rs);
}
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
//将查询到的一条记录封装为Student对象并返回
//1.定义一个类,实现ResultSetHandler接口
public class BeanHandler<T> implements ResultSetHandler<T>{
//2.定义Class对象类型变量
private Class<T> beanClass;
//3.通过有参构造为变量赋值
public BeanHandler(Class<T> beanClass){
this.beanClass=beanClass;
}
//4.重写handler方法,并将一条记录封装到自定义对象中
@Override
public T handler(ResultSet rs) {
//5. 声明自定义对象类型
T bean=null;
try {
//6.创建传递参数对象,为自定义对象赋值
bean= beanClass.newInstance();
//7.判断结果集中是否有数据
if(rs.next()){
//8. 通过结果集对象获取结果集源信息对象
ResultSetMetaData metaData = rs.getMetaData();
//9.通过结果集源信息对象获取列数
int columnCount = metaData.getColumnCount();
//10.通过循环遍历列数
for (int i = 1; i <=columnCount; i++) {
//11.通过结果集源信息对象获取列数
String columnName = metaData.getColumnName(i);
//12.通过列明获取数据
Object value = rs.getObject(columnName);
//13.创建属性描述器对象,将获取到的值通过该对象的set方法进行赋值
PropertyDescriptor pd=new PropertyDescriptor(columnName.toLowerCase(),beanClass);
//获取其中的set方法
Method writeMethod = pd.getWriteMethod();
//执行对应的set方法
writeMethod.invoke(bean,value);
}
}
} catch (Exception e) {
e.printStackTrace();
}
//14.返回封装好的对象
return bean;
}
}
@Test
public void queryForObject() {
//新增数据的测试
String sql="select * from student where id=?";
Student student = template.queryForObject(sql, new BeanHandler<>(Student.class), 5);
System.out.println(student);
}