1)JDBC是什么
Java DataBase Connectivity(Java语言连接数据库)
2)JDBC的本质是什么
JDBC的本质是一套接口。(有利于降低耦合度)
思考:为什么SUN制定一套JDBC接口?
因为每一个数据库的底层实现原理不一样。
因此每个数据库厂家都实现了JDBC接口。
3)JDBC编程六步(重点)
第一步:注册驱动 (作用:告诉java程序,即将要连接的是那个品牌的数据库)
第二步:获取连接 (表示JVM的进程和数据库进程之间的通道打开了,这属于进程之间的通信,使用完后一定要关闭通道)
第三步:获取数据库操作对象 (专门执行sql语句的对象)
第四步:执行sql语句(DQL、DML…)
第五步:处理结果集(只有当第四步执行的是select语句时,才有这第五步处理查询结果集)
第六步:释放资源(使用完资源后一定要关闭资源)
4)注册驱动的实现
1、Java.sql包下有一个接口Driver
public interface Driver
每个驱动程序类必须实现的接口
每个数据库厂商都有不同的实现类
2、Java.sql包下有一个类DriverManager
java.sql.DriverManager
DriverManager类会在尝试加载在“jdbc.drivers”系统属性中引用的驱动程序类
DriverManager类的静态方法
public static void registerDriver(Driver driver)
向DriverManager注册相关的驱动程序。(新加载的驱动类应该调用registerDriver方法)
让DriverManager知道是那个数据库
注册驱动的第一种方法
使用DriverManager加载MySQL驱动程序
//创建Driver接口实例对象
Driver driver=new com.mysql.jdbc.Driver();//多态,父类引用指向子类对象
//使用DriverManager类加载Driver接口的实例对象(注册mysql驱动)
DriverManager.registerDriver(driver)
第二种方法
Class.forName("com.mysql.cj.jdbc.Driver);
mysql实现Driver接口代码
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!");
}
}
}
发现源码中DriverManager.registerDriver(new Driver());代码写在静态代码块中
因此,我们可以通过类加载来实现注册驱动。(类加载时,静态代码块会执行)
5)Java代码实现Jdbc编程六步
public static void main(String[] args) {
Connection conn=null;
Statement stat=null;
ResultSet rs=null;
try {
//1.注册驱动
Class.forName("com.mysql.cj.jdbc.Driver");
//获取连接
String url="jdbc:mysql://localhost:3306/unipue?serverTimezone=UTC";
String user="root";
String password="123";
conn= DriverManager.getConnection(url,user,password);
//获取数据操作对象
stat=conn.createStatement();
//执行sql语句
String ln="zhangsan";
String sql="select *from t_user where loginName='"+ln+"'";
rs=stat.executeQuery(sql);//返回结果集
//处理结果集
while(rs.next()){
String loginName=rs.getString("loginName");
String loginPassword=rs.getString("loginPassword");
System.out.println("用户名:"+loginName+",密码:"+loginPassword);
}
} catch (Exception e) {
e.printStackTrace();
}finally{
//释放资源
if(rs!=null){
try {
rs.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if(stat!=null){
try {
stat.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if(conn!=null){
try {
conn.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
}
不过上面这种方式会有sql注入问题
6)Statement和PreparedStatement的区别
- Statement存在sql注入问题,PreparedStatement解决了sql注入问题
- Statement是编译一次执行一次,PreparedStatement是编译一次,可执行N次。PreparedStatement执行效率较高
- PreparedStatement会在编译阶段做类型的安全检查。(预编译)
public static void main(String[] args) {
Connection conn=null;
PreparedStatement ps=null;
try {
//1.注册驱动
Class.forName("com.mysql.cj.jdbc.Driver");
//获取连接
String url="jdbc:mysql://localhost:3306/unipue?serverTimezone=UTC";
String user="root";
String password="123";
conn= DriverManager.getConnection(url,user,password);
//?是占位符
String sql="update t_user set loginPassword=? where loginName=? and loginPassword=?";
//获取数据库预编译对象
ps=conn.prepareStatement(sql);
//给占位符(?)赋值,占位符下标从1开始
ps.setString(1,"159357");
ps.setString(2,"zhangsan");
ps.setString(3,"123");
//执行sql语句
//返回一共处理多少条数据
int sum=ps.executeUpdate();
} catch (Exception e) {
e.printStackTrace();
}finally{
//释放资源
if(ps!=null){
try {
ps.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if(conn!=null){
try {
conn.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
}
7)什么情况使用Statement?
当业务方面必须支持SQL注入的时候。
凡是业务方面要求需要进行sql语句拼接的,都要使用Statement。
比如:对某个字段进行升序/降序排序。(价格等)