JDBC入门
Java DataBase Connectivity
持久化概念引入(persistence):
把数据保存到可掉电式存储设备(断电之后数据还在 )中
数据持久化意味着将内存中的数据保存到硬盘上加以 固化
可以做持久化的:
记事本
XML
数据库
1. JDBC 简介
是一种用于执行SQL语句的java API ,可以为多种关系数据库提供统一访问.
它由一组用Java语言编写的类和接口组成。JDBC提供了一种基准,据此可以构建更高级的工具和接口
JDBC是接口,基准,工具-- 说明Java做了一组规范,它本身不实现这组规范。
让各大厂商去实现这组规范 具体实现代码由厂商提供 驱动程序
在java中 数据库存取技术只能通过JDBC访问数据库 其它技术是JDBC封装
JDBC访问数据库的形式主要有两种:
JDBC是一种最原生的访问方式
直接使用JDBC的API去访问数据库服务器
间接使用JDBC的API去访问数据库服务器 使用其他框架 第三方O/R Mapping
工具,如Hibernate Mybatis JPA等
2. JDBC连接
记得导入数据库连接包 一般在数据库官网有提供下载
连接步骤:
贾(加载注册驱动) Class.forName(“com.mysql.jdbc.Driver”)
琏(获取连接) DriverManager.getConnection(url,username,password)
欲(获取语句对象) Statement st = conn.createStatement();
执(执行) st.executeUpdate/executeQuery(sql)
事(释放资源) st.close()/rs.close()/conn.close()
2.1 加载注册驱动
从Java6开始,规范要求每一个JDBC驱动的包, 都必须带有
META-INF/services/java.sql.Driver文件 可以不用注册驱动
建议手动的加载注册驱动.如此,可以兼容之前的JDK版本
注册驱动的三种方式:
A .DriverManager.registerDriver(new com.mysql.jdbc.Driver());
会造成DriverManager中产生两个一样的驱动,并会对具体的驱动类产生依赖。
具体来说就是:
1,加载的时候注册一次驱动(原因请看第三中注册方式),实例化的时候又注册一
次。所以两次。
2,由于实例化了com.mysql.jdbc.Driver.class,导致必须导入该类(就是要
把这个类import进去),从而具体驱动产生了依赖。不方便扩展代码。
B. System.setProperty("jdbc.drivers","com.mysql.jdbc.Driver");
通过系统的属性设置注册驱动 如果要注册多个驱动,则 System.setProperty
("jdbc.drivers","com.mysql.jdbc.Driver:com.oracle.jdbc.Driver");
虽然不会对具体的驱动类产生依赖;但注册不太方便,所以很少使用。
C. Class.forName("com.mysql.jdbc.Driver")
推荐这种方式,不会对具体的驱动类产生依赖(就是不用import package了)
关键点:
com.mysql.jdbc.Driver类中 因为这个静态代码块 在加载类时就会执行了
static{
try{
java.sql.DriverManager.registerDriver(new Driver());
}catch(SQLException e){
throw new RuntimeException("can't register driver!");
}
}
2.2 取连接对象
String url="jdbc:mysql://127.0.0.1:3306/mysqltest"
Connection conn=DriverManager.getConnection(url,uname,password);
解释: jdbc:mysql指连接的数据库是mysql数据库
127.0.0.1:3306指的是数据库所在主机地址 和数据库端口号
uname 指的是数据库用户名
password 值得是数据库密码
注意:
在MySQl8.0及更高版本中 使用高版本的驱动包时有所变化
驱动注册包变为com.mysql.cj.jdbc.Driver 同时在获取数据库连接时也有所不同 如下:
Class.forName("com.mysql.cj.jdbc.Driver");
Connection conn =
DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/mysqltest?
useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=GMT",
"root","root");
2.3 获取语句
String sql="";
2.4 获取执行语句对象
Statement st=conn.createStatement();
或prepareStatement pst=conn.prepareStatement();
prepareStatement使用方法:
//用?占位
String sql ="select * from student where username=? and password=?";
// 预先连接数据库
PreparedStatement ps = conn.prepareStatement(sql );
ps.setString(1," 填充第一问号占位 ");
ps.setString(2, " 填充第2问号占位 ");
ResultSet rs = ps.executeQuery();
区别:
关系:PreparedStatement继承自Statement,都是接口
区别:PreparedStatement可以使用占位符,是预编译的,批处理比Statement效率高
PreparedStatement利用预编译的机制将sql语句的主干和参数分别传输给数据库服务器,从而使数据库分辨的出
哪些是sql语句的主干哪些是参数,这样一来即使参数中带了sql的关键字,数据库服务器也仅仅将他当作参数值使用,
关键字不会起作用,从而从原理上防止了sql注入的问题
PreparedStatement主要有如下的三个优点:
1.可以防止sql注入
2.由于使用了预编译机制,执行的效率要高于Statement
3.sql语句使用?形式替代参数,然后再用方法设置?的值,比起拼接字符串,代码更加优雅.
PreparedStatement 与Statment比较
1)语法不同:PreparedStatement可以使用预编译的sql,而Statment只能使用静态的sql
2)效率不同: PreparedStatement可以使用sql缓存区,效率比Statment高
3)安全性不同: PreparedStatement可以有效防止sql注入,而Statment不能防止sql注
入。
2.5 获取结果映射集 ResultSet
ResultSet resultSet = prepareStatement.executeQuery();
或ResultSet resultSet= statement.execute(sql);
查询数据库时,返回的是一个二维的结果集,我们需要用到ResultSet来遍历结果集,获取每一行的数据
常用方法:
boolean next() 将光标从当前位置向前移一行。
String getString(int columnIndex) 以java编程语言中String的形式获取此ResultSet对象的
当前行中指定列的值
String getString(String columnLabel) 以java编程语言中String的形式获取此ResultSet对
象的当前行中指定列的值
ResultSetMetaData data = resultSet.getMetaData();
int i=data.getColumnCount();//返回数据行数
data.getColumnName(j) //获取列名
2.6 释放资源
public void close(Connection con, PreparedStatement ps, ResultSet rs) {
try {
if (rs != null)
rs.close();
} catch (SQLException e) {
e.printStackTrace();
} finally {
try {
if (ps != null)
ps.close();
} catch (SQLException e) {
e.printStackTrace();
} finally {
try {
if (con != null)
con.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
完整示例代码
mysql5.5 驱动包版本5.1 jdk 1.8
public class JdbcUtil {
public static Connection getConnection() {
String url = "jdbc:mysql://127.0.0.1:3306/mysqltest";
String user = "root";
String password = "root";
Connection conn = null;
try {
Class.forName("com.mysql.jdbc.Driver");
conn = (Connection) DriverManager.getConnection(url, user, password);
} catch (Exception e) {
e.printStackTrace();
}
return conn;
}
public static void close(Connection con, PreparedStatement ps, ResultSet rs) {
try {
if (rs != null)
rs.close();
} catch (SQLException e) {
e.printStackTrace();
} finally {
try {
if (ps != null)
ps.close();
} catch (SQLException e) {
e.printStackTrace();
} finally {
try {
if (con != null)
con.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
public class JdbcUse {
@Test
public void tes() throws Exception {
Connection conn=JdbcUtil.getConnection();
String sql="select * from dlltest ";
PreparedStatement prepareStatement = (PreparedStatement) conn.prepareStatement(sql);
ResultSet resultSet = prepareStatement.executeQuery();
ResultSetMetaData data = resultSet.getMetaData();
int i=data.getColumnCount();
while(resultSet.next()) {
for(int j=1;j<=i;j++)
System.out.print(resultSet.getObject(j)+" ");
System.out.println();
}
JdbcUtil.close(conn, prepareStatement, resultSet);
}
}
参考链接:
https://blog.csdn.net/wangxintong_1992/article/details/80768067
https://blog.csdn.net/lsx2017/article/details/82630838
https://www.cnblogs.com/chenning/p/5030790.html