JDBC(Java Data Base Connection)是通过Java
访问数据库的操作,这里以常用的MySQL
数据库为例。
访问MySQL
需要使用到第三方的类,比如mysql-connector-java-5.0.8-bin.jar
,下载完之后,进入eclipse
的项目中导入这个jar包。
导包步骤:
右键:project->property->java build path->libaries->add external jars
初始化驱动
在连接数据库之前,通过:Class.forName("com.mysql.jdbc.Driver");
初始化驱动类:com.mysql.jdbc.Driver
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
建立数据库连接
- 建立与数据库的
Connection
连接,需要提供:
- 数据库所处于的ip:127.0.0.1 (本机)
- 数据库的端口号: 3306 (mysql专用端口号)
- 数据库名称 how2java
- 编码方式 UTF-8
- 账号 root
- 密码 admin
try {
Connection c = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/how2java?characterEncoding=UTF-8",
"root", "admin");
} catch(SQLException e){
e.printStackTrace();
}
Statement
是用于执行SQL语句的,比如增加,删除
try {
Statement s = c.createStatement();
} catch(SQLException e){
e.printStackTrace();
}
- 在相关操作完成之后,需要关闭数据库的连接,释放资源。
- 因为
Connection
和Statement
都实现了AutoCloseable
接口,可以使用try-with-resource
的方式自动关闭连接,较为方便。
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
public class TestJDBC {
public static void main(String[] args) {
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
try (
Connection c = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/how2java?characterEncoding=UTF-8",
"root", "admin");
Statement s = c.createStatement();
){
//数据库操作
} catch(SQLException e){
e.printStackTrace();
}
数据库操作
1. 通过Statement实现
在JDBC中增加,删除,修改的操作都很类似,只是传递不同的SQL语句就行了。
在建立连接的基础下,我们需要传递完整的MySQL
语句。
//插入
String sql1 = "insert into hero values(null," + "'提莫'" + "," + 313.0f + "," + 50 + ")";
//删除
String sql2 = "delete from hero where id = 5";
//修改
String sql = "update hero set name = 'name 5' where id = 3";
//通过execute实现
s.execute(sql);
s.execute(sql);
s.execute(sql);
查询需要返回结果集,这里我们使用ResultSet
来接受结果集,并用executeQuery
执行查询语句。
import java.sql.ResultSet;
...
String sql = "select * from hero";
// 执行查询语句,并把结果集返回给ResultSet
ResultSet rs = s.executeQuery(sql);
//遍历
while (rs.next()) {
int id = rs.getInt("id");// 可以使用字段名
String name = rs.getString(2);// 也可以使用字段的顺序
float hp = rs.getFloat("hp");
int damage = rs.getInt(4);
System.out.printf("%d\t%s\t%f\t%d%n", id, name, hp, damage);
}
// 不一定要在这里关闭ReultSet,因为Statement关闭的时候,会自动关闭ResultSet
// rs.close();
...
2. 通过PreparedStatement实现
PreparedStatement
是Statement
的预编译。
与Statement
不同的是,PreparedStatement
可以通过设置参数,指定相应的值。
优点:
- 使用参数设置,可读性好,不易犯错
PreparedStatement
有预编译机制,性能比Statement
更快- 防止
SQL
注入式攻击
import java.sql.PreparedStatement;
...
String sql = "insert into hero values(null,?,?,?)";
try (
Connection c = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/how2java?characterEncoding=UTF-8","root", "admin");
// 根据sql语句创建PreparedStatement
PreparedStatement ps = c.prepareStatement(sql);
) {
// 设置参数
ps.setString(1, "提莫");
ps.setFloat(2, 313.0f);
ps.setInt(3, 50);
// 执行
ps.execute();
} catch (SQLException e) {
e.printStackTrace();
}
...
execute与executeUpdate的区别
- 相同点
- 都可以执行增加,删除,修改
- 不同点
execute
可以执行查询语句,然后通过getResultSet
,把结果集取出来
executeUpdate
不能执行查询语句execute
返回boolean
类型,true
表示执行的是查询语句,false
表示执行的是insert
,delete
,update
等等
executeUpdate
返回的是int
,表示有多少条数据受到了影响
使用事务
- 在事务中的多个操作,要么都成功,要么都失败。
通过c.setAutoCommit(false);
关闭自动提交
使用c.commit();
进行手动提交
c.setAutoCommit(false);
// 加血的SQL
String sql1 = "update hero set hp = hp +1 where id = 22";
s.execute(sql1);
// 减血的SQL
// 不小心写错写成了 updata(而非update)
String sql2 = "updata hero set hp = hp -1 where id = 22";
s.execute(sql2);
// 手动提交
c.commit();
获取数据库的元数据
- 元数据概念:
和数据库服务器相关的数据,比如数据库版本,有哪些表,表有哪些字段,字段类型是什么等等。 - 在建立连接的条件下,通过获取
DatabaseMetaData
对象,来实现相关操作。
import java.sql.DatabaseMetaData;
...
DatabaseMetaData dbmd = c.getMetaData();
// 获取数据库服务器产品名称
System.out.println("数据库产品名称:\t"+dbmd.getDatabaseProductName());
// 获取数据库服务器产品版本号
System.out.println("数据库产品版本:\t"+dbmd.getDatabaseProductVersion());
// 获取数据库服务器用作类别和表名之间的分隔符 如test.user
System.out.println("数据库和表分隔符:\t"+dbmd.getCatalogSeparator());
// 获取驱动版本
System.out.println("驱动版本:\t"+dbmd.getDriverVersion());
System.out.println("可用的数据库列表:");
// 获取数据库名称
ResultSet rs = dbmd.getCatalogs();
while (rs.next()) {
System.out.println("数据库名称:\t"+rs.getString(1));
}
...
DRM
- ORM = Object Relationship Database Maping
- 对象和关系数据库的映射
- 简单说,一个对象,对应数据库里的一条记录。
DAO
- DAO = Data Access Objec
- 数据访问对象
- 实际上就是运用了ORM中的思路,把数据库相关的操作都封装在这个类里面,其他地方看不到JDBC的代码。