有位教育家说得好:教育的真正目的就是让你忘掉你所学的所有之后还剩下的东西。在技术行业好像尤其如此,忘掉所学的所有技能,还剩下什么呢?
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.