目录
JDBC的介绍
JDBC(Java DataBase Connectivity)是Java和数据库连接的桥梁,它是一个规范,而不是一个实现,使用JDBC能够在Java代码中执行操作数据库的SQL语句。
JDBC操作数据库步骤
(1)加载数据库驱动;
(2)连接数据库DriverManager;
(3)获取执行SQL语句的对象;
(4)执行SQL语句
(5)获取返回的结果集(处理执行结果)
(6)释放连接(释放资源)
代码详细解释步骤(Statement对象)
(1)加载数据库驱动;
- 方式一(常用):
Class.forName("com.mysql.jdbc.Driver");
此类方式的Class.forName函数作用是根据类的名字将类装载到虚拟机中(并未实例化),因此这种方式不会对具体的驱动类产生依赖,而且使用很方便,所以推荐使用。 - 方式二:
DriverManager.registerDriver(com.mysql.jdbc.Driver);
这种方式要求程序首先要引入驱动包,否则无法通过编译。而且它可能会造成DriverManager中产生两个一样的驱动,并对具体的驱动类产生依赖,所以不推荐使用。
(2)连接数据库DriverManager;
DriverManager.getConnection(url, username, password);
//(2)用户信息和url
//url格式:JDBC:子协议:子名称//主机名:端口/数据库名?key=value&…
String url = "jdbc:mysql://localhost:3306/表名?useUnicode=true&characterEncoding=utf8&&useSSL=true";
String username = "root";
String password = "root";
//(3)连接成功,获取数据库对象 Connection代表数据库
Connection connection = DriverManager.getConnection(url, username, password);
URL的类型:
-
MySQL数据库:
协议∶//主机地址:端口号/数据库名?参数1&参数2&参数3
端口: 3306
写法:jdbc:mysql://localhost:3306/表名?useUnicode=true&characterEncoding=utf8&&useSSL=true
-
Oracle数据库:
协议∶//主机地址:端口号/数据库名?参数1&参数2&参数3
端口:1521
写法:jdbc:oracle:thin:@localhost:1521:sid
(3)获取执行SQL语句的对象;
Statement statement = connection.createStatement();
这里有两个对象可以使用:Statement、PreparedStatement对象,后面详细介绍这两个对象的使用以及区别。
(4)执行SQL语句、并且处理结果集
- 查询
String sql = "select * from users";
ResultSet resultSet = statement.executeQuery(sql);
while(resultSet.next()){
//处理结果集操作
}
- 增删改
sql可以是增删改操作的SQL语句
int i = st.executeUpdate(sql);
if(i>0){ //i>0时表示操作成功
System.out.println("数据添加成功");
}
//(6)释放连接
resultSet.close();
statement.close();
connection.close();
依次释放ResultSet、Statement(或PreparedStatement)、Connection对象,释放顺序与创建顺序相反(类似“栈”结构)。因为在增删改查的操作中都要用到这样的关闭操作,为了使代码简单,增加其复用性,后面介绍中我将这些关闭的操作写成一个方法和建立连接的方法一起放到一份工具类中。
封装工具类(以MySQL为例、Statement对象) 实现增删改查
这里以MySQL数据库为例子,并且使用Statement对象进行代码的封装。
使用Maven创建一个工程进行测试。
数据库建表语句
- 建表语句
CREATE TABLE `users` (
`id` int(11) NOT NULL,
`NAME` varchar(40) DEFAULT NULL,
`PASSWORD` varchar(40) DEFAULT NULL,
`email` varchar(60) DEFAULT NULL,
`birthday` date DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
- 插入数据:
INSERT INTO `users`(id,NAME,PASSWORD,email,birthday)
VALUES(1,'zhansan','123456','[email protected]','1980-12-04'),
(2,'lisi','123456','[email protected]','1981-12-04'),
(3,'wangwu','123456','[email protected]','1979-12-04')
Pom文件
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
配置文件–db.properties
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/数据库名?useUnicode=true&characterEncoding=utf8&useSSL=true
username=root
password=root
工具类
import java.io.InputStream;
import java.sql.*;
import java.util.Properties;
public class JdbcUtils {
private static String driver = null;
private static String url = null;
private static String username = null;
private static String password = null;
static {
try{
InputStream in = JdbcUtils.class.getClassLoader().getResourceAsStream("db.properties");
Properties properties = new Properties();
properties.load(in);
driver = properties.getProperty("driver");
url = properties.getProperty("url");
username = properties.getProperty("username");
password = properties.getProperty("password");
//驱动只加载一次
Class.forName(driver);
}catch(Exception e){
e.printStackTrace();
}
}
//获取连接
public static Connection getConnection() throws SQLException {
return DriverManager.getConnection(url,username,password);
}
//释放资源
public static void release(Connection conn, Statement st, ResultSet rs){
if(rs!=null){
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(st!=null){
try {
st.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(conn!=null){
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
增删改操作
public static void main(String[] args) {
Connection conn = null;
Statement st = null;
ResultSet rs = null;
try{
conn = JdbcUtils.getConnection();//获取数据库连接对象
st = conn.createStatement();//获取SQL执行对象
// 增
//String sql = "INSERT INTO users(id,`NAME`,`PASSWORD`,`email`,`birthday`)" +
// " VALUES(4,'oldou','654321','[email protected]','2020-01-01')";
//改
// String sql = "UPDATE users set `name`= 'oldou',`email`= '[email protected]' where id = 1";
//删
String sql = "delete from users where id = 4";
//执行SQL语句
int i = st.executeUpdate(sql);
if(i>0){
System.out.println("数据删除成功");
}
}catch(Exception e){
e.printStackTrace();
}finally {
//关闭连接
JdbcUtils.release(conn,st,rs);
}
}
查操作
public static void main(String[] args) {
Connection conn= null;
Statement st = null;
ResultSet rs = null;
try{
conn = JdbcUtils.getConnection();
st = conn.createStatement();
String sql = "select * from users";
rs = st.executeQuery(sql);
while(rs.next()){
System.out.print(rs.getObject("id")+" ");
System.out.print(rs.getObject("NAME")+" ");
System.out.print(rs.getObject("PASSWORD")+" ");
System.out.print(rs.getObject("email")+" ");
System.out.println(rs.getObject("birthday"));
}
}catch (Exception e){
e.printStackTrace();
}finally {
JdbcUtils.release(conn,st,rs);
}
}
封装工具类(PreparedStatement对象)实现增删改查
工具类
public class JdbcUtils {
private static String driver = null;
private static String url = null;
private static String username = null;
private static String password = null;
static {
try{
InputStream in = JdbcUtils.class.getClassLoader().getResourceAsStream("db.properties");
Properties properties = new Properties();
properties.load(in);
driver = properties.getProperty("driver");
url = properties.getProperty("url");
username = properties.getProperty("username");
password = properties.getProperty("password");
//驱动只加载一次
Class.forName(driver);
}catch(Exception e){
e.printStackTrace();
}
}
//获取连接
public static Connection getConnection() throws SQLException {
return DriverManager.getConnection(url,username,password);
}
//释放资源
public static void release(Connection conn, Statement st, ResultSet rs){
if(rs!=null){
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(st!=null){
try {
st.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(conn!=null){
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
增操作
public class TestInsert {
public static void main(String[] args) {
Connection conn = null;
PreparedStatement ps = null;
try{
conn = JdbcUtils.getConnection();
String sql = "insert into users(id,`NAME`,`PASSWORD`,`email`,`birthday`) values(?,?,?,?,?)";
ps = conn.prepareStatement(sql);
//手动赋值
ps.setInt(1,4);
ps.setString(2,"oldouou");
ps.setString(3,"123456");
ps.setString(4,"[email protected]");
//new Date().getTime()获得时间戳
ps.setDate(5,new java.sql.Date(new Date().getTime()));
int i = ps.executeUpdate();
if(i>0){
System.out.println("数据插入成功..........");
}
}catch (Exception e){
e.printStackTrace();
}finally {
JdbcUtils.release(conn,ps,null);
}
}
}
删操作
public class TestDelete {
public static void main(String[] args) {
Connection conn = null;
PreparedStatement ps = null;
try{
conn = JdbcUtils.getConnection();
String sql = "delete from users where id = ?";
ps = conn.prepareStatement(sql); //预编译SQL
ps.setInt(1,4);
int i = ps.executeUpdate();
if(i>0){
System.out.println("数据删除成功..........");
}
}catch (Exception e){
e.printStackTrace();
}finally {
JdbcUtils.release(conn,ps,null);
}
}
}
改操作
public class TestUpdate {
public static void main(String[] args) {
Connection conn = null;
PreparedStatement ps = null;
try{
conn = JdbcUtils.getConnection();
String sql = "update users set NAME = ? , email = ? where id = ?";
ps = conn.prepareStatement(sql);
//手动赋值
ps.setString(1,"pipiou");
ps.setString(2,"[email protected]");
ps.setInt(3,3);
int i = ps.executeUpdate();
if(i>0){
System.out.println("数据更新成功..........");
}
}catch (Exception e){
e.printStackTrace();
}finally {
JdbcUtils.release(conn,ps,null);
}
}
}
查操作
public class TestSelect {
public static void main(String[] args) {
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
try{
conn = JdbcUtils.getConnection();
String sql = "select * from users where id = ?";
ps = conn.prepareStatement(sql);
ps.setInt(1,3);
rs = ps.executeQuery();
while(rs.next()){
System.out.print(rs.getObject("id")+" ");
System.out.print(rs.getObject("NAME")+" ");
System.out.print(rs.getObject("email")+" ");
System.out.println(rs.getObject("Birthday"));
}
}catch (Exception e){
e.printStackTrace();
}finally {
JdbcUtils.release(conn,ps,null);
}
}
}
Statement对象和PrepareStatement对象的区别
关系:PreparedStatement继承自Statement,都是接口
区别:PreparedStatement可以使用占位符,是预编译的,批处理比Statement效率高,并且PreparedStatement能够防止SQL注入。
PreparedStatement:表示预编译的 SQL 语句的对象。
- PreparedStatement接口代表预编译的语句,它主要的优势在于可以减少SQL的编译错误并增加SQL的安全性(减少SQL注射攻击的可能性);
- PreparedStatement中的SQL语句是可以带参数的,避免了用字符串连接拼接SQL语句的麻烦和不安全;
- 当批量处理SQL或频繁执行相同的查询时,PreparedStatement有明显的性能上的优势,由于数据库可以将编译优化后的SQL语句缓存起来,下次执行相同结构的语句时就会很快(不用再次编译和生成执行计划)
PreparedStatement的优点
-
1、其使用参数设置,可读性好,不易记错。在statement中使用字符串拼接,可读性和维护性比较差。
-
2、其具有预编译机制,性能比statement更快。
-
3、其能够有效防止SQL注入攻击。
execute和executeUpdate的区别
相同点:二者都能够执行增加、删除、修改等操作。
不同点:
-
execute可以执行查询语句,然后通过getResult把结果取出来。executeUpdate不能执行查询语句。
-
execute返回Boolean类型,true表示执行的是查询语句,false表示执行的insert、delete、update等。executeUpdate的返回值是int,表示有多少条数据受到了影响