JDBC的介绍
概念
JDBC全称 Java Database Connectivity ,是使用Java语言操作数据库的方法。JDBC其实是官方(sun)定义的一套操作所有关系数据可得规则,即接口。各个数据库厂商去实现接口,提供数据库驱动jar包。我们可以使用这套接口(JDBC)编程,真正执行的代码是驱动jar包中的实现类。
JDBC使用快速入门
步骤:
1.导入驱动jar包
*复制我们的驱动jar包到项目的libs(自建目录)下
*右键自建目录->add as library
2.注册驱动
3.获取数据库的Connection对象
4.定义sql语句
5.获取执行sql语句的对象Statement
6.执行sql,接收返回的结果
7.处理结果
8.释放资源
实例代码:
package com.learn.jdbc;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
/*
account表添加一条信息
*/
public class demo02try {
public static void main(String[] args) {
Statement stat=null;
Connection conn=null;
try {
//1.注册驱动
Class.forName("com.mysql.jdbc.Driver");
//2.定义sql
String sql="insert into account (name,money) values('wang',300)";
//3.获取Connection的对象
conn= DriverManager.getConnection("jdbc:mysql://localhost:3306/data01","root","root");
//获取执行sql的Statement对象
stat =conn.createStatement();
//执行sql
int count =stat.executeUpdate(sql);//返回影响的行数
//6.处理结果
if(count>0){
System.out.println("添加成功");
}else {
System.out.println("添加失败");
}
} catch (ClassNotFoundException | SQLException e) {
e.printStackTrace();
}finally {
//7.释放资源
//避免空指针异常
if(stat!=null)
{
try {
stat.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if(conn!=null)
{
try {
conn.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
}
}
JDBC对象介绍
DriverManager:驱动管理对象
DriverManager功能:
1.注册驱动:告诉程序该使用哪一个数据库驱动jar。但在mysql5之后版本jdbc会自动注册,不需要写这句代码。
static void registerDriver(Driver driver):注册与给定的驱动DriverManage。
写代码使用:Class.forName("com.mysql.jdbc.Driver");
通过查看Driver.java:发现在com.mysql.jdbc.Driver类中存在静态代码块:
static {
try {
DriverManager.registerDriver(new Driver());
} catch (SQLException var1) {
throw new RuntimeException("Can't register driver!");
}
}
真正注册驱动的是DriverManager.registerDriver(new Driver()
2.获取数据库连接:
方法:
Static public static Connection getConnection(String url,String user, String password)静态方法,通过类名进行调用即可
参数:
url:指定连接的路径:ip可以指定是拿一台计算机上的数据库,端口号可以在该计算机中找到数据库
*语法:jdbc:mysql://ip地址(域名):端口号/数据库名称
*例子:jdbc:mysql://localhost(127.0.0.1):3306/data01
*细节:如果连接的是本机的mysql服务器,并且mysql的默认端口号是3306,则url可以简写成:jdbc:mysql:///数据库名称
user:用户名
password:密码
Connection:数据库管理对象
Connection.功能
1.获取执行sql的对象
*Statement createStatement() 获取Statement对象
*PreparedStatement prepareStatement(String sql) 获取PrepareStatement对象
2.管理事务:
*开启事务:void setAutoCommit(boolean autoCommit); 调用该方法设置参数false,即开启事务。
*提交事务:void commit()
*回滚事务:void rollback()
Statement:执行sql对象
功能:执行sql
1.boolean execute(String sql):可以执行任意的sql,并不多用作为了解。
2.int executeUpdate(String sql):执行的是DML(insert,update,delete)语句,DDL(create,alter,drop)语句
*返回值:影响的行数,可以通过影响的行数判断sql语句执行是否成功,返回值>0则成功
3.ResultSet executeQuery(String sql):执行DQL(select)语句,返回的类型是结果集
ResultSet:结果集对象
ResultSet方法介绍:
1.Boolean next()方法:游标向下移动一行,判断当前是否为最后一行(是否有数据)
2.getXxx(c参数):获取数据
1.Xxx代表数据类型 如:int getInt();
2.参数
Int:代表类的编号,从1开始,如:getInt(1)
String:代表列名称,如:getString("name");
在进行结果集的展示时我们可以按照查询获取的数据进行对象的封装,然后将获取的所有对象集合成列。
PrepareStatement://执行sql对象
1.sql注入问题:在拼接sql时,有一些sql的关键字参与字符串的拼接,造成安全问题
随便输入用户名,a' or 1=1
sql语句就变成了:select * for user where username='aaaaaa' and password='a' or 1=1;
2.解决sql注入问题:使用PrepareStatement对象来解决
3.预编译的sql:参数使用?作为占位符
4.步骤:
1.导入驱动jar包
2.注册驱动
3.获取数据库的Connection对象
4.定义sql语句
注意sql语句使用?作为占位符。如:select * for user where username=? and password=?
5.获取执行sql语句的对象PrepareStatement PreparedStatement prepareStatement(String sql)
6.给?赋值
*方法 :setXxx(参数1,参数2):参数1是问号的位置,参数2是问号的值
7.执行sql语句
8.处理结果
9.释放资源
后期都会使用PreparedStatement来完成增删改查的所有操作,这种方式就可以防止sql注入效率也会更高。
JDBC简化操作——抽取工具类
在编写进行操作数据库的代码时,我们每个类进行链接数据库和释放资源等都要进行代码编写这无疑大大增加了我们的代码编写负担。我们可以将重复的代码抽出来,封装成一个独立的方法。这样每次我们创建链接只要调用方法就可以了。
1.编写数据库配置文件
url=jdbc:mysql://localhost:3306/data01
user=root
password=root
driver=com.mysql.jdbc.Driver
2.编写数据库连接方法
package com.learn.util;
import java.io.FileReader;
import java.io.IOException;
import java.net.URI;
import java.net.URL;
import java.sql.*;
import java.util.Properties;
/*
jdbc工具类
读取配置文件,我们希望只要读取一次,所以我们用静态代码块
*/
public class JDBCuril {
//只有静态变量才能被静态代码块调用
private static String url;
private static String user;
private static String password;
private static String driver;
public static Connection getConnection() throws SQLException {
return DriverManager.getConnection(url,user,password);
}
static {
try {
//读取资源文件,获取值
//1.创建properties集合类
Properties pro=new Properties();
//获取src路径下的文件方式-->ClassLoader 类加载器 ,加载字节码文件进内存。
ClassLoader classLoader=JDBCuril.class.getClassLoader();
//获取ULRL
URL res= classLoader.getResource("jdbc.properties");
//URL转化为String字符类型
String path= res.getPath();
//2.加载文件
pro.load(new FileReader(path));
url=pro.getProperty("url");
user=pro.getProperty("user");
password=pro.getProperty("password");
driver=pro.getProperty("driver");
try {
Class.forName(driver);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
} catch (IOException e) {
e.printStackTrace();
}
}
//释放资源1
public static void close(Statement statement,Connection connection){
if(statement!=null){
try {
statement.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if(connection!=null){
try {
connection.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
//方法重载,第二种释放方法
public static void close(ResultSet resultSet, Statement statement, Connection connection){
if(resultSet!=null){
try {
resultSet.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();
}
}
}
//方法重载,第三种释放方法
public static void close(ResultSet resultSet, PreparedStatement statement, Connection connection){
if(resultSet!=null){
try {
resultSet.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();
}
}
}
}
3.在主方法中进行调用
package com.learn.jdbc;
import com.learn.util.JDBCuril;
import java.sql.*;
public class demo07select {
public static void main(String[] args) {
Statement stat=null;
Connection conn=null;
ResultSet re=null;
try {
conn=JDBCuril.getConnection();
String sql="select * from account ";
stat=conn.createStatement();
//5.执行sql,并接受返回值
re= stat.executeQuery(sql);
//6.处理数据
while(re.next()) {
int i = re.getInt("id");
String name = re.getString("name");
double b = re.getDouble("money");
System.out.println("账号:" + i + " " + "姓名" + name + " " + "余额" + " " + b);
}
} catch (SQLException e) {
e.printStackTrace();
}finally {
//7.资源关闭
JDBCuril.close(re,stat,conn);
}
}
}
JDBC控制事务
.事务:一个包含多个业务的操作。如果这个业务被事务管理,则这多个步骤要么同时成功要么同时失败。
使用Connection对象来管理事务
1.开启事务:setAutoCommit(Boolean autocommit)
*在执行sql前开启事务
2.提交事务:commit()
*在执行完所有sql后提交事务
3.管理事务:rollback()
*在catch中进行回滚
转账事务的实现实例:
package com.learn.jdbc;
import com.learn.util.JDBCuril;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
/*
事务的操作
*/
public class demo10 {
public static void main(String[] args) {
Connection conn=null;
PreparedStatement ps1=null;
PreparedStatement ps2=null;
try {
//1.获取链接
conn= JDBCuril.getConnection();
//开启事务
conn.setAutoCommit(false);
//2.定义sql
//张三-500
String sql1="update account set money =money-? where id=?";
//李四+500
String sql2="update account set money =money+? where id=?";
ps1=conn.prepareStatement(sql1);
ps2=conn.prepareStatement(sql2);
//4.设置参数
ps1.setDouble(1,500);
ps1.setInt(2,1);
ps2.setDouble(1,500);
ps2.setInt(2,2);
ps1.executeUpdate();
//手动制造异常
int i=3/0;
ps2.executeUpdate();
//事务提交
conn.commit();
} catch (Exception throwables) {
try {
if(conn!=null) {
//事务回滚
conn.rollback();
}
} catch (SQLException e) {
e.printStackTrace();
}
throwables.printStackTrace();
}finally {
JDBCuril.close(ps1,conn);
JDBCuril.close(ps2,null);
}
}
}