本质是sun公司制作的一套操作所有关系型数据库的规则,即接口。各个数据库厂商负责实现这些接口,提供响应的数据库驱动jar包,我们可以使用这套接口(JDBC)编程,最终真正执行的是数据库驱动jar包中的实现类
public class JDBCDemo1 {
public static void main(String[] args) throws Exception {
//注册驱动
Class.forName("com.mysql.cj.jdbc.Driver");
//获取数据库连接对象
Connection connection= DriverManager.getConnection("jdbc:mysql://cdb-cd3ybvc6.cd.tencentcdb.com:10056/weixinNews","root","renboyu");
//定义sql语句
String sql="SELECT * FROM WEIBO WHERE TITLE LIKE '%韩国%';";
//获取执行sql的对象Statement
Statement statement=connection.createStatement();
//执行sql语句
ResultSet set=statement.executeQuery(sql);
//打印结果
while (set.next()){
String title=set.getString("TITLE");
System.out.println(title);
}
//释放资源
statement.close();
connection.close();
}
}
(尽量避免直接抛出错误)
public class JDBCDemo2 {
public static void main(String[] args) {
Connection connection=null;
Statement statement=null;
try {
//注册驱动
Class.forName("com.mysql.cj.jdbc.Driver");
//定义sql语句
String sql="insert into stuMess VALUES(null,'Leslie','CS','95');";
//获取数据库连接对象
connection= DriverManager.getConnection("jdbc:mysql://cdb-cd3ybvc6.cd.tencentcdb.com:10056/jdbcTest","root","renboyu010214");
//获取执行sql的对象Statement
statement=connection.createStatement();
//执行sql语句
int result=statement.executeUpdate(sql);
//输出结果
System.out.println(result);
} catch (ClassNotFoundException | SQLException e) {
e.printStackTrace();
}finally {
//释放资源,由于可能出错导致没有成功获取数据库连接对象和Statement,所以要提前检验是否为空
if(statement!=null) {
try {
statement.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if(connection!=null) {
try {
connection.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
}
}
驱动管理对象
注册驱动
DriverManager提供registerDriver方法注册给定的驱动程序,而我们在上面代码中所写的Class.forName("com.mysql.cj.jdbc.Driver");
之所以能注册驱动,是因为将com.mysql.cj.jdbc.Driver加载进了内存,而com.mysql.cj.jdbc.Driver包内存在静态代码块,通过阅读源码可以找到该静态代码块
static {
try {
java.sql.DriverManager.registerDriver(new Driver());
} catch (SQLException E) {
throw new RuntimeException("Can't register driver!");
}
}
可以看到Class.forName("com.mysql.cj.jdbc.Driver");
仍然是通过调用DriverManager提供的registerDriver方法注册驱动程序,只是这种写法比调用方法更加简洁
不过,自5版本后,jar包会自动帮我们注册驱动,所以其实注册驱动步骤可以省略
获取数据库连接
利用DriverManager的getConnection方法可以获取数据库连接,返回数据库连接对象
该方法接收三个参数,分别是
数据库连接对象
获取执行sql语句的对象
管理事务
执行sql语句的对象
执行sql语句
数据库结果集对象
执行sql语句的对象
在拼接sql时,有一些sql的特殊关键字参与字符串拼接,导致安全性问题。例如,下面代码
String userName, password;
String sql="SELECT * FROM loginMess where userName ='"+userName+"' and password='"+password+"';";
假如password处用户传入a' or 'a'='a'
。则整个sql语句变为了SELECT * FROM loginMess where userName ='userName' and password='a' or 'a'='a';
则整个sql语句变为恒等句,用户始终可以登录成功
/**
* 登录案例,使用PreparedStatement实现
*/
public class LoginDemo2 {
public static void login(String userName,String password){
Connection connection=null;
Statement statement=null;
try {
//通过工具类获取数据库连接
connection= JDBCUtils.getConnection();
//定义sql语句
String sql="SELECT * FROM loginMess where userName ='"+userName+"' and password='"+password+"';";
//获取执行sql的对象Statement
statement=connection.createStatement();
//执行sql语句
ResultSet set=statement.executeQuery(sql);
//遍历数据库表,获得所有用户对象
if (set.next()){
System.out.println("登陆成功");
}else {
System.out.println("登陆失败");
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}finally {
//通过工具类关闭资源
JDBCUtils.closeDB(connection,statement);
}
}
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
System.out.println("please input the username:");
String userName=sc.nextLine();
System.out.println("please input the password:");
String password=sc.nextLine();
login(userName,password);
}
}
使用PreparedStatement对象来执行sql语句,PreparedStatement对象执行预编译的sql语句,所有参数使用“?”作为占位符。借此可解决sql诸如问题
可以避免sql诸如问题
/**
* 登录案例,使用PreparedStatement实现
*/
public class LoginDemo2 {
public static void login(String userName,String password){
Connection connection=null;
PreparedStatement preSta=null;
ResultSet set=null;
try {
//通过工具类获取数据库连接
connection= JDBCUtils.getConnection();
//定义sql语句,所有变量用通配符?代替
String sql="SELECT * FROM loginMess where userName =? and password=?;";
//获取执行sql的对象PreparedStatement
preSta=connection.prepareStatement(sql);
//给?赋值
preSta.setString(1,userName);
preSta.setString(2,password);
//执行sql语句(不需要传参)
set=preSta.executeQuery();
//遍历数据库表,获得所有用户对象
if (set.next()){
System.out.println("登陆成功");
}else {
System.out.println("登陆失败");
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}finally {
//通过工具类关闭资源
JDBCUtils.closeDB(set,connection,preSta);
}
}
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
System.out.println("please input the username:");
String userName=sc.nextLine();
System.out.println("please input the password:");
String password=sc.nextLine();
login(userName,password);
}
}
/**
* JDBC工具类
*/
public class JDBCUtils {
//定义各个静态遍历
private static String url;
private static String user;
private static String password;
private static String driver;
/**
* 静态代码块,只在创建时调用一次
* 可以在此处进行配置文件的读取,以及驱动注册等步骤
*
* 将url,user,password,driver等变量
* 存入配置文件并读取可以提高代码复用性
*/
static {
try {
//创建配置文件数据集
Properties pro=new Properties();
//创建类加载器classLoader
ClassLoader classLoader=JDBCUtils.class.getClassLoader();
//通过类加载器获取在src下的配置文件,这样可以避免绝对路径带来的问题
URL res=classLoader.getResource("jdbc.properties");
String path=res.getPath();
//加载配置文件
pro.load(new FileReader(path));
//获取配置文件中的数据
url=pro.getProperty("url");
user=pro.getProperty("user");
password=pro.getProperty("password");
driver=pro.getProperty("driver");
//注册驱动
Class.forName(driver);
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
}
/**
* 获取数据库连接
* @return 数据库连接
* @throws SQLException
*/
public static Connection getConnection() throws SQLException {
return DriverManager.getConnection(url,user,password);
}
/**
* 关闭数据库相关资源
* @param rs ResultSet数据库结果集对象
* @param connection 数据库连接对象
* @param statement sql语句执行对象
*/
public static void closeDB(ResultSet rs,Connection connection,Statement statement){
if(rs!=null){
try {
rs.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if(statement!=null){
try {
statement.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if(connection!=null){
try {
connection.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
/**
* 关闭数据库相关资源
* @param connection 数据库连接对象
* @param statement sql语句执行对象
*/
public static void closeDB(Connection connection,Statement statement){
if(statement!=null){
try {
statement.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if(connection!=null){
try {
connection.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
}
url=jdbc:mysql://cdb-cd3ybvc6.cd.tencentcdb.com:10056/weixinNews
user=root
password=rby
driver=com.mysql.cj.jdbc.Driver
public class JDBCDemo3 {
public static void main(String[] args) {
Connection connection=null;
Statement statement=null;
try {
//通过工具类获取数据库连接
connection= JDBCUtils.getConnection();
//定义sql语句
String sql="SELECT * FROM WEIBO WHERE TITLE LIKE '%韩国%';";
//获取执行sql的对象Statement
statement=connection.createStatement();
//执行sql语句
ResultSet set=statement.executeQuery(sql);
//打印结果
while (set.next()){
String title=set.getString("TITLE");
System.out.println(title);
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}finally {
//通过工具类关闭资源
JDBCUtils.closeDB(connection,statement);
}
}
}