有位教育家说得好:教育的真正目的就是让你忘掉你所学的所有之后还剩下的东西。在技术行业好像尤其如此,忘掉所学的所有技能,还剩下什么呢?
JDBC——Java DataBase Connectivity,今天小美就在这里回味与分享JDBC从最原始的连接到优化后版本的过程,通过连接方式的不断优化,这种简化思想就是我忘掉所有之后还剩下的。
一、JDBC实现CURD
CURE- Create Update Retrieve Delete
前期准备工作:
1 使用MyEclipse创建javaweb项目Test_JDBC
2 导入MySQL连接包,版本:mysql-connector-java-5.1.39.jar
3 使用MySQ数据库,创建数据库news_db,数据表t_news,并添加3条数据。
步骤如下:
#创建数据库news_db
create database news_db;
use news_db;
#创建数据表t_news
create table t_news (
id int(11) auto_increment primary key,
title varchar(255),
author varchar(255)
);
#为t_news增加3条数据
insert into t_news (title,author) values
("资源和政策堆出来的联通还是衰落了","新华社"),
("不要把特斯拉市值超越通用汽车当回事儿","南方日报"),
("若iPhone8推迟到11月上市,谁会偷着乐?","羊城晚报");
准备工作完成,Beautiful!
1)实现Select
package com.hmc.jdbc;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
/**
* @Author Meice
* @Date 2017年8月5日
*/
public class TestJDBCSelect {
public void select() {
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
//1 加载驱动
try {
Class.forName("com.mysql.jdbc.Driver");
//2 获取连接
String url = "jdbc:mysql://localhost:3306/news_db";
String user = "root";
String password = "119913";
conn = DriverManager.getConnection(url, user, password);
//3 预编译SQL语句
String sql = "select * from t_news";
ps = conn.prepareStatement(sql);
//4 执行编译
rs = ps.executeQuery();
//5 遍历结果集
while(rs.next()) {
System.out.println(rs.getInt("id")+"--"+rs.getString("title")+"--"+rs.getString("author"));
}
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
//6 释放资源
try {
if(rs != null) rs.close();
if(ps != null) ps.close();
if(conn != null) conn.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public static void main(String[] args) {
new TestJDBCSelect().select();
}
}
2)实现Insert
package com.hmc.jdbc;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
/**
* @Author Meice
* @Date 2017年8月5日
*/
public class TestJDBCInsert {
public void add() {
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
Class.forName("com.mysql.jdbc.Driver");
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/news_db", "root", "119913");
//变化点1:新增sql我们采用参数传递
String sql = "insert into t_news (title,author) values (?,?)";
ps = conn.prepareStatement(sql);
ps.setString(1, "我是用参数增加的第一条新闻");
ps.setString(2, "admin1");
//变化点2:执行CUD时候,用的是executeUpdate()方法,不再是executeQuery()方法。
//并且返回结果为int
int result = ps.executeUpdate();
if(result>0) {
System.out.println("恭喜你,增加新闻成功!");
}else {
System.out.println("遗憾,增加新闻失败!");
}
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
try {
if(rs != null) rs.close();
if(ps != null) ps.close();
if(conn != null) conn.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public static void main(String[] args) {
new TestJDBCInsert().add();
}
}
截图比较费时间,后面除非到了一图胜千言的情况,一般不再截图。所有代码都是编写边测试。
3)实现Update
package com.hmc.jdbc;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
/**
* @Author Meice
* @Date 2017年8月5日
*/
public class TestJDBCUpdate {
public void update() {
Connection conn = null;
PreparedStatement ps = null;
try {
Class.forName("com.mysql.jdbc.Driver");
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/news_db", "root", "119913");
String sql = "update t_news set author = ? where id = ?";
ps = conn.prepareStatement(sql);
ps.setString(1, "admin2");
ps.setInt(2, 4);
int result = ps.executeUpdate();
if(result>0) {
System.out.println("恭喜你,修改成功!");
}else {
System.out.println("遗憾,修改失败!");
}
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
try {
if(ps != null) ps.close();
if(conn!= null) conn.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public static void main(String[] args) {
new TestJDBCUpdate().update();
}
}
4)实现Delete
package com.hmc.jdbc;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
/**
* @Author Meice
* @Date 2017年8月5日
*/
public class TestJDBCDelete {
public void del() {
Connection conn = null;
PreparedStatement ps = null;
try {
Class.forName("com.mysql.jdbc.Driver");
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/news_db", "root", "119913");
String sql = "delete from t_news where id = ?";
ps = conn.prepareStatement(sql);
ps.setInt(1, 4);
int result = ps.executeUpdate();
if(result>0) {
System.out.println("猴赛雷,删除成功!");
}else {
System.out.println("嗷嗷,删除失败!");
}
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
try {
if(ps != null) ps.close();
if(conn != null) conn.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public static void main(String[] args) {
new TestJDBCDelete().del();
}
}
这里采用的都是DML语句,如果采用DDL(create drop alter)会有效果吗?
5)采用DDL,创建一个表t_news2
package com.hmc.jdbc;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
/**
* @Author Meice
* @Date 2017年8月5日
*/
public class TestJDBCCreate {
public void addTable() {
Connection conn = null;
PreparedStatement ps = null;
try {
Class.forName("com.mysql.jdbc.Driver");
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/news_db", "root","119913");
String sql = "create table t_news2(id int(11) auto_increment primary key,title varchar(255),author varchar(255))";
ps = conn.prepareStatement(sql);
ps.executeUpdate();//针对DDL,是没有返回类型的。
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally{
try {
if(ps != null) ps.close();
if(conn != null) conn.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public static void main(String[] args) {
new TestJDBCCreate().addTable();
}
}
总结:
1 以上代码小美重复了5遍,重复是为了加深印象,只有深刻体会重复的辛劳,才能深刻体会后面优化的快感;
2 Select做了详细备注,后面相同都省了了注释。
3 CURD流程固定都是:
1 加载驱动 (Class.forName)–>
2 创建连接(DriverManager.getConnection(url,user,password))–>
3 预编译(PreparedStatement)–>
4 执行(executeQuery()或者executeUpdate())–>
5 释放资源(close)
4 注意导包正确。都是java.sql下面的包,不要导成com.mysql.jdbc下面的Connection
5 Select的时候用的是PreparedStatement的executeQuery()方法,其他用的是executeUpdate()方法
6 PreparedStatement是接口,而PrepareStatement是Connection的一个方法。
7 重复的过程要体会那些地方可以优化
8 executeUpdate()
在此 PreparedStatement 对象中执行 SQL 语句,该语句必须是一个 SQL 数据操作语言(Data Manipulation Language,DML)语句,比如 INSERT、UPDATE 或 DELETE 语句;或者是无返回内容的 SQL 语句,比如 DDL 语句。(这句话摘抄自API),话虽简单,要深刻体会实际运用。
9 代码中都做了输出处理,为了是验证下,避免控制台什么都没输出(除了Bug)
10 传参是重点,不把SQL语句写死,而是灵活变化,意义重大,我们注意力只用放在变化的部分,其他部分以不变应万变。
11 关闭资源是非常好的习惯,尽管现在还看不出来有什么明确效果,数据列一旦大起来,就非常重要。
好了,Beautiful!后续补充优化版本Version_1.