JDBC介绍:
JDBC(Java DataBase Connectivity)是Java和数据库之间的一个桥梁,是Java语言中用来规范客户端程序如何来访问数据库的应用程序接口,是一种规范而不是一种实现,真正的实现是由数据库提供商提供的数据库驱动,不同类型的数据库都有相应不同的驱动,也就是有不同的实现
所以我们程序员在写代码的时候,只需要让我们的Java程序面向JDBC接口即可,提高了开发效率。
JDBC API:
- 提供者:Java官方
- 内容:供开发者调用的接口
- DirverManager类
- connection 接口
- statement接口
- resultset接口
DriverManager:
- 提供者: Java官方
- 作用:管理不同的JDBC驱动
JDBC驱动:相当于是java和数据库的桥梁
- 提供者:数据库厂商
- 作用:负责连接不同的数据库
JDBC的使用:(我们这里用MySql为例)
1.装载相应的数据库JDBC驱动,并且初始化
导入专用的jar包(不同的数据库需要的jar包不同)
访问MySql数据库需要用到第三方的类,这些第三方类都被压缩到一个.jar文件里
我下载的是8.0.xx版本,(因为高版本可以兼容低版本的数据库,所以最好选高的)然后把包复制到java项目的lib文件下
复制之后还没有结束,我们需要在idea中导入这个jar包
2.初始化驱动
Class.forName("com.mysql.cj.jdbc.Driver");//利用反射加载运行时类
在src中建立com.southwind.test文件,并且建立Test.java文件
- 1.加载数据库,Java程序和数据库之间的桥梁
- 2.获取Connection,java程序与数据库的一次连接
- 3.创建Statement对象,由Connection产生,执行sql语句
- 4.如果需要接受返回值,创建ResultSet对象,保存Statement执行之后所查询到的结果
3.建立java文件(通过Statement方式或者通过prepareStatement方式)
public class Test{
public static void main(String[] args){
try{
//1 . 加载驱动
class.forName("com.mysql.cj.jdbc.Driver")//利用反射加载运行时类
//2. 获取链接:
String url="jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF-8"//
test是数据库的名字 使用unicode编码方式
是为了方式乱码
String usr="root";
String password="19900310"//数据库的密码
//3. 连接数据库
Connection connection=DriverManager.getConnection(url,user,password);
String sql="insert into student(name,score,birthday)values('张三',78,'2019-2-2');
//获取statement,然后来执行sql语句
//4 .通过executeUpdate方法来执行sql语句
//result返回的是执行的数据条数
Satement statement =connection.createStatement();
int result=statement.executeUpdate(sql);
}catch(ClassNotFoundException e){
e.printStackTrace();
}catch(SQLException e){
e.printStackTrace();
}
}
}
注意:增删改使用executeUpdate(sql),但是查询需要使用executeQuery
String sql="select * from student";
Statement student=connection.createStatement();
ResultSet resultSet=statement.executeQuery(sql);//相当于返回一个集合
while(resultSet.next()){
Integer id=resultSet.getInt(columnLabel:"id");//这里id也可以写成1
Integer name=resultSet.getString(columnLabel:2);
}
上面的操作是通过创建Statement来进行,但是在现实生活中很少使用Statement
为什么很少使用Statement?
1.在Statement中使用字符串拼接的方式,该方式存在句法复杂,容易犯错,并且存在SQL注入等缺点,具体在下文中的对比中介绍。所以Statement在实际过程中使用的非常的少,
2.字符串拼接方式的SQL语句是非常繁琐的,中间有很多的单引号和双引号的混用,极易出错。
3. 与 Statement一样,PreparedStatement也是用来执行sql语句的与创建Statement不同的是,需要根据sql语句创建PreparedStatement。除此之外,还能够通过设置参数,指定相应的值,而不是Statement那样使用字符串拼接。
使用Statement存在SQL注入的风险:如下:
String username="list'or '1' ='1";
String mypassword="123' or '1'='1";//无论输入的密码和账号是否正确都会登录成功
使用PreparedStatement方式:
//获取链接
String url="jdbc:/mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF-8"
String user="root"
String password="19970420";
//数据库连接
Connection connection=DriverManager.getConnection(url,user,password);
String username="lisi";
String mypassword="000";
String sql="select * from t_user where username=? and password=?";
//执行sql语句
PreparedStatement preparedStatement=connection.prepareStatement(sql);
preparedStatement.setString(1,username);
preparedStatement.setString(2,mypassword);
ResultSet resultSet=prepareStatement.executeQuery();
注意:增删改都用.executeQuery()方法,查询用 executeQuery()方法
4.释放资源:
在JDBC编码的过程中我们创建了Connection、ResultSet等资源,这些资源在使用完毕之后是一定要进行关闭的。关闭的过程中遵循从里到外的原则。因为在增删改查的操作中都要用到这样的关闭操作,为了使代码简单,增加其复用性,这里我将这些关闭的操作写成一个方法和建立连接的方法一起放到一份工具类中。
/**
* 封装三个关闭方法
* @param pstmt
*/
public static void close(PreparedStatement pstmt){
if(pstmt != null){ //避免出现空指针异常
try{
pstmt.close();
}catch(SQLException e){
e.printStackTrace();
}
}
}
public static void close(Connection conn){
if(conn != null){
try {
conn.close();
} catch (SQLException e) {
// TODO: handle exception
e.printStackTrace();
}
}
}
public static void close(ResultSet rs){
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {
// TODO: handle exception
e.printStackTrace();
}
}
}