学完数据库和java se部分,刚好来看一下JDBC,JDBC其实就是java所提供的用来执行SQL语句的Java API。
因为数据库种类非常多,java语言需要连接不同的数据库,自己需要去实现连接步骤,但是这样做比较麻烦,所以java语言只是定义一套关于数据库连接操作接口。然后交给不同的数据库开发商去实现(mysql.jar)。
JDBC(Java DataBase Connectivity)java数据库连接
1. 是一种用于执行SQL语句的Java API,可以为多种关系型数据库提供统一访问, 它由一组用Java语言编写的类和接口组成。
2. 有了JDBC,java开发人员只需要编写一次程序,就可以访问不同的数据库。
JDBC API:
供程序员调用的接口与类,集成在java.sql包中
DriverManager类作用:管理各种不同的jDBC驱动
Connection 接口 与特定数据库的连接
Statement 接口 执行sql
PreparedStatement接口 执行sql
ResultSet接口 接收查询结果
JDBC搭建
第一步,注册JDBC驱动程序:
这需要初始化驱动程序,这样就可以打开与数据库的通信信道。 Class.forName(“com.mysql.cj.jdbc.Driver”); //反射实现
或者 DriverManager.registerDriver(new Driver());
第二步,建立与数据库连接:
● 这需要使用DriverManager.getConnection()方法来创建一个 Connection对象,它代表一个物理连接的数据库.
● Connection conn = DriverManager.getConnection(URL,USER,PASS); URL:jdbc:mysql://ip(127.0.0.1):端口(3306)/数据库 名?serverTimezone=Asia/Shanghai USER:用户名(root) PASS:密码
第三步,获得Satement执行sql语句 或者 获得PrepareStatement执行sql语句
Statement st = connection.createStatement();
Satement中的方法:
Int executeUpdate(String sql) 用于执行ddl语句和dml(增,删,改)语句 返回 操作的行数
用于执行ddl语句返回0
用于执行dml语句返回操作的行数
ResultSet executeQuery(String sql); 用于执行查询语句 返回一个 ResultSet 集合
在sql语句中参数位置使用占位符,使用setXX方法向sql中设置参数
PrepareStatement ps = connection.prepareStatement(sql);
PrepareStatement中的方法:
Int executeUpdate() 用于执行ddl语句和dml(增,删,改)语句 返回操作的行数
用于执行ddl语句返回0
用于执行dml语句返回操作的行数
ResultSet executeQuery(); 用于执行查询语句 返回一个ResultSet 集合
第四步,结果集处理
PreparedStatement和Statement中的executeQuery()方法中会返回一 个ResultSet对象,查询结果就封装在此对象中.
使用ResultSet中的next()方法获得下一行数据
使用getXXX(String name)方法获得值
最后一步,关闭与数据库的链接通道
每次操作完成后关闭所有与数据库交互的通道
st.close();
rs.close();
conn.close();
ps.close();
那么为什么 Connection、Statement和ResulSet?这三个对象是在方法内部定义的,则这三个对象不是在方法执行完毕就消失了么,为什么还要单独去关闭它们呢?
其实是因为,这个连接是与数据库服务器的一个连接,虽然你的方法结束了,但是这个资源依然存在数据库连接并没有释放。所以我们需要在使用完毕后,自己手动的释放。
PreparedStatement和Statement的区别
1.Statement 直接在sql中拼接参数 书写不方便
PreparedStatement 使用占用符占用,通过sql方法设置值
2.Statement直接拼接参数,不安全
PreparedStatement使用setObject设置值,检测占位符对应的值 or 1=1
先把sql预编译到对象中,然后赋值.
下面为两者进行sql语句处理的实例。
public static void main(String[] args) throws SQLException, ClassNotFoundException {
String id = "1000 or 1=1"; //sql注入 sql攻击
Class.forName("com.mysql.cj.jdbc.Driver");
Connection connection = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/chatdb?serverTimezone=Asia/Shanghai", "root", "root");
//预编译sql ?-->占位符
PreparedStatement ps = connection.prepareStatement("delete from tuser where id = ?");
ps.setObject(1, id);//set方法中对传入的值进行检测.一个?对应一个值,不能有其他的关键字
ps.executeUpdate();//执行
ps.close();
connection.close();
}
public static void main(String[] args) throws SQLException, ClassNotFoundException {
String id = "1000 or 1=1"; //sql注入 sql攻击
Class.forName("com.mysql.cj.jdbc.Driver");
Connection connection = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/chatdb?serverTimezone=Asia/Shanghai", "root", "root");
Statement st = connection.createStatement();
st.executeUpdate("delete from tuser where id = "+id);
st.close();
connection.close();
}
以下是没有基于任何框架的,最基础版本的使用JDBC,达成与数据库交互的实例
public class LoginDao {
public Admin login(String account, String password) throws ClassNotFoundException, SQLException {
Admin admin=null;
Connection connection = null;
PreparedStatement ps = null;
try {
Class.forName("com.mysql.cj.jdbc.Driver");//加载驱动
//创建数据库连接 DriverManager.getConnection("用户名","密码","连接")
connection = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/webdb?serverTimezone=Asia/Shanghai", "root", "");
//执行sql语句 Statement PreparedStatement
ps = connection.prepareStatement("select id,account from admin where account = ? and password = ?");
ps.setObject(1,account);//将问号位置的值注入
ps.setObject(2,password);
ResultSet resultSet = ps.executeQuery();//处理结果 ResultSet
while (resultSet.next()){
admin=new Admin();
admin.setID(resultSet.getInt("id"));
admin.setAccount(resultSet.getString("account"));
}
}finally {
if(connection!=null){
connection.close();//关闭连接
}
if (ps!=null){
ps.close();//关闭连接
}
}
return admin;
}
}