JDBC
JDBC:Java与数据库的连接技术,是Java语言中用来规范客户端程序如何来访问数据库的应用程序接口,提供了诸如查询和更新数据库中数据的方法
步骤
前提:准备MySQL的驱动包,加载到项目里
-
加载驱动
-
获取连接
-
执行增删改查操作
-
关闭连接
以下是删除
package test;
import org.gjt.mm.mysql.Driver;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
public class Test {
public static void main(String[] args) throws SQLException {
//1.加载驱动
DriverManager.registerDriver(new Driver());
//获取连接
Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/school?characterEncoding=UTF-8", "root", "root");
System.out.println("连接成功");
//执行增删改查
/*
* 编写SQL语句
* 执行SQL语句
* 获取执行SQL语句的对象
*使用命令对象指向SQL语句
* 处理执行结果
* 关闭连接*/
//删除 :String sql="delete from student where id=15";
//更新:String sql="update student set name='四宫辉夜'where id=13 ";
//增加
String sql ="insert into student values(null,'hanser','女','2010-10-14',4500) ";
Statement statement = connection.createStatement();
int i = statement.executeUpdate(sql);
System.out.println(i>0?"成功":"失败");
statement.close();
connection.close();
}
}
字节符在idea中和MySQL中的不同,在
Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/school?characterEncoding=UTF-8", "root", "root");
package test;
import com.mysql.jdbc.Driver;
import java.sql.DriverManager;
import java.sql.SQLException;
import static java.lang.Class.forName;
//实现JDBC加载驱动
/*
* 类的加载
* 1.new 对象
* 2.加载子类
* 3. 调用类中的静态成员
* 4. 通过反射
* 使用new对象的方式加载类 的不足:
* 1.依赖性太强,如果编译期间该类不存在,则直接编译错误
*2. 导致driver对象创建了两遍,效率较低
*
* 采用反射的方式加载类
* 1.属于运行期加载,大大降低类的依赖性
* 2.Driver对象仅仅创建一遍,效率较高
* */
public class Demo2 {
public static void main(String[] args)throws SQLException,ClassNotFoundException{
// DriverManager.deregisterDriver(new Driver());不推荐
Class.forName("com.mysql.jdbc.Driver");
System.out.println("成功");
}
}
package test;
import java.io.FileInputStream;
import java.sql.DriverManager;
import java.util.Properties;
//演示JDBC的步骤2:获取连接
public class Demo3 {
public static void main(String[] args) throws Exception{
Properties info=new Properties();
info.load(new FileInputStream("src\\jdbc.properties"));
info.list(System.out);//输出写入文件的命令
String user = info.getProperty("user");
String password = info.getProperty("password");
String url = info.getProperty("url");
String driver = info.getProperty("driver");
//1.注册连接
Class.forName(driver);
//2.获取连接
// DriverManager.getConnection("jdbc:mysql://localhost:3306/school?user=root&password=root");
// DriverManager.getConnection();
DriverManager.getConnection(url,user,password);
System.out.println("连接成功");
}
}
Object支持全部类型
package test;
import java.io.FileInputStream;
import java.sql.*;
import java.util.Properties;
//此类用于展示JDBC步骤3:增删改查
//主要这个类执行的是查
public class Demo4 {
public static void main(String[] args) throws Exception{
Properties info = new Properties();
info.load(new FileInputStream("src\\jdbc.properties"));
//info.list(System.out);//输出写入文件的命令
String user = info.getProperty("user");
String password = info.getProperty("password");
String url = info.getProperty("url");
String driver = info.getProperty("driver");
//1.注册连接
Class.forName(driver);
//2.获取连接
Connection connection = DriverManager.getConnection(url, user, password);
//3. 执行增删改查
String sql ="select id,name,sex,birthday,salary from student";
//获取执行SQL的命令对象
Statement statement =connection.createStatement();
//执行SQL语句
// int i = statement.executeUpdate(sql);执行增删改查语句,返回受影响的行数
ResultSet set = statement.executeQuery(sql);//执行查询语句,返回一个结果集
//boolean execute = statement.execute(sql); 执行任何的SQL语句,但不具体
while (set.next()) {
int id = set.getInt(1);
String name = set.getString(2);
String sex = set.getString(3);
Date date = set.getDate(4);
int salary = set.getInt(5);
System.out.println(id + "\t" + name + "\t" + sex + "\t" + date + "\t" + salary + "\t");
}
set.close();
statement.close();
connection.close();
}
}
package test;
import java.io.FileInputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Properties;
import java.util.Scanner;
//此类用于演示PreparedStement和Statement的区别
public class Demo5 {
//使用Statemen实现登录
public static void main(String[] args) throws Exception{
Scanner input =new Scanner(System.in);
System.out.println("输入姓名");
String username=input.next();
String pwd=input.next();
Properties info = new Properties();
info.load(new FileInputStream("src\\jdbc.properties"));
//info.list(System.out);//输出写入文件的命令
String user = info.getProperty("user");
String password = info.getProperty("password");
String url = info.getProperty("url");
String driver = info.getProperty("driver");
//注册驱动
Class.forName(driver);
//获取连接
Connection connection = DriverManager.getConnection(url, user, password);
//执行查询
String sql="select count(*) from admin where username='"+username+"'and password="+pwd+"";
Statement statement = connection.createStatement();
ResultSet set = statement.executeQuery(sql);
if (set.next()){
int count=set.getInt(1);
System.out.println(count>0?"成功":"失败");
}
//关闭
set.close();
statement.close();
connection.close();
}
}
package test;
import java.io.FileInputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.Properties;
import java.util.Scanner;
//此类用于演示PreparedStatement
/*好处
* 不再使用+拼接SQL语句,减少语法错误,语义性强
* 将模板SQL(固定的部分)和参数部分进行分离,提高维护性
* 有效解决了SQL注入问题
* 减少编译次数,效率高*/
public class Demo6 {
public static void main(String[] args) throws Exception {
Scanner input =new Scanner(System.in);
System.out.println("输入姓名");
String username=input.next();
String pwd=input.next();
Properties info = new Properties();
info.load(new FileInputStream("src\\jdbc.properties"));
//info.list(System.out);//输出写入文件的命令
String user = info.getProperty("user");
String password = info.getProperty("password");
String url = info.getProperty("url");
String driver = info.getProperty("driver");
//注册驱动
Class.forName(driver);
//编写SQL语句
String sql="select count(*) from admin where username=? and password=?";
//获取连接
Connection connection = DriverManager.getConnection(url, user, password);
PreparedStatement preparedStatement = connection.prepareStatement(sql);
//设置占位符的值
preparedStatement.setString(1,username);
preparedStatement.setString(2,pwd);
//执行sql
ResultSet set = preparedStatement.executeQuery();
if (set.next()){
int count=set.getInt(1);
System.out.println(count>0?"成功":"失败");
}
//关闭
set.close();
preparedStatement.close();
connection.close();
}
}
JDBC的相关API
DriverManger驱动管理类
registDriver(Driver对象):注册驱动,不太适应
getConnection(URL,user,pwd):获取连接
Connection连接对象接口
createStatement():生成命令对象
prepareStatement(sql):生成预编译命令对象
Statement命令对象接口
executeUpdate(sql):执行增删改查语句,返回影响的行数
executeQuery(sql):执行查询语句,返回结果集
execute(sql):执行任意SQL语句,返回Boolean
PrepareStatement预编译命令对象接口
executeUpdate(sql):执行增删改查语句,返回影响的行数
executeQuery(sql):执行查询语句,返回结果集
execute(sql):执行任意SQL语句,返回Boolean
setXX(占位符索引,占位符的值):设置对应索引的占位符的值,类型为XX类型
setObject(占位符索引,占位符的值):设置对应索引的占位符的值,类型为Object类型
ResultSet结果集对象接口
next():下移一行,返回当前行是否有值
previous():上移一行,返回当前行是否有值
getXX(列索引|列名|别名):返回对应的值,接受类型为XX
getObject(列索引|列名|别名):返回对应的值,接受类型为Object
PrepareStatement和Statement区别
关系:Statement和PrepareStatement都属于执行SQL语句的命令接口,都提供一系列执行失去了语句的方法
PrepareStatement继承Statement
区别:
-
PrepareStatement不再使用+,减少错误
-
将模板SQL(固定的部分)和参数部分进行分离,提高维护性
-
有效解决了SQL注入问题
-
减少编译次数,效率高
工具类
package test;
import java.io.FileInputStream;
import java.io.IOException;
import java.sql.*;
import java.util.Properties;
/*
* 此类用于封装JDBC工具类
* 功能:获取可用的连接对象
* 1. 获取连接
* 2. 释放资源
* */
public class JDBCUtils {
static String user;
static String password;
static String url;
static String driver;
static {
try {
Properties info = new Properties();
info.load(new FileInputStream("src\\jdbc.properties"));
//info.list(System.out);//输出写入文件的命令
String user = info.getProperty("user");
String password = info.getProperty("password");
String url = info.getProperty("url");
String driver = info.getProperty("driver");
//注册驱动
Class.forName(driver);
} catch (Exception e){
throw new RuntimeException(e);
}
}
public static Connection getconnection() {
try {
return DriverManager.getConnection(url, user, password);
} catch (Exception e) {
throw new RuntimeException(e);//抛一个运行异常。不强制你立马处理异常
}
}
//释放资源
public static void close(ResultSet set, Statement statement,Connection connection){
try {
if(set!=null){
set.close();
}
if (statement!=null){
statement.close();
}
if (connection!=null){
connection.close();
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
JDBC处理事务
JDBC程序当一个连接对象被创建时,默认情况是自动提交事务,如果执行成功,就会像数据库自动提交,不能回滚
package JDBC事务;
import test.JDBCUtils;
import test.Test;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Statement;
/*使用步骤
1. 开启新事务
取消事务自动提交的功能
2. 编写组成事务的一组SQL语句
3. 结束事务
细节:
要求开启事务的连接和获取命令的连接对象必须是同一个,否则事务无效
*/
public class Demo1 {
public static void main(String[] args)throws Exception {
Connection connection=null;
PreparedStatement statement=null;
try {
//获取连接
connection = JDBCUtils.getConnection();
//开启事务,取消了每一条SQL语句自动提交
connection.setAutoCommit(false);
//编写事务,执行SQL语句
statement = connection.prepareStatement("update accout set balance =? where stuname=?");
//操作1:张三丰的钱-5000
statement.setInt(1,5000);
statement.setString(2,"张三丰");
statement.executeUpdate();
//操作2:灭绝师太的钱+5000
statement.setInt(1,15000);
statement.setString(2,"灭绝师太");
statement.executeUpdate();
//结束事务
connection.commit();
} catch (Exception e) {
try {
//回滚事务
connection.rollback();
} catch (SQLException ex) {
ex.printStackTrace();
}
}finally {
JDBCUtils.close(null,statement,connection);
}
}
}
批处理
当需要呈批插入,可以使用Java的批量更新机制,允许多条语句一次性提交给数据库批量处理
-
addBatch():添加需要批量处理的SQL语句或参数
-
executeBatch():执行批量处理语句;
-
clearBatch():清空处理语句;
多条SQL语句的批量处理
一个SQL语句的批量传参
注意
JDBC连接MySQL时,如果要使用批处理功能,请在URL中加参数?rewriteBatchedStatements=true
PreparedStatement作为批处理插入式使用values(使用value没有效果)
package JDBC事务;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import java.sql.Connection;
public class Demo5 {
public static void main(String[] args) throws Exception{
Connection connection = JDBCUtilByDruid.getConnection();
QueryRunner qr = new QueryRunner();
admin query = qr.query(connection, "select * from admin where id=?", new BeanHandler<>(admin.class),3033);
System.out.println(query);
JDBCUtilByDruid.close(null,null,connection);
}
}
package JDBC事务;
//封装表中信息
import sun.security.util.Password;
public class admin {
private int id;
private String username;
private String password;
public admin(int id) {
this.id = id;
this.password= password ;
this.username=username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public admin(){
super();
}
@Override
public String toString() {
return "admin{" +
"id=" + id +
", username='" + username + '\'' +
", password='" + password + '\'' +
'}';
}
}
DAO:data access object 数据访问对象层
增删改查操作封装在DAO类中
通用的增删改方法,针对任何表
通用的查询单条记录,针对任何表
通用的查询多条记录,针对任何表
通用的查询单个值,针对任何表
) {
this.username = username;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public admin(){
super();
}
@Override
public String toString() {
return "admin{" +
"id=" + id +
", username='" + username + '\'' +
", password='" + password + '\'' +
'}';
}
}
DAO:data access object 数据访问对象层
增删改查操作封装在DAO类中
通用的增删改方法,针对任何表
通用的查询单条记录,针对任何表
通用的查询多条记录,针对任何表
通用的查询单个值,针对任何表
