Java数据库连接,(Java Database Connectivity,简称JDBC)是Java语言中用来规范客户端程序如何来访问数据库的应用程序接口,提供了诸如查询和更新数据库中数据的方法。JDBC也是Sun Microsystems的商标。我们通常说的JDBC是面向关系型数据库的。
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
public class JdbcDemo {
public static void main(String[] args) throws Exception {
//注册驱动
Class.forName("com.mysql.jdbc.Driver");
//获取数据连接对象
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/root?serverTimezone=UTC","root","123456");
//定义sql语句
String sql = "update user set password = '123' where id =1";
//获取sql对象Statement
Statement stmt = conn.createStatement();
//执行sql
stmt.executeUpdate(sql);
//释放资源
stmt.close();
conn.close();
}
}
DriverManage的主要作用是注册驱动,即告诉程序使用哪一个数据库驱动jar
从Driver的源码文件中可以看出其在静态代码块执行驱动注册
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//
package com.mysql.cj.jdbc;
import java.sql.DriverManager;
import java.sql.SQLException;
public class Driver extends NonRegisteringDriver implements java.sql.Driver {
public Driver() throws SQLException {
}
static {
try {
DriverManager.registerDriver(new Driver());
} catch (SQLException var1) {
throw new RuntimeException("Can't register driver!");
}
}
}
DriverManage的第二个作用是获取数据库连接
通过getConnection(String url,String user, String password)方法获取数据库连接
参数包括:
url:指定连接的路径
user:用户名
password:密码
@CallerSensitive
public static Connection getConnection(String url,
String user, String password) throws SQLException {
java.util.Properties info = new java.util.Properties();
if (user != null) {
info.put("user", user);
}
if (password != null) {
info.put("password", password);
}
return (getConnection(url, info, Reflection.getCallerClass()));
}
Connection的主要作用获取执行sql的对象并管理事务
可以形象的理解Connection的作用是建桥,建立Java和数据库的连接,Statement的作用是执行事务,形象理解为派个人过桥,提着篮子,去拿数据
实现代码:Statement stmt = conn.createStatement();
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
public class JdbcDemo {
public static void main(String[] args){
Statement stmt = null;
Connection conn = null;
try {
Class.forName("com.mysql.jdbc.Driver");
String sql = "insert into user (username, password) values ('admin','789')";
conn = DriverManager.getConnection("jdbc:mysql:///root?serverTimezone=UTC","root","123456");
stmt = conn.createStatement();
int count = stmt.executeUpdate(sql);
if(count>0){
System.out.println("添加成功");
}else {
System.out.println("添加失败");
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException exception) {
exception.printStackTrace();
}finally {
if(stmt!=null){
try {
stmt.close();
} catch (SQLException exception) {
exception.printStackTrace();
}
}
if(conn!=null){
try {
conn.close();
} catch (SQLException exception) {
exception.printStackTrace();
}
}
}
}
}
import javax.xml.transform.Result;
import java.sql.*;
public class JdbcDemo {
public static void main(String[] args){
Statement stmt = null;
Connection conn = null;
ResultSet rs = null;
try {
Class.forName("com.mysql.jdbc.Driver");
String sql = "select * from user ";
conn = DriverManager.getConnection("jdbc:mysql:///root?serverTimezone=UTC","root","123456");
stmt = conn.createStatement();
rs = stmt.executeQuery(sql);
rs.next();
int id = rs.getInt(1);
String username = rs.getString("username");
String password = rs.getString("password");
System.out.println(id+"---"+username+"---"+password);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException exception) {
exception.printStackTrace();
}finally {
if(rs!=null){
try {
rs.close();
} catch (SQLException exception) {
exception.printStackTrace();
}
}
if(stmt!=null){
try {
stmt.close();
} catch (SQLException exception) {
exception.printStackTrace();
}
}
if(conn!=null){
try {
conn.close();
} catch (SQLException exception) {
exception.printStackTrace();
}
}
}
}
}
下面是一个简单的jdbc-demo,相比于上一个demo,这个demo增加了 while (rs.next())使得每条查询记录都能打印出来(上一个demo只能打印一条查询记录)
import javax.xml.transform.Result;
import java.sql.*;
public class JdbcDemo {
public static void main(String[] args){
Statement stmt = null;
Connection conn = null;
ResultSet rs = null;
try {
Class.forName("com.mysql.jdbc.Driver");
String sql = "select * from user ";
conn = DriverManager.getConnection("jdbc:mysql:///root?serverTimezone=UTC","root","123456");
stmt = conn.createStatement();
rs = stmt.executeQuery(sql);
while (rs.next()){
int id = rs.getInt(1);
String username = rs.getString("username");
String password = rs.getString("password");
System.out.println(id+"---"+username+"---"+password);
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException exception) {
exception.printStackTrace();
}finally {
if(rs!=null){
try {
rs.close();
} catch (SQLException exception) {
exception.printStackTrace();
}
}
if(stmt!=null){
try {
stmt.close();
} catch (SQLException exception) {
exception.printStackTrace();
}
}
if(conn!=null){
try {
conn.close();
} catch (SQLException exception) {
exception.printStackTrace();
}
}
}
}
}
下面是一个简单的jdbc-demo,相比于上一个demo,这个demo增加了 user类,对于user表,将查询的数据封装为对象装载进入集合
public class User {
private int id;
private String username;
private String password;
public int getId() {
return id;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", password='" + password + '\'' +
'}';
}
public void setId(int id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
public class JdbcDemo2 {
public static void main(String[] args) {
List<User> list = new JdbcDemo2().findAll();
System.out.println(list);
}
public List<User> findAll(){
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
List<User> list = new ArrayList<User>();
try {
Class.forName("com.mysql.jdbc.Driver");
conn = DriverManager.getConnection("jdbc:mysql:///root?serverTimezone=UTC","root","123456");
String sql = "select * from user";
stmt = conn.createStatement();
rs = stmt.executeQuery(sql);
while (rs.next()){
int id = rs.getInt("id");
String username = rs.getString("username");
String password = rs.getString("password");
User user = new User();
user.setId(id);
user.setUsername(username);
user.setPassword(password);
list.add(user);
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException exception) {
exception.printStackTrace();
}finally {
if(rs!=null){
try {
rs.close();
} catch (SQLException exception) {
exception.printStackTrace();
}
}
if(stmt!=null){
try {
stmt.close();
} catch (SQLException exception) {
exception.printStackTrace();
}
}
if(conn!=null){
try {
conn.close();
} catch (SQLException exception) {
exception.printStackTrace();
}
}
}
return list;
}
}
详细的内容可以查看我的另一篇博文sql注入问题
以上的代码重复度过高,所以我们需要抽取方法,简化书写,首先将一些惯用的常量放在配置文件druid.properties中
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/root?serverTimezone=UTC
username=root
password=123456
下面是工具类的书写,值得关注的是类加载器ClassLoader的使用
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.net.URL;
import java.sql.*;
import java.util.Properties;
public class JDBCUtils {
//文件的读取,只需要读取一次即可拿到这些值,使用静态代码块
private static String url;
private static String user;
private static String password;
private static String driver;
static {
try {
//读取资源文件
//创建Properties集合类
Properties pro = new Properties();
//类加载器ClassLoader可以获取src路径下的文件
ClassLoader classLoader = JDBCUtils.class.getClassLoader();
URL res = classLoader.getResource("druid.properties");
String path = res.getPath();
pro.load(new FileReader(path));
url = pro.getProperty("url");
user = pro.getProperty("username");
password = pro.getProperty("password");
driver = pro.getProperty("driver");
//注册驱动
Class.forName(driver);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException exception) {
exception.printStackTrace();
}
}
public static Connection getConnection(){
try {
return DriverManager.getConnection(url,user,password);
} catch (SQLException exception) {
exception.printStackTrace();
}
return null;
}
/** * 释放资源 * @param stmt * @param conn */
public static void close(Statement stmt,Connection conn){
if(stmt!=null){
try {
stmt.close();
} catch (SQLException exception) {
exception.printStackTrace();
}
}
if(conn!=null){
try {
conn.close();
} catch (SQLException exception) {
exception.printStackTrace();
}
}
}
/** * 重载方法 * @param rs * @param stmt * @param conn */
public static void close(ResultSet rs,Statement stmt, Connection conn){
if(rs!=null){
try {
rs.close();
} catch (SQLException exception) {
exception.printStackTrace();
}
}
if(stmt!=null){
try {
stmt.close();
} catch (SQLException exception) {
exception.printStackTrace();
}
}
if(conn!=null){
try {
conn.close();
} catch (SQLException exception) {
exception.printStackTrace();
}
}
}
}
下面是实现类,代码量精简了很多
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
public class JdbcDemo2 {
public static void main(String[] args) {
List<User> list = new JdbcDemo2().findAll();
System.out.println(list);
}
public List<User> findAll(){
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
List<User> list = new ArrayList<User>();
try {
conn = JDBCUtils.getConnection();
String sql = "select * from user";
stmt = conn.createStatement();
rs = stmt.executeQuery(sql);
while (rs.next()){
int id = rs.getInt("id");
String username = rs.getString("username");
String password = rs.getString("password");
User user = new User();
user.setId(id);
user.setUsername(username);
user.setPassword(password);
list.add(user);
}
} catch (SQLException exception) {
exception.printStackTrace();
}finally {
JDBCUtils.close(rs,stmt,conn);
}
return list;
}
}
下面是运用JDBCUtils工具类实现了登录的案例,从键盘录入用户名和密码,通过与数据库内的值进行匹配判断是否能登录
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Scanner;
public class JdbcDemo3 {
public static void main(String[] args) {
//键盘录入。接收用户名和密码
Scanner scanner = new Scanner(System.in);
String username = scanner.nextLine();
String password = scanner.nextLine();
//调用方法
boolean flag = new JdbcDemo3().login(username,password);
//判断结果,输出不同语句
if(flag){
System.out.println("登录成功");
}else {
System.out.println("登录失败");
}
}
/** * 登录方法 * @param username * @param password * @return */
public boolean login(String username,String password){
if(username == null || password == null){
return false;
}
Connection connection = null;
Statement stmt = null;
ResultSet rs = null;
try {
//连接数据库判断是否登录成功
connection = JDBCUtils.getConnection();
//定义sql
String sql = "select * from user where username = '"+username+"' and password = '"+password+"'";
//获取执行sql的对象
stmt = connection.createStatement();
//执行查询
rs = stmt.executeQuery(sql);
//判断
return rs.next();
} catch (SQLException exception) {
exception.printStackTrace();
}finally {
JDBCUtils.close(rs,stmt,connection);
}
return false;
}
}
当我们在执行sql时候,如果在连续执行sql语句过程中出现异常,则会导致执行中断,即后面的sql语句无法执行,为了避免这种情况,我们使用事务管理。
下面是一个demo,在获取连接后开启事务,在sql执行后提交事务,在异常处理中添加事务回滚,如果出现异常通过回滚可以执行被中断的方法
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
public class JdbcDemo4 {
public static void main(String[] args) {
Connection conn = null;
PreparedStatement pstmt1 = null;
PreparedStatement pstmt2 = null;
try {
//获取连接
conn = JDBCUtils.getConnection();
//开启事务
conn.setAutoCommit(false);
//定义sql
String sql1 = "update user set password = ? where id = ?";
String sql2 = "update user set password = ? where id = ?";
//获取执行sql对象
pstmt1 = conn.prepareStatement(sql1);
pstmt2 = conn.prepareStatement(sql2);
//设置参数
pstmt1.setString(1,"yhyhyh");
pstmt1.setInt(2,1);
pstmt2.setString(1,"henrik");
pstmt2.setInt(2,2);
//执行sql
pstmt1.executeUpdate();
pstmt2.executeUpdate();
//提交事务
conn.commit();
} catch (Exception exception) {
//事务回滚
try {
if(conn!=null){
conn.rollback();
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}
exception.printStackTrace();
}finally {
JDBCUtils.close(pstmt1,conn);
JDBCUtils.close(pstmt2,null);
}
}
}
版权说明 : 本文为转载文章, 版权归原作者所有 版权申明
原文链接 : https://blog.csdn.net/qq_50216270/article/details/117082515
内容来源于网络,如有侵权,请联系作者删除!