JDBC概述 Java Database connectivity,Java与数据库连接的操作规范。不同的数据库都要遵循这个规范(接口)。
 
JDBC规范 掌握四个核心对象:
DriverManager:用于注册驱动。 
Connection:表示与数据库创建的连接。 
Statement:操作数据库SQL语句的对象。 
ResultSet:结果集 或 一张虚拟表。 
 
JDBC的准备工作 JDBC接口放在JDK中的 java.sql 和 javax.sql。
下载jdbc的jar包。 
导入jar包到项目中。 
 
实现JDBC操作 
注册驱动 
创建连接 
得到执行SQL语句的Statement对象 
执行SQL语句,并返回结果 
处理结果 
关闭资源 
 
DriverManager java.sql.DriverManager类:注册驱动,创建连接。
这个类在加载时就会注册驱动,所以在使用时,只需要使用Class.forName("com.mysql.jdbc.Driver");来加载一下这个类即可完成注册驱动。使用DriverManager.registerDriver(new Driver());会造成二次注册驱动。
Connection 有三种创建连接的方法:
Connection conn = DriverManager.getConnection(url,user,password);
 
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/test1?user=root&password=123456");
 
String url = "jdbc:mysql://localhost:3306/test1" ;
Properties info = new  Properties();
info.setProperty("user" ,"root" );
info.setProperty("password" ,"passwo2d@CQ" );
Connection conn = DriverManager.getConnection(url, info);
<!--0 -->
 
 
 
java的数据类型与数据库中类型的对应关系 
java 
数据库 
 
 
byte 
tityint 
 
short 
smallint 
 
int 
int 
 
long 
bigint 
 
float 
float 
 
double 
double 
 
String 
char varchar 
 
Date 
date 
 
resultSet用游标记录了当前在哪一行。
next()将游标移动到下一行。previous()将游标移动到上一行。afterLast()将光标移动到末尾,位于最后一行之后。beforeFirst()将光标移动到开头,正好位于第一行之前。
正确关闭资源 因为程序中有可能抛出异常,而抛出异常会导致后面的资源无法关闭,所以将close方法放到finally中。再用一套try/catch包裹close来处理close的方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 public  static  void  main (String[] args)  {    Connection conn = null ;     Statement stmt = null ;     ResultSet rs = null ;     try {                                             String url = "jdbc:mysql://localhost:3306/test1?serverTimezone=GMT" ;         Properties info = new  Properties();         info.setProperty("user" , "root" );         info.setProperty("password" , "passwo2d@CQ" );         conn = DriverManager.getConnection(url, info);                  stmt = conn.createStatement();                  rs = stmt.executeQuery("select * from user;" );                  while  (rs.next()) {                          System.out.print(rs.getObject(1 ) + " - " );             System.out.print(rs.getObject(2 ) + " - " );             System.out.print(rs.getObject(3 ) + " - " );             System.out.print(rs.getObject(4 ) + " - " );             System.out.print(rs.getObject(5 ) + " - " );             System.out.println();         }     }catch (Exception e){     }finally {                  if (rs != null ){             try  {                 rs.close();             } catch  (SQLException e) {                 e.printStackTrace();             }         }         if (stmt != null ){             try  {                 stmt.close();             } catch  (SQLException e) {                 e.printStackTrace();             }         }         if (conn != null ){             try  {                 conn.close();             } catch  (SQLException e) {                 e.printStackTrace();             }         }     } } 
 
抽取工具类(简化连接数据库和关闭资源操作) 创建一个同级工具类包,内放一个工具类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 package  com.Retur0.util;import  java.sql.*;public  class  DBUtils   {    private  static  String url = "jdbc:mysql://localhost:3306/test1?serverTimezone=GMT" ;     private  static  String user = "root" ;     private  static  String password = "passwo2d@CQ" ;          public  static  Connection getConnection ()  throws  SQLException  {         return  DriverManager.getConnection(url,user,password);     }     public  static  void  close (Connection conn, ResultSet rs, Statement stmt)  {         if (rs!=null ) {             try  {                 rs.close();             } catch  (SQLException e) {                 e.printStackTrace();             }         }         if (conn!=null ) {             try  {                 conn.close();             } catch  (SQLException e) {                 e.printStackTrace();             }         }         if (stmt!=null ) {             try  {                 stmt.close();             } catch  (SQLException e) {                 e.printStackTrace();             }         }     } } 
 
