JDBC
一. 简介:
JDBC :Java Database Connectivity Java数据库连接,Java语言操作数据库
* 本质:使用统一的一套可以操作所有关系型数据库的规则(接口),不同数据库厂商实现这套接口,提供数据库驱动jar包。
* 使用接口编程,执行的代码是驱动jar包中的实现类。
* 基本步骤: 1.导入驱动jar包(复制到包;右键Add as Library);
* 2注册驱动;
* 3获取数据库连接对象Connection;
* 4定义sql;
* 5.获取执行sql语句的对象Statement
* 6.执行sql,接受返回结果;
* 7.处理结果
* 8.释放资源
二. 对象:
1. DriverManager:驱动管理对象;
* 负责注册驱动:static void registerDriver(Driver driver) ,注册与给定的驱动程序DriverManager
* Class.forName("com.MysqL.jdbc.Driver"); 其中存在:
* static {
* try {
* java.sql.DriverManager.registerDriver(new Driver());
* } catch (sqlException E) {
* throw new RuntimeException("Can't register driver!");
* }
* }
* 获取数据库连接
* Static Connection getConnection(String url,String user,String password)
* url:指定连接路径 jdbc:MysqL:// ip:port / db_name ,若为本机3306,可简写去掉 ip:port
2. Connection:数据库连接对象
* 1.获取执行sql对象:
* Statement createStatement()
* PreparedStatement prepareStatement(String sql)
* 2.管理事务:
* 开启事务:setAutoCommit(boolean autoCommit) false为开启事务
* 提交事务:commit()
* 回滚事务:rollback()
3. Statement:执行sql对象
* boolean execute(String sql),执行任意sql
* int executeUpdate(String sql):执行DML(列 insert update delete),DDL(表库create,alter,drop)。
* 返回值int代表影响的行数 ,>0则成功
* ResultSet executeQuery (String sql)
4. ResultSet:结果集对象,封装查询结果
* next(): 游标向下移动一行
* getType();获取数据 。
* 如:getInt,getString
* 参数:
* 1.int: getString(1),代表列的编号,从1开始
* 2.String: getDouble(""),代表列的名称
*
5. PreparedStatement:执行sql对象
* 1.sql注入:拼接sql时,有一些sql参与特殊关键字参与字符串的拼接,造成安全性问题
* 2.解决sql注入,使用PreparedStatement对象来解决; 同时效率更高
* 3.预编译的sql,参数使用占位符?
* 4.步骤:
* * 1.导入驱动jar包(复制到包;右键Add as Library);
* * 2注册驱动;
* * 3获取数据库连接对象Connection;
* * 4定义sql:sql参数使用占位符?,
* PrepareStatement Connection.prepareStatement(String sql)
* 给?赋值 setXXX(参数1,参数2) 参数X与?的位置对应
* * 5.获取执行sql语句的对象Statement
* * 6.执行sql,接受返回结果;
* * 7.处理结果
* * 8.释放资源
三. 操作
1. 操作表对象:
(1)account
id NAME balance
------ ------ ---------
1 张三 2000
2 李四 2000
Field | Type |
id | int(11) NOT NULL |
NAME | varchar(10) NULL |
balance | double NULL |
(2)users
id name password email
------ ------ -------- -------------------
1 User1 1234 1234@qq.com
2 User2 5678 5678@qq.com
Field | Type |
id | int(10) NOT NULL |
name | varchar(25) NULL |
password | varchar(25) NULL |
varchar(25) NULL |
2. 基本流程
public class JDBC {
public static void main(String[] args) throws Exception {
// 注册驱动
Class.forName("com.MysqL.jdbc.Driver");
// 获取对象
Connection conn=DriverManager.getConnection("jdbc:MysqL://localhost:3306/jdbcdemo","root","root");
// 定义语句
String sql="update account set balance=1550 where id=1";
// 获取执行对象
Statement sta=conn.createStatement();
// 执行
int count=sta.executeUpdate(sql);
System.out.println(count);
// 释放资源(执行对象,连接对象)
sta.close();
conn.close();
}
}
3. 写法优化(封装方法)
(1)创建account类
public class account {
private int id;
private String name;
private int balance;
@Override
public String toString() {
return "account{" +
"id=" + id +
", name='" + name + '\'' +
", balance=" + balance +
'}';
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getBalance() {
return balance;
}
public void setBalance(int balance) {
this.balance = balance;
}
}
(2)JDBCUtils
public class JDBCUtils {
private static String url;
private static String user;
private static String password;
private static String driver;
static {
// 读取资源文件,获取值
try {
// 创建集合类
Properties pro=new Properties();
// 获取src路径下的文件方式ClassLoader类加载器
ClassLoader classLoader = JDBCUtils.class.getClassLoader();
URL resource = classLoader.getResource("JDBC.properties");
String path = resource.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 e) {
e.printstacktrace();
} catch (ClassNotFoundException e) {
e.printstacktrace();
}
}
// 连接对象
public static Connection getConnection() throws sqlException {
return DriverManager.getConnection(url,user,password);
}
// 释放资源
public static void close(ResultSet rs1,Statement stat1, Connection conn1){
if(rs1!=null)
{
try {
rs1.close();
} catch (sqlException e) {
e.printstacktrace();
}
}
if(stat1!=null){
try {
stat1.close();
} catch (sqlException e) {
e.printstacktrace();
}
}
if (conn1!=null){
try {
conn1.close();
} catch (sqlException e) {
e.printstacktrace();
}
}
}
}
(3)JDBC.properties
url=jdbc:MysqL:///jdbcdemo
user=root
password=root
driver=com.MysqL.jdbc.Driver
public class JDBCAccount {
public static void main(String[] args) {
List<account> list=new JDBCAccount().findAll();
System.out.println(list);
}
public List<account> findAll() {
Connection conn=null;
Statement stat=null;
ResultSet rs=null;
List<account> list=new ArrayList<>();
try {
//连接--初始操作
// Class.forName("com.MysqL.jdbc.Driver");
// conn=DriverManager.getConnection("jdbc:MysqL:///jdbcdemo","root","root");
//连接--使用工具类方法
conn=JDBCUtils.getConnection();
String sql ="select * from account";
stat=conn.createStatement();
rs=stat.executeQuery(sql);
account acont=null;
//查询所有信息
while (rs.next()){
//获取列信息
int id=rs.getInt("id");
String name=rs.getString("name");
int balance=rs.getInt("balance");
//创建account对象
acont=new account();
//为对象赋值
acont.setId(id);
acont.setBalance(balance);
acont.setName(name);
//将赋值对象添加到list中
list.add(acont);
}
} catch ( sqlException e) {
e.printstacktrace();
} finally {
//释放资源
JDBCUtils.close(rs,stat,conn);
//不使用工具类中方法,分别释放资源
// if(stat!=null)
// {
// try {
// stat.close();
// } catch (sqlException e) {
// e.printstacktrace();
// }
// }
// if(conn!=null)
// {
// try {
// conn.close();
// } catch (sqlException e) {
// e.printstacktrace();
// }
// }
// if(rs!=null)
// {
// try {
// rs.close();
// } catch (sqlException e) {
// e.printstacktrace();
// }
// }
//
}
//返回存储了acount对象的列表
return list;
}
}
4.登陆练习
* 需求:
* 1.通过键盘录入用户名和密码
* 2.判断用户是否与表中信息匹配
ublic class JDBCPrac1 {
public static void main(String[] args) {
String uname;
String upd;
System.out.println("请输入用户名:");
Scanner sc=new Scanner(system.in);
uname=sc.next();
System.out.println("请输入密码:");
Scanner sc1=new Scanner(system.in);
upd=sc1.next();
if(login(uname,upd)){
System.out.println("登录成功");
}
else{
System.out.println("密码与账号不匹配");
}
}
/**
* 登录判断
*
*/
public static boolean login(String username, String psd){
if(username==null||psd==null){
return false;
}
Connection conn=null;
Statement statement=null;
PreparedStatement preparedStatement=null;
ResultSet resultSet=null;
try {
// 获取连接
conn = JDBCUtils.getConnection();
// 未防止注入
// String sql="select * from users where name='"+username+"'and password='"+psd+"'";
// statement = conn.createStatement();
// resultSet = statement.executeQuery(sql);
// 使用preparedStatement防止注入攻击
String sql2="select * from users where name=?and password=?";
preparedStatement = conn.prepareStatement(sql2);
// 为?赋值
preparedStatement.setString(1,username);
preparedStatement.setString(2,psd);
resultSet=preparedStatement.executeQuery();
return resultSet.next();
} catch (sqlException e) {
e.printstacktrace();
}
finally {
// 关闭非PreparedStatement对象
// JDBCUtils.close(resultSet,statement,conn);
JDBCUtils.close(resultSet,preparedStatement,conn);
}
return false;
}
}
5. JDBC事务
public class JDBCTransaction {
public static void main(String[] args) {
double balance1;
int id1;
double balance2;
int id2;
transac(500,500,1,2);
System.out.println("Over....");
}
public static void transac (double balance1,double balance2, int id1, int id2){
Connection conn = null;
PreparedStatement ps = null;
try {
//获取连接对象
conn = JDBCUtils.getConnection();
// 开启事务
conn.setAutoCommit(false);
// 定义sql
String sql1 = "update account set balance= balance-? where id=?";
String sql2 = "update account set balance= balance+? where id=?";
// 执行sql语句
ps = conn.prepareStatement(sql1);
// 对PreparedStatement对象进行赋值
ps.setDouble(1, balance1);
ps.setInt(2, id1);
// 完成更新
ps.executeUpdate();
System.out.println("语句1更新成功");
// 手动异常,使其无法顺利执行sql2。
int i=3/0;
ps = conn.prepareStatement(sql2);
ps.setDouble(1, balance2);
ps.setInt(2, id2);
ps.executeUpdate();
System.out.println("语句2更新成功");
// 提交事务
conn.commit();
} catch (Exception e) {
// 有异常则回滚
try {
if(conn!=null)
conn.rollback();
} catch (sqlException ex) {
ex.printstacktrace();
}
e.printstacktrace();
System.out.println("更新失败,已回滚");
}
finally{
JDBCUtils.close(null,ps,conn);
}
}
}