1 package com.tao.jdbc; 2 3 import java.sql.Connection; 4 import java.sql.DriverManager; 5 import java.sql.ResultSet; 6 import java.sql.Statement; 7 8 public class MainTest { 9 10 public static void main(String[] args) { 11 Connection conn=null; 12 Statement st=null; 13 ResultSet rs=null; 14 try { 15 //通过接口调用函数,使用多态,实质是调用导入的驱动重写的函数(驱动就是实现了jdbc提供的接口) 16 //这样来适应连接不同数据库的底层实现差异 17 18 /*1.注册驱动*/ 19 //com.mysql.jdbc.Driver实现了java.sql.Driver接口 20 //DriverManager.registerDriver(new com.mysql.jdbc.Driver());//lib下的mysql驱动要buildpath一下 21 //函数参数是java.sql.Driver引用指向com.mysql.jdbc.Driver对象 22 23 //一般用这句,上面.mysql.jdbc.Driver()在加载类文件的时候注册了一遍,相当于注册了两遍 24 Class.forName("com.mysql.jdbc.Driver"); 25 26 /*2.建立连接*/ 27 //getConnection()静态方法返回的是Connection对象实例,由Connection接口类型的引用接收 28 //真正的与数据库的直接的连接交互在厂商的PgConnection类中完成,该类实际实现了Connection接口 29 conn=DriverManager.getConnection("jdbc:mysql://localhost/stu_page", "root", "taotao"); 30 /*3.创建statement,使用数据库一定需要这个对象*/ 31 //createStatement()调用的应该是mysql重写的那个,因为它是接口中的抽象函数 32 st=conn.createStatement(); 33 /*4.执行查询,得到结果集*/ 34 //executeQuery()调用的应该是mysql重写的那个,因为它是接口中的抽象函数 35 String sql="select * from user"; 36 rs=st.executeQuery(sql);//查询,增删改都用executeUpdate(sql); 37 /*5.遍历查询每条记录*/ 38 while(rs.next()){ 39 int id=rs.getInt("id"); 40 String name=rs.getString("user"); 41 String pw=rs.getString("pw"); 42 System.out.println("id="+id+"==name="+name+"pwd="+pw); 43 } 44 } catch (Exception e) { 45 e.printStackTrace(); 46 }finally{ 47 JDBCUtil.release(conn, st, rs); 48 } 49 50 } 51 52 }
1 package com.tao.jdbc; 2 3 import java.sql.Connection; 4 import java.sql.ResultSet; 5 import java.sql.SQLException; 6 import java.sql.Statement; 7 8 9 10 public class JDBCUtil { 11 /** 12 * 释放资源 13 * @param conn 14 * @param st 15 * @param rs 16 */ 17 public static void release(Connection conn,Statement st,ResultSet rs){ 18 closeRs(rs); 19 closeSt(st); 20 closeConn(conn); 21 } 22 private static void closeRs(ResultSet rs){ 23 try { 24 if(rs!=null) 25 rs.close(); 26 } catch (SQLException e) { 27 e.printStackTrace(); 28 }finally{ 29 rs=null; 30 } 31 } 32 33 private static void closeSt(Statement st){ 34 try { 35 if(st!=null) 36 st.close(); 37 } catch (SQLException e) { 38 e.printStackTrace(); 39 }finally{ 40 st=null; 41 } 42 } 43 private static void closeConn(Connection conn){ 44 try { 45 if(conn!=null) 46 conn.close(); 47 } catch (SQLException e) { 48 e.printStackTrace(); 49 }finally{ 50 conn=null; 51 } 52 } 53 54 }
//优化代码
1 package com.tao.jdbc; 2 3 import java.sql.Connection; 4 import java.sql.ResultSet; 5 import java.sql.Statement; 6 7 public class MainTest { 8 9 public static void main(String[] args) { 10 Connection conn=null; 11 Statement st=null; 12 ResultSet rs=null; 13 try { 14 //通过接口调用函数,使用多态,实质是调用导入的驱动重写的函数(驱动就是实现了jdbc提供的接口) 15 //这样来适应连接不同数据库的底层实现差异 16 17 /*1.注册2.连接*/ 18 conn=JDBCUtil.getConn(); 19 /*3.创建statement,使用数据库一定需要这个对象*/ 20 //createStatement()调用的应该是mysql重写的那个,因为它是接口中的抽象函数 21 st=conn.createStatement(); 22 /*4.执行查询,得到结果集*/ 23 //executeQuery()调用的应该是mysql重写的那个,因为它是接口中的抽象函数 24 String sql="select * from user"; 25 rs=st.executeQuery(sql); 26 /*5.遍历查询每条记录*/ 27 while(rs.next()){ 28 int id=rs.getInt("id"); 29 String name=rs.getString("user"); 30 String pw=rs.getString("pw"); 31 System.out.println("id="+id+"==name="+name+"pwd="+pw); 32 } 33 } catch (Exception e) { 34 e.printStackTrace(); 35 }finally{ 36 JDBCUtil.release(conn, st, rs); 37 } 38 39 } 40 41 }
1 package com.tao.jdbc; 2 3 import java.io.InputStream; 4 import java.sql.Connection; 5 import java.sql.DriverManager; 6 import java.sql.ResultSet; 7 import java.sql.SQLException; 8 import java.sql.Statement; 9 import java.util.Properties; 10 11 12 13 public class JDBCUtil { 14 static String driverClass=null; 15 static String url=null; 16 static String name=null; 17 static String password=null; 18 //使用静态代码块读入配置信息 19 static{ 20 try { 21 //创建一个属性配置对象 22 Properties properties=new Properties(); 23 //properties文件要放在src下,使在bin目录下加载字节码文件的时候加载properties 24 //使用类加载器加载资源文件 25 InputStream is=JDBCUtil.class.getClassLoader().getResourceAsStream("jdbc.properties");//实现获取在classpath路径下的资源文件的输入流 26 27 properties.load(is); 28 //读取属性 29 driverClass=properties.getProperty("driverClass"); 30 url=properties.getProperty("url"); 31 name=properties.getProperty("name"); 32 password=properties.getProperty("password"); 33 34 35 } catch (Exception e) { 36 e.printStackTrace(); 37 } 38 } 39 public static Connection getConn(){ 40 Connection conn=null; 41 42 43 try { 44 /*1.注册驱动*/ 45 //com.mysql.jdbc.Driver实现了java.sql.Driver接口 46 //DriverManager.registerDriver(new com.mysql.jdbc.Driver());//lib下的mysql驱动要buildpath一下 47 //函数参数是java.sql.Driver引用指向com.mysql.jdbc.Driver对象 48 49 //一般用这句,上面.mysql.jdbc.Driver()在加载类文件的时候注册了一遍,相当于注册了两遍 50 Class.forName(driverClass); 51 52 /*2.建立连接*/ 53 //getConnection()静态方法返回的是Connection对象实例,由Connection接口类型的引用接收 54 //真正的与数据库的直接的连接交互在厂商的PgConnection类中完成,该类实际实现了Connection接口 55 conn=DriverManager.getConnection(url, name, password); 56 } catch (Exception e) { 57 // TODO Auto-generated catch block 58 e.printStackTrace(); 59 } 60 return conn; 61 } 62 /** 63 * 释放资源 64 * @param conn 65 * @param st 66 * @param rs 67 */ 68 public static void release(Connection conn,Statement st,ResultSet rs){ 69 closeRs(rs); 70 closeSt(st); 71 closeConn(conn); 72 } 73 private static void closeRs(ResultSet rs){ 74 try { 75 if(rs!=null) 76 rs.close(); 77 } catch (SQLException e) { 78 e.printStackTrace(); 79 }finally{ 80 rs=null; 81 } 82 } 83 84 private static void closeSt(Statement st){ 85 try { 86 if(st!=null) 87 st.close(); 88 } catch (SQLException e) { 89 e.printStackTrace(); 90 }finally{ 91 st=null; 92 } 93 } 94 private static void closeConn(Connection conn){ 95 try { 96 if(conn!=null) 97 conn.close(); 98 } catch (SQLException e) { 99 e.printStackTrace(); 100 }finally{ 101 conn=null; 102 } 103 } 104 105 }
jdbc.properities文件放在src下
内容:
driverClass=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost/stu_page
name=root
password=taotao
//////////////////////////////////////////一个实例
1 package com.tao.dao; 2 3 public interface UserDao { 4 public boolean queryUserByNameAndPassword(String name,String password); 5 }
1 package com.tao.daoImpy; 2 3 import java.sql.Connection; 4 import java.sql.PreparedStatement; 5 import java.sql.ResultSet; 6 import java.sql.SQLException; 7 import java.sql.Statement; 8 9 import com.tao.dao.UserDao; 10 import com.tao.util.JDBCUtil; 11 12 public class UserDaoImply implements UserDao{ 13 @Override 14 public boolean queryUserByNameAndPassword(String name, String password) { 15 Connection conn=null; 16 // Statement st=null; 17 PreparedStatement pst=null; 18 ResultSet result=null; 19 boolean flag=false; 20 try { 21 //注册连接 22 conn=JDBCUtil.getConn(); 23 24 // //通过连接获取statement(这种方式会导致sql注入) 25 // st=conn.createStatement(); 26 // //查找内容 27 // String sql="select * from user where username='"+name+"' and password='"+password+"';"; 28 // result=st.executeQuery(sql); 29 String sql="select * from user where username=? and password=?;"; 30 pst=conn.prepareStatement(sql); 31 pst.setString(1, name); 32 pst.setString(2, password); 33 result= pst.executeQuery(); 34 if(result.next()){ 35 flag=true; 36 } 37 } catch (SQLException e) { 38 e.printStackTrace(); 39 }finally{ 40 JDBCUtil.release(conn, pst);//JDBCUtil.release()有实现重载,且Statement是PrepareStatament的父亲,有多态 41 } 42 return flag; 43 44 } 45 46 47 48 }
1 package com.tao.test; 2 3 import org.junit.Test; 4 5 import com.tao.dao.UserDao; 6 import com.tao.daoImpy.UserDaoImply; 7 8 public class TestUser { 9 @Test 10 public void testLogin(){ 11 UserDao user=new UserDaoImply(); 12 // boolean flag=user.queryUserByNameAndPassword("小涛涛", "124 ' or '1=1");//sql注入 13 boolean flag=user.queryUserByNameAndPassword("小涛涛", "124"); 14 if(flag){ 15 System.out.println("登录成功"); 16 }else{ 17 System.out.println("登录失败"); 18 } 19 } 20 21 }
相比较以前的Statement,PrepareStatement预先处理给定的sql语句,对其进行语法检查,在
sql语句中使用?占位符,来代替后面传进来的变量,后面传进来的变量会被看成字符串,不会产生任何关键字
// Java Database Connectivity,简称JDBC。 // 是Java语言中用来规范客户端程序如何来访问数据库的应用程序接口 // 不同的数据库提供商去实现底层的访问规则 Ctrl+O 查看一个类的纲要,列出其方法和成员变量。 提示:再多按一次Ctrl+O,可以列出该类继承的方法和变量。 助记:"O"--->"Outline"--->"纲要" Ctrl+T 查看一个类的继承关系树,是自顶向下的,再多按一次Ctrl+T, 会换成自底向上的显示结构。 提示:选中一个方法名,按Ctrl+T,可以查看到有这个同名方法的父类、子类、接口。 助记:"T"------->"Tree"----->"层次树" 添加单元测试,项目右键,buildpath,add libraries,jUnit,然后在测试单元上加@Test 使用时在函数上右键(或outline视图中) 单元测试绿条代表代码逻辑没问题,但结果不一定 Dao模式:Data Access Object数据访问对象