本文最后更新于:4 个月前
package utils;
import java.sql.*;
/**
* @Classname JdbcUtils
* @Description JDBC的工具类。(尽量用单例模式)
* @Created by melodyjerry
*/
public class JdbcUtil {
private static final String driverName = "com.mysql.jdbc.Driver";
// 数据库连接路径
private static final String URL = "jdbc:mysql://localhost:3306/librarysystem?" //127.0.0.1
+ "useUnicode = true & serverTimezone = GMT"
// MySQL在高版本需要指明是否进行SSL连接
+ "& characterEncoding = utf8 & useSSL = false";
private static final String userName = "root";
private static final String userPassword = "root";
private static Connection dbConn = null;
private static Statement stmt;
private static JdbcUtil utils = null;
// 预编译语句
private static PreparedStatement pstmt = null;
/**
* 不是线程安全的
* 如果有并发访问实例化的时候会出现线程安全的问题
* 解决办法加同步锁synchronized
*/
public synchronized static JdbcUtil getJdbcUtil() {
if (utils == null) {
utils = new JdbcUtil();
return utils;
}
return utils;
}
/**
* 静态代码块
* 将加载驱动、连接数据库放入静态块中
*/
static {
if (dbConn == null) {
try
{
// 使用Class.forName()方式来加载数据库的驱动类
// Class.forName()是Java提供的一种基于反射的方式,直接根据类的全限定名(包+类)
Class.forName(driverName);
System.out.println("加载驱动成功!");
}catch(Exception e){
e.printStackTrace();
System.out.println("加载驱动失败!");
}
try{
dbConn= DriverManager.getConnection(URL,userName,userPassword);
System.out.println("连接数据库成功!");
}catch(Exception e)
{
e.printStackTrace();
System.out.print("SQL Server连接失败!");
}
}
}
/**
* 对外提供一个方法来获取数据库连接
* @return dbConn
* @throws Exception
*/
public static Connection getConn() throws Exception {
return dbConn;
}
/**
* 创建语句对象
* @return stmt
* @throws Exception
*/
public static Statement getStmt() throws Exception {
if(stmt == null) {
try {
if(dbConn == null) {
dbConn = getConn();
}
stmt = dbConn.createStatement();
} catch (Exception e) {
e.printStackTrace();
}
}
return stmt;
}
/**
* 预编译语句对象
* PreparedStatement对象可以防止sql注入,而Statement不能防止sql注入
* @param sql
* @return
* @throws Exception
*/
public static PreparedStatement getPstmt(String sql) throws Exception {
if(pstmt == null) {
try {
pstmt = dbConn.prepareStatement(sql);
} catch (SQLException e) {
e.printStackTrace();
}
}
return pstmt;
}
/**
* 关闭数据库连接
* @param dbConn
* @throws Exception
*/
public void closeConn(Connection dbConn) throws Exception {
try {
if(dbConn != null)
dbConn.close();
} catch (SQLException e) {
e.printStackTrace();
System.out.print("MySQL数据库关闭失败!");
}
}
/**
* 测试数据库连接、sql操作
* @param args
*/
public static void main(String[] args) {
// 创建实例来测试连接
JdbcUtil jdbcUtil = new JdbcUtil();
try {
getConn(); // jdbcUtil.getConn();
// 基于数据库连接Connection对象,创建SQL语句执行句柄,Statement对象
// prepareStatement对象,就是用来基于底层的Connection代表的数据库连接
// 允许我们通过java程序,通过prepareStatement对象,向MySQL数据库发送SQL语句
// 从而实现通过发送的SQL语句来执行增删改查等逻辑
// 第一个,SQL语句中,值所在的地方,都用问号(?)代表
String sql = "select * from admin where adminName = ? and adminPassword = ?;";
pstmt = dbConn.prepareStatement(sql);
// 第二个,必须调用PreparedStatement的setX()系列方法,对指定的占位符设置实际的值
pstmt.setString(1,"admin");
pstmt.setString(2,"admin");
// Statement.executeQuery()方法,用来执行select语句
// Statement.executeUpdate()方法,就可以用来执行insert、update、delete语句
// executeUpdate()方法,返回类型是个int值,也就是SQL语句影响的行数
// 第三个,执行SQL语句时,直接使用executeQuery()即可,不用传入任何参数
ResultSet rs = pstmt.executeQuery();
// int rsn = pstmt.executeUpdate();
// System.out.println("SQL语句影响了【" + rsn + "】行。");
while(rs.next()){
//打印的就是总记录数。把检索结果看成只有一跳记录一个字段的表
System.out.println(rs.getString(3)+"\t");
}
} catch (SQLException e) {
e.printStackTrace();
System.out.println("sql语句操作失败!"+e.toString());
} catch (Exception e) {
e.printStackTrace();
System.out.println("存在异常!"+e.toString());
}finally {
try {
// 最后一定要记得在finally代码块中,尽快在执行完SQL语句之后,就释放数据库连接
if (pstmt != null){
pstmt.close();
}
if (dbConn !=null){
dbConn.close();
}
}catch (Exception e){
e.printStackTrace();
}
}
}
}
参考资料:
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!