//解决SQL注入攻击的方案 private static void login2() { try{ Class.forName("com.mysql.jdbc.Driver"); String url="jdbc:mysql:///cgb2104?characterEncoding=utf8"; Connection conn = DriverManager.getConnection(url, "root", "root"); // Statement st = conn.createStatement();不行,不安全,会被SQL攻击 String user = new Scanner(System.in).nextLine();//用户输入jack'# String pwd = new Scanner(System.in).nextLine(); //?叫占位符 ,SQL的骨架 String sql ="select * from user2 where name=? and password=?";//参数使用问号 //先把SQL骨架发给数据库执行 PreparedStatement ps = conn.prepareStatement(sql); //给SQL里的? 设置参数 ps.setString(1,user);//给第一个?设置值是user,对应参数类型,第几个问号 ps.setString(2,pwd);//给第二个?设置值是pwd ResultSet rs = ps.executeQuery();//去掉sql参数,执行拼接好的SQL,返回结果集 if(rs.next()){ System.out.println("登录成功~"); }else{ System.out.println("登录失败~"); } ps.close(); conn.close(); }catch(Exception e){ e.printStackTrace();//有异常,直接打印异常信息 //System.out.println("执行失败。。。");//上线 } }
Class.forName注册驱动,是java.sql.Driver.class的源码使用静态代码块创建对象
static { try { DriverManager.registerDriver(new Driver()); } catch (SQLException var1) { throw new RuntimeException("Can't register driver!"); } }
**加粗样式写了创建了,那不写呢?怎么不写也能执行呢?
Java提供了SPI机制,用户可以自行配置类,JDBC高版本驱动就都引入了这个支持。如果用户使用了Class.forName方式就自己指定了驱动,如果未写这句话,则Java自动去META-INF/services/java.sql.Driver文件中找启动类。