本专栏将从基础开始,循序渐进,讲解数据库的基本概念以及使用,希望大家都能够从中有所收获,也请大家多多支持。
专栏地址: 数据库必知必会
相关软件地址:软件地址
如果文章知识点有错误的地方,请指正!大家一起学习,一起进步。
1 一个关于数据库操作的优化实例
1.1 原始版本
添加依赖
<dependencies>
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.22</version>
</dependency>
</dependencies>
创建数据库与表:
create database learnDesignPattern;
use learnDesignPattern;
create table t_student(
id int(32) primary key auto_increment,
name varchar(50),
age varchar(50)
);
alter table t_student change column age age int(32);
创建学生类Student.java:
public class Student {
private int age;
private String name;
private int id;
public Student(int age, String name) {
this.age = age;
this.name = name;
}
public Student(int age, String name, int id) {
this.age = age;
this.name = name;
this.id = id;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
创建对学术的增删查改StudentDao.java
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.Statement;
public class StudentDao {
//添加学生信息
public void add(Student stu){
String sql = "insert into t_student(name,age) values(?,?)";
Connection conn = null;
Statement st = null;
try{
//1.初始化驱动类,在初始化的时候通过静态代码块中的java.sql.DriverManager.registerDriver(new Driver())注册驱动
Class.forName("com.mysql.cj.jdbc.Driver");
//2.获取数据库连接
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/learnDesignPattern?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=GMT","root","root");
//3.创建语句对象
PreparedStatement ps = conn.prepareStatement(sql);
ps.setObject(1,stu.getName());
ps.setObject(2,stu.getAge());
//4.执行sql
ps.executeUpdate();
} catch (Exception e) {
e.printStackTrace();
}finally {
//释放资源
try{
if (st != null){
st.close();
}
if(conn!=null){
conn.close();
}
}catch (Exception e){
e.printStackTrace();
}
}
}
//删除学生信息
public void delete(int id){
String sql = "delete from t_student where id=?";
Connection conn = null;
Statement st = null;
try{
//1.初始化驱动类,在初始化的时候通过静态代码块中的java.sql.DriverManager.registerDriver(new Driver())注册驱动
Class.forName("com.mysql.cj.jdbc.Driver");
//2.获取数据库连接
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/learnDesignPattern?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=GMT","root","root");
//3.创建语句对象
PreparedStatement ps = conn.prepareStatement(sql);
ps.setObject(1,id);
//4.执行sql
ps.executeUpdate();
} catch (Exception e) {
e.printStackTrace();
}finally {
//释放资源
try{
if (st != null){
st.close();
}
if(conn!=null){
conn.close();
}
}catch (Exception e){
e.printStackTrace();
}
}
}
//修改学生信息
public void update(Student stu){
String sql = "update t_student set name =?,age=? where id=?";
Connection conn = null;
Statement st = null;
try{
//1.初始化驱动类,在初始化的时候通过静态代码块中的java.sql.DriverManager.registerDriver(new Driver())注册驱动
Class.forName("com.mysql.cj.jdbc.Driver");
//2.获取数据库连接
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/learnDesignPattern?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=GMT","root","root");
//3.创建语句对象
PreparedStatement ps = conn.prepareStatement(sql);
ps.setObject(1,stu.getName());
ps.setObject(2,stu.getAge());
ps.setObject(3,stu.getId());
//4.执行sql
ps.executeUpdate();
} catch (Exception e) {
e.printStackTrace();
}finally {
//释放资源
try{
if (st != null){
st.close();
}
if(conn!=null){
conn.close();
}
}catch (Exception e){
e.printStackTrace();
}
}
}
}
1.2 使用JDBCUtil封装代码
可以看到上面代码功能没有问题,但是重复代码太多,因此可以进行抽取,把重复代码放到一个工具类JDBCUtil里。
- JDBCUtil.java
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
public class JDBCUtil {
private JDBCUtil(){
}
static {
try{
//1.初始化驱动类,在初始化的时候通过静态代码块中的java.sql.DriverManager.registerDriver(new Driver())注册驱动
Class.forName("com.mysql.cj.jdbc.Driver");
}catch (Exception e){
e.printStackTrace();
}
}
public static Connection getConnection(){
try{
//2.获取数据库连接
return DriverManager.getConnection("jdbc:mysql://localhost:3306/learnDesignPattern?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=GMT","root","root");
}catch (Exception e){
e.printStackTrace();
}
return null;
}
public static void close(ResultSet rs, Statement st, Connection conn){
//释放资源
try{
if(rs != null){
rs.close();
}
if (st != null){
st.close();
}
if(conn!=null){
conn.close();
}
}catch (Exception e){
e.printStackTrace();
}
}
}
- StudentDao.java
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.Statement;
public class StudentDao {
//添加学生信息
public void add(Student stu){
String sql = "insert into t_student(name,age) values(?,?)";
Connection conn = null;
Statement st = null;
PreparedStatement ps = null;
try{
conn = JDBCUtil.getConnection();
ps = conn.prepareStatement(sql);
ps.setObject(1,stu.getName());
ps.setObject(2,stu.getAge());
ps.executeUpdate();
} catch (Exception e) {
e.printStackTrace();
}finally {
JDBCUtil.close(null,ps,conn);
}
}
//删除学生信息
public void delete(int id){
String sql = "delete from t_student where id=?";
Connection conn = null;
Statement st = null;
PreparedStatement ps = null;
try{
conn = JDBCUtil.getConnection();
ps = conn.prepareStatement(sql);
ps.setObject(1,id);
ps.executeUpdate();
} catch (Exception e) {
e.printStackTrace();
}finally {
JDBCUtil.close(null,ps,conn);
}
}
//修改学生信息
public void update(Student stu){
String sql = "update t_student set name =?,age=? where id=?";
Connection conn = null;
Statement st = null;
PreparedStatement ps = null;
try{
conn = JDBCUtil.getConnection();
ps = conn.prepareStatement(sql);
ps.setObject(1,stu.getName());
ps.setObject(2,stu.getAge());
ps.setObject(1,stu.getId());
ps.executeUpdate();
} catch (Exception e) {
e.printStackTrace();
}finally {
JDBCUtil.close(null,ps,conn);
}
}
}
1.3 使用配置文件,以及查询和修改统一方式
3.2的方法任然有部分冗余,可以把查询和修改的方法进行统一。
- JDBCUtil.java
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Properties;
public class JDBCUtil {
private static Properties p = null;
private JDBCUtil(){
}
static {
try{
//1.初始化驱动类,在初始化的时候通过静态代码块中的java.sql.DriverManager.registerDriver(new Driver())注册驱动
ClassLoader loader = Thread.currentThread().getContextClassLoader();
InputStream inputStream = loader.getResourceAsStream("db.properties");
p = new Properties();
p.load(inputStream);
Class.forName(p.getProperty("driverClassName"));
}catch (Exception e){
e.printStackTrace();
}
}
public static Connection getConnection(){
try{
//2.获取数据库连接
return DriverManager.getConnection(p.getProperty("url"),p.getProperty("username"),p.getProperty("password"));
}catch (Exception e){
e.printStackTrace();
}
return null;
}
public static void close(ResultSet rs, Statement st, Connection conn){
//释放资源
try{
if(rs != null){
rs.close();
}
if (st != null){
st.close();
}
if(conn!=null){
conn.close();
}
}catch (Exception e){
e.printStackTrace();
}
}
}
- JDBCTemplate.java
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;
public class JDBCTemplate {
public static void update(String sql,Object... params){
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
try{
conn = JDBCUtil.getConnection();
ps = conn.prepareStatement(sql);
for(int i=0;i<params.length;i++){
ps.setObject(i+1,params[i]);
}
ps.executeUpdate();
}catch (Exception e){
e.printStackTrace();
}finally {
JDBCUtil.close(rs,ps,conn);
}
}
public static List<Student> query(String sql,Object... params){
List<Student> list = new ArrayList<Student>();
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
try{
conn = JDBCUtil.getConnection();
ps = conn.prepareStatement(sql);
for(int i=0;i<params.length;i++){
ps.setObject(i+1,params[i]);
}
rs = ps.executeQuery();
while(rs.next()){
int id = rs.getInt("id");
String name = rs.getString("name");
int age = rs.getInt("age");
Student stu = new Student(id,name,age);
list.add(stu);
}
}catch (Exception e){
e.printStackTrace();
}finally {
JDBCUtil.close(rs,ps,conn);
}
return list;
}
}
- StudentDao.java
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
public class StudentDao {
private Logger logger = LoggerFactory.getLogger(StudentDao.class);
//添加学生信息
public void add(Student stu){
String sql = "insert into t_student(name,age) values(?,?)";
Object[] params = new Object[]{
stu.getName(),stu.getAge()};
JDBCTemplate.update(sql,params);
}
//删除学生信息
public void delete(int id){
String sql = "delete from t_student where id=?";
JDBCTemplate.update(sql,id);
}
//修改学生信息
public void update(Student stu){
String sql = "update t_student set name =?,age=? where id=?";
Object[] params = new Object[]{
stu.getName(),stu.getAge(),stu.getId()};
JDBCTemplate.update(sql,params);
}
//查询
public Student get(int id){
String sql = "select * from t_student where id=?";
List<Student> list = JDBCTemplate.query(sql, id);
return list.size()>0?list.get(0):null;
}
//查询
public List<Student> list(){
String sql = "select * from t_student";
return JDBCTemplate.query(sql);
}
}
1.4 使用泛型处理多种返回结果
如果不仅要查询学生信息(List类型),还要查询学生数量,这时就要通过泛型来完成。
- IRowMapper.java
import java.sql.ResultSet;
import java.util.List;
public interface IRowMapper<T> {
T mapping(ResultSet rs) throws Exception;
}
- StudentRowMapper.java
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;
public class StudentRowMapper implements IRowMapper<List<Student>> {
public List<Student> mapping(ResultSet rs) throws Exception {
List<Student> list = new ArrayList<Student>();
while(rs.next()){
int id = rs.getInt("id");
String name = rs.getString("name");
int age = rs.getInt("age");
Student stu = new Student(id,name,age);
list.add(stu);
}
return list;
}
}
- JDBCUtil
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Properties;
public class JDBCUtil {
private static Properties p = null;
private JDBCUtil(){
}
static {
try{
//1.初始化驱动类,在初始化的时候通过静态代码块中的java.sql.DriverManager.registerDriver(new Driver())注册驱动
ClassLoader loader = Thread.currentThread().getContextClassLoader();
InputStream inputStream = loader.getResourceAsStream("db.properties");
p = new Properties();
p.load(inputStream);
Class.forName(p.getProperty("driverClassName"));
}catch (Exception e){
e.printStackTrace();
}
}
public static Connection getConnection(){
try{
//2.获取数据库连接
return DriverManager.getConnection(p.getProperty("url"),p.getProperty("username"),p.getProperty("password"));
}catch (Exception e){
e.printStackTrace();
}
return null;
}
public static void close(ResultSet rs, Statement st, Connection conn){
//释放资源
try{
if(rs != null){
rs.close();
}
if (st != null){
st.close();
}
if(conn!=null){
conn.close();
}
}catch (Exception e){
e.printStackTrace();
}
}
}
- StudentDao
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.xml.transform.Result;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
public class StudentDao {
private Logger logger = LoggerFactory.getLogger(StudentDao.class);
//添加学生信息
public void add(Student stu){
String sql = "insert into t_student(name,age) values(?,?)";
Object[] params = new Object[]{
stu.getName(),stu.getAge()};
JDBCTemplate.update(sql,params);
}
//删除学生信息
public void delete(int id){
String sql = "delete from t_student where id=?";
JDBCTemplate.update(sql,id);
}
//修改学生信息
public void update(Student stu){
String sql = "update t_student set name =?,age=? where id=?";
Object[] params = new Object[]{
stu.getName(),stu.getAge(),stu.getId()};
JDBCTemplate.update(sql,params);
}
//查询
public Student get(int id){
String sql = "select * from t_student where id=?";
List<Student> list = JDBCTemplate.query(sql, new StudentRowMapper(),id);
return list.size()>0?list.get(0):null;
}
//查询
public List<Student> list(){
String sql = "select * from t_student";
return JDBCTemplate.query(sql,new StudentRowMapper());
}
public int getCount(){
String sql = "select count(*) total from t_student";
int totalCount = (int)JDBCTemplate.query(sql, new IRowMapper<Integer>() {
public Integer mapping(ResultSet rs) throws Exception{
Integer totalCount = null;
if(rs.next()){
totalCount = rs.getInt("total");
}
return totalCount;
}
});
return totalCount;
}
}
- JDBCTemplate.java
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;
public class JDBCTemplate {
public static void update(String sql,Object... params){
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
try{
conn = JDBCUtil.getConnection();
ps = conn.prepareStatement(sql);
for(int i=0;i<params.length;i++){
ps.setObject(i+1,params[i]);
}
ps.executeUpdate();
}catch (Exception e){
e.printStackTrace();
}finally {
JDBCUtil.close(rs,ps,conn);
}
}
public static <T> T query(String sql,IRowMapper<T> rsh,Object... params){
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
try{
conn = JDBCUtil.getConnection();
ps = conn.prepareStatement(sql);
for(int i=0;i<params.length;i++){
ps.setObject(i+1,params[i]);
}
rs = ps.executeQuery();
return rsh.mapping(rs);
}catch (Exception e){
e.printStackTrace();
}finally {
JDBCUtil.close(rs,ps,conn);
}
return null;
}
}
1.5 连接池
以上代码每次执行sql都要获取数据库连接,这就导致资源的浪费,所以可以使用数据库连接池来优化代码。
- Pool.java
package JDBC.Pool;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.Driver;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Properties;
public abstract class Pool {
// private Logger logger = LoggerFactory.getLogger(Pool.class);
public String propertiesName = "db.properties";
private static Pool instance = null;
//最大连接数
protected int maxConnection = 100;
//保持连接数
protected int stayConnection = 10;
//驱动字符串
protected String driverName = null;
//驱动类
protected Driver driver = null;
protected Pool(){
try{
init();
loadDrivers(driverName);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* @Author cgw
* @Description 初始化所有从配置文件中读取的成员变量
* @return: void
* @Date 2022/2/18 16:13
**/
private void init() throws IOException{
Properties properties = new Properties();
InputStream is = Pool.class.getClassLoader().getResourceAsStream(propertiesName);
try {
properties.load(is);
} catch (IOException e) {
e.printStackTrace();
}
this.driverName = properties.getProperty("driverClassName");
if(properties.getProperty("maxConnection")!=null){
this.maxConnection = Integer.parseInt(properties.getProperty("maxConnection"));
}
if(properties.getProperty("stayConnection")!=null){
this.stayConnection = Integer.parseInt(properties.getProperty("stayConnection"));
}
}
/**
* @Author cgw
* @Description 装载和注册所有JDBC驱动程序
* @param driverName: 接收驱动字符串
* @return: void
* @Date 2022/2/18 16:12
**/
private void loadDrivers(String driverName){
String driverClassName= driverName;
try {
driver = (Driver) Class.forName(driverClassName).newInstance();
DriverManager.registerDriver(driver);
// logger.info("成功注册JDBC驱动程序:{}",driverClassName);
} catch (Exception e) {
// logger.info("无法注册JDBC驱动程序:{},异常:{}",driverClassName,e);
}
}
/**
* @Author cgw
* @Description 获得一个可用的连接,如果没有,则创建一个连接,并且小于最大连接限制
* @return: java.sql.Connection
* @Date 2022/2/18 16:01
**/
public abstract Connection getConnection();
/**
* @Author cgw
* @Description 获得一个连接,有时间限制
* @param time: 设置该连接的持续时间(以毫秒为单位)
* @return: java.sql.Connection
* @Date 2022/2/18 16:02
**/
public abstract Connection getConnection(long time);
/**
* @Author cgw
* @Description 将连接对象返回连接池
* @param connection: 获得连接对象
* @return: void
* @Date 2022/2/18 16:03
**/
public abstract void freeConnection(Connection connection);
/**
* @Author cgw
* @Description 返回当前空闲的连接数
* @return: int
* @Date 2022/2/18 16:04
**/
public abstract int getNumFree();
/**
* @Author cgw
* @Description 返回当前工作的连接数
* @return: int
* @Date 2022/2/18 16:04
**/
public abstract int getNumActive();
/**
* @Author cgw
* @Description 关闭所有连接,撤销驱动注册,此方法为单例方法
* @return: void
* @Date 2022/2/18 16:14
**/
protected synchronized void release(){
try{
DriverManager.deregisterDriver(driver);
// logger.info("撤销JDBC驱动程序:{}",driver.getClass().getName());
} catch (SQLException e) {
// logger.info("无法撤销JDBC驱动程序:{},异常:{}",driver.getClass().getName(),e);
}
}
}
- DBConnectionPool.java
package JDBC.Pool;
import org.slf4j.LoggerFactory;
import org.slf4j.Logger;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.util.Date;
import java.util.Enumeration;
import java.util.Properties;
import java.util.Vector;
//final修饰的类不能被继承
public final class DBConnectionPool extends Pool {
// private Logger logger = LoggerFactory.getLogger(DBConnectionPool.class);
private Vector<Connection> freeConnections = new Vector<Connection>();//存放产生的连接对象容器
private String url = null;//连接字符串
private String username = null;//用户名
private String password = null;//密码
private int numTotal;//连接总数
private static int numFree = 0;//空闲的连接数, 放入到连接池里的连接数量
private static int numActive = 0;//在活跃的连接数,默认为0,指的是在使用的线程数量
private static DBConnectionPool dbConnectionPool = null;//连接池实例对象
private DBConnectionPool(){
try{
init();
for(int i=0;i<stayConnection;i++){
Connection c = newConnection();
if(null != c){
freeConnections.addElement(c);
numTotal++;
numFree++;
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
// 使用单例模式获取连接池
public static DBConnectionPool getInstance() {
if (dbConnectionPool == null){
synchronized (Pool.class){
if(dbConnectionPool == null){
dbConnectionPool = new DBConnectionPool();
}
}
}
return dbConnectionPool;
}
/**
* @Author cgw
* @Description 初始化
* @return: void
* @Date 2022/2/18 16:22
**/
private void init() throws Exception{
InputStream is = DBConnectionPool.class.getClassLoader().getResourceAsStream(propertiesName);
Properties properties = new Properties();
properties.load(is);
this.driverName = properties.getProperty("driverClassName");
this.url = properties.getProperty("url");
this.username = properties.getProperty("username");
this.password = properties.getProperty("password");
}
/**
* @Author cgw
* @Description 创建一个新连接
* @return: java.sql.Connection
* @Date 2022/2/18 16:26
**/
private Connection newConnection(){
Connection connection = null;
try{
if(username == null || password == null){
connection = DriverManager.getConnection(url);
}else {
connection = DriverManager.getConnection(url,username,password);
}
// logger.info("连接池创建一个新的连接");
} catch (Exception e) {
// logger.info("无法创建url:{}的连接,错误原因:{}",url,e);
return null;
}
return connection;
}
/**
* @Author cgw
* @Description 获取一个可用连接
* @return: java.sql.Connection
* @Date 2022/2/18 19:14
**/
public synchronized Connection getConnection() {
Connection connection = null;
if(freeConnections.size() > 0){
connection = (Connection)freeConnections.firstElement();
numFree--;
freeConnections.removeElementAt(0);
try{
if(connection.isClosed()){
// logger.info("从连接池删除一个无效连接");
numTotal--;
connection = getConnection();
}
} catch (Exception e) {
// logger.info("从连接池删除一个无效连接");
}
//没有空闲连接且当前连接小于允许最大值,若最大值为0,则不限制
}else if(maxConnection == 0 || numTotal < maxConnection){
connection = newConnection();
numTotal++;
}
if(connection != null){
numActive++;
}
return connection;
}
//获取一个可用连接,并加上等待时间限制,时间为毫秒
public Connection getConnection(long timeout) {
long startTime = new Date().getTime();
Connection connection = null;
while((connection = getConnection()) == null){
try{
//20毫秒执行一次
Thread.sleep(20);
} catch (Exception e) {
e.printStackTrace();
}
if((new Date().getTime() - startTime) >= timeout){
return null;//如果超时,则返回
}
}
return connection;
}
public void freeConnection(Connection con) {
freeConnections.addElement(con);
numFree++;
numActive--;
// notifyAll();//解锁
}
public int getNumFree() {
return numFree;
}
public int getNumActive() {
return numActive;
}
//释放所有连接
public synchronized void release() {
try {
Enumeration allConnections = freeConnections.elements();
while (allConnections.hasMoreElements()) {
Connection conn = (Connection) allConnections.nextElement();
try {
conn.close();
numFree--;
} catch (Exception e) {
System.out.println("无法关闭连接池中的连接");
}
}
freeConnections.removeAllElements();
numTotal=0;
} catch (Exception e) {
System.out.println("释放失败!");
} finally {
//卸载驱动
super.release();
}
}
}
- JDBCUtil.java
package JDBC.Util;
import JDBC.Pool.DBConnectionPool;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Properties;
public class JDBCUtil {
private static Properties p = null;
private JDBCUtil(){
}
static {
try{
//1.初始化驱动类,在初始化的时候通过静态代码块中的java.sql.DriverManager.registerDriver(new Driver())注册驱动
ClassLoader loader = Thread.currentThread().getContextClassLoader();
InputStream inputStream = loader.getResourceAsStream("db.properties");
p = new Properties();
p.load(inputStream);
Class.forName(p.getProperty("driverClassName"));
}catch (Exception e){
e.printStackTrace();
}
}
public static Connection getConnection(){
try{
//2.获取数据库连接
// return DriverManager.getConnection(p.getProperty("url"),p.getProperty("username"),p.getProperty("password"));
return DBConnectionPool.getInstance().getConnection();
}catch (Exception e){
e.printStackTrace();
}
return null;
}
public static void close(ResultSet rs, Statement st, Connection connection){
//释放资源
try{
if(rs != null){
rs.close();
}
if (st != null){
st.close();
}
if(connection!=null){
DBConnectionPool.getInstance().freeConnection(connection);
}
}catch (Exception e){
e.printStackTrace();
}
}
}
- IRowMapper.java
package JDBC.Util;
import java.sql.ResultSet;
import java.util.List;
public interface IRowMapper<T> {
T mapping(ResultSet rs) throws Exception;
}
- JDBCTemplate.java
package JDBC.Util;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
public class JDBCTemplate {
public static void update(String sql,Object... params){
Connection connection = null;
PreparedStatement ps = null;
ResultSet rs = null;
try{
connection = JDBCUtil.getConnection();
ps = connection.prepareStatement(sql);
for(int i=0;i<params.length;i++){
ps.setObject(i+1,params[i]);
}
ps.executeUpdate();
}catch (Exception e){
e.printStackTrace();
}finally {
JDBCUtil.close(rs,ps,connection);
}
}
public static <T> T query(String sql,IRowMapper<T> rsh,Object... params){
Connection connection = null;
PreparedStatement ps = null;
ResultSet rs = null;
try{
connection = JDBCUtil.getConnection();
ps = connection.prepareStatement(sql);
for(int i=0;i<params.length;i++){
ps.setObject(i+1,params[i]);
}
rs = ps.executeQuery();
return rsh.mapping(rs);
}catch (Exception e){
e.printStackTrace();
}finally {
JDBCUtil.close(rs,ps,connection);
}
return null;
}
}
- StudentDao.java
package dao;
import JDBC.Util.IRowMapper;
import JDBC.Util.JDBCTemplate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import pojo.Student;
import java.sql.*;
import java.util.List;
public class StudentDao {
// private Logger logger = LoggerFactory.getLogger(StudentDao.class);
//添加学生信息
public void add(Student stu){
String sql = "insert into t_student(name,age) values(?,?)";
Object[] params = new Object[]{
stu.getName(),stu.getAge()};
JDBCTemplate.update(sql,params);
}
//删除学生信息
public void delete(int id){
String sql = "delete from t_student where id=?";
JDBCTemplate.update(sql,id);
}
//修改学生信息
public void update(Student stu){
String sql = "update t_student set name =?,age=? where id=?";
Object[] params = new Object[]{
stu.getName(),stu.getAge(),stu.getId()};
JDBCTemplate.update(sql,params);
}
//查询
public Student get(int id){
String sql = "select * from t_student where id=?";
List<Student> list = JDBCTemplate.query(sql, new StudentRowMapper(),id);
return list.size()>0?list.get(0):null;
}
//查询
public List<Student> list(){
String sql = "select * from t_student";
return JDBCTemplate.query(sql,new StudentRowMapper());
}
public int getCount(){
String sql = "select count(*) total from t_student";
int totalCount = (int)JDBCTemplate.query(sql, new IRowMapper<Integer>() {
public Integer mapping(ResultSet rs) throws Exception{
Integer totalCount = null;
if(rs.next()){
totalCount = rs.getInt("total");
}
return totalCount;
}
});
return totalCount;
}
}
- StudentRowMapper.java
package dao;
import JDBC.Util.IRowMapper;
import pojo.Student;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;
public class StudentRowMapper implements IRowMapper<List<Student>> {
public List<Student> mapping(ResultSet rs) throws Exception {
List<Student> list = new ArrayList<Student>();
while(rs.next()){
int id = rs.getInt("id");
String name = rs.getString("name");
int age = rs.getInt("age");
Student stu = new Student(id,name,age);
list.add(stu);
}
return list;
}
}
- 测试代码
import dao.StudentDao;
public class ExectorThread extends Thread {
@Override
public void run() {
StudentDao stuDao = new StudentDao();
System.out.println("线程" + this.getName() + " " + stuDao.list());
}
}
import dao.StudentDao;
public class TestApi {
public static void main(String[] args) {
for(int i = 0;i<200000;i++){
Thread t = new Thread(new ExectorThread());
t.setName(""+i);
t.start();
}
// System.out.println("End");
// StudentDao stuDao = new StudentDao();
// stuDao.add(new Student(19,"bbb"));
// System.out.println(stuDao.list());
// System.out.println(stuDao.getCount());
// System.out.println(stuDao.get(2).getName());
// stuDao.add(new Student(18,"aaa"));
// stuDao.update(new Student(19,"aaa",1));
// stuDao.delete(1);
}
}