之后连接和操作数据库的代码就简化如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 package  demo;import  com.Retur0.util.DBUtils;import  java.sql.*;public  class  demo02   {    public  static  void  main (String[] args)  {         Connection conn = null ;         Statement stmt = null ;         ResultSet rs = null ;         try {             conn = DBUtils.getConnection();             stmt = conn.createStatement();             rs = stmt.executeQuery("select * from user" );             while  (rs.next()) {                                  System.out.print(rs.getObject(1 )+"\t" );                 System.out.print(rs.getObject(2 )+"\t" );                 System.out.print(rs.getObject(3 )+"\t" );                 System.out.print(rs.getObject(4 )+"\t" );                 System.out.println(rs.getObject(5 )+"\t" );             }         }catch (Exception e){             e.printStackTrace();         }finally {             DBUtils.close(conn, rs, stmt);         }     } } 
 
插入数据 使用预处理的Statement对象,用占位符代替要处理的数据。使用设置方法挨个设置占位符处的数据。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 public  static  void  main (String[] args)  {    Connection conn = null ;     PreparedStatement ps = null ;     try  {         conn = DBUtils.getConnection();                  String sql = "insert into user (id,name,password,email,birthday) values (?,?,?,?,?)" ;         ps = conn.prepareStatement(sql);                  ps.setInt(1 , 4 );         ps.setString(2 , "name03" );         ps.setString(3 , "123456" );         ps.setString(4 , "11111@qq.com" );                  ps.setDate(5 , new  java.sql.Date(System.currentTimeMillis()));         int  r = ps.executeUpdate();         System.out.println("受影响的行数:" +r);     }catch (Exception e){         e.printStackTrace();     }finally {         DBUtils.close( conn, null , ps);     } } 
 
更改数据 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 public  static  void  main (String[] args)  {         Connection conn = null ;     PreparedStatement ps = null ;     try  {         conn = DBUtils.getConnection();                  String sql = "update user set password=?, email=? where name=?" ;         ps = conn.prepareStatement(sql);                  ps.setString(1 , "000000" );         ps.setString(2 , "xxx@qq.com" );         ps.setString(3 , "name02" );         int  r = ps.executeUpdate();         System.out.println("受影响的行数:" +r);     }catch (Exception e){         e.printStackTrace();     }finally {         DBUtils.close( conn, null , ps);     } } 
 
删除数据 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 public  static  void  main (String[] args)  {    Connection conn = null ;     PreparedStatement ps = null ;     try  {         conn = DBUtils.getConnection();                  String sql = "delete from user where id=?" ;         ps = conn.prepareStatement(sql);                  ps.setInt(1 , 4 );         int  r = ps.executeUpdate();         System.out.println("受影响的行数:" +r);     }catch (Exception e){         e.printStackTrace();     }finally {         DBUtils.close( conn, null , ps);     } } 
 
查询数据 查询不使用预处理Statement。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 public  static  void  main (String[] args)  {         Connection conn = null ;     Statement stmt = null ;     ResultSet rs = null ;     try  {         conn = DBUtils.getConnection();         stmt = conn.createStatement();         rs = stmt.executeQuery("select * from user" );         List<User> list = new  ArrayList<User>();                  while  (rs.next()){                                       User user = new  User();             user.setId(rs.getInt("id" ));             user.setName(rs.getString("name" ));             user.setEmail((rs.getString("email" )));             user.setBirthday((rs.getDate("birthday" )));             list.add(user);         }                  for (User u : list){             System.out.println(u.toString());         }     }catch (Exception e){         e.printStackTrace();     }finally {         DBUtils.close(conn, rs, stmt);     } } 
 
将数据封装成的模型起码要保存数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 public  class  User   {    private  int  id;     private  String name;     private  String password;     private  String email;     private  Date birthday;     public  int  getId ()   {         return  id;     }     public  String getName ()   {         return  name;     }     public  String getPassword ()   {         return  password;     }     public  String getEmail ()   {         return  email;     }     public  Date getBirthday ()   {         return  birthday;     }     public  void  setId (int  id)   {         this .id = id;     }     public  void  setName (String name)   {         this .name = name;     }     public  void  setPassword (String password)   {         this .password = password;     }     public  void  setEmail (String email)   {         this .email = email;     }     public  void  setBirthday (Date birthday)   {         this .birthday = birthday;     }     public  String toString ()  {         return  id + " "  + name + " "  + password + " "  + email + " "  + birthday;     } } 
 
SQL注入 如果把占位符换成字符串变量,用拼接的方法完成sql语句,会有注入的问题。
这个问题就是,如果输入的字符串利用了sql语句的规则成为了字符串的一部分,导致信息校验出现问题(比如查询出不存在的数据)。被注入了其它的sql语句进来。
解决办法就是使用预加载Statement和占位符。