zoukankan      html  css  js  c++  java
  • 2017.6.27 jdbc基本使用

    参考来自:http://www.runoob.com/w3cnote/jdbc-use-guide.html

    1.jdbc的执行流程

    JDBC API 允许用户访问任何形式的表格数据,尤其是存储在关系数据库中的数据。

    执行流程:

    • 连接数据源,如:数据库。

    • 为数据库传递查询和更新指令。

    • 处理数据库响应并返回的结果。

    2.jdbc的编程步骤

    2.1 加载驱动程序

    Class.forName(driverClass)
    //加载MySql驱动
    Class.forName("com.mysql.jdbc.Driver")
    //加载Oracle驱动
    Class.forName("oracle.jdbc.driver.OracleDriver")

    2.2 获得数据库连接

    DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/imooc", "root", "root");

    2.3 创建StatementPreparedStatement对象

    conn.createStatement();
    conn.prepareStatement(sql);

    2.4 执行操作

      1 import java.sql.Connection;
      2 import java.sql.DriverManager;
      3 import java.sql.ResultSet;
      4 import java.sql.Statement;
      5 
      6 public class DbUtil {
      7 
      8     public static final String URL = "jdbc:mysql://localhost:3306/imooc";
      9     public static final String USER = "liulx";
     10     public static final String PASSWORD = "123456";
     11 
     12     public static void main(String[] args) throws Exception {
     13         //1.加载驱动程序
     14         Class.forName("com.mysql.jdbc.Driver");
     15         //2. 获得数据库连接
     16         Connection conn = DriverManager.getConnection(URL, USER, PASSWORD);
     17         //3.操作数据库,实现增删改查
     18         Statement stmt = conn.createStatement();
     19         ResultSet rs = stmt.executeQuery("SELECT user_name, age FROM imooc_goddess");
     20         //如果有数据,rs.next()返回true
     21         while(rs.next()){
     22             System.out.println(rs.getString("user_name")+" 年龄:"+rs.getInt("age"));
     23         }
     24     }
     25 }
    

    3.完整示例

     1 public class DbUtil {
     2     public static final String URL = "jdbc:mysql://localhost:3306/imooc";
     3     public static final String USER = "liulx";
     4     public static final String PASSWORD = "123456";
     5     private static Connection conn = null;
     6     static{
     7         try {
     8             //1.加载驱动程序
     9             Class.forName("com.mysql.jdbc.Driver");
    10             //2. 获得数据库连接
    11             conn = DriverManager.getConnection(URL, USER, PASSWORD);
    12         } catch (ClassNotFoundException e) {
    13             e.printStackTrace();
    14         } catch (SQLException e) {
    15             e.printStackTrace();
    16         }
    17     }
    18 
    19     public static Connection getConnection(){
    20         return conn;
    21     }
    22 }
      1 package liulx.dao;
      2 
      3 import liulx.db.DbUtil;
      4 import liulx.model.Goddess;
      5 
      6 import java.sql.Connection;
      7 import java.sql.ResultSet;
      8 import java.sql.SQLException;
      9 import java.sql.Statement;
     10 import java.util.ArrayList;
     11 import java.util.List;
     12 
     13 public class GoddessDao {
     14     //增加
     15     public void addGoddess(Goddess g) throws SQLException {
     16         //获取连接
     17         Connection conn = DbUtil.getConnection();
     18         //sql
     19         String sql = "INSERT INTO imooc_goddess(user_name, sex, age, birthday, email, mobile,"+
     20             "create_user, create_date, update_user, update_date, isdel)"
     21                 +"values("+"?,?,?,?,?,?,?,CURRENT_DATE(),?,CURRENT_DATE(),?)";
     22         //预编译
     23         PreparedStatement ptmt = conn.prepareStatement(sql); //预编译SQL,减少sql执行
     24 
     25         //传参
     26         ptmt.setString(1, g.getUser_name());
     27         ptmt.setInt(2, g.getSex());
     28         ptmt.setInt(3, g.getAge());
     29         ptmt.setDate(4, new Date(g.getBirthday().getTime()));
     30         ptmt.setString(5, g.getEmail());
     31         ptmt.setString(6, g.getMobile());
     32         ptmt.setString(7, g.getCreate_user());
     33         ptmt.setString(8, g.getUpdate_user());
     34         ptmt.setInt(9, g.getIsDel());
     35 
     36         //执行
     37         ptmt.execute();
     38     }
     39 
     40     public void updateGoddess(){
     41         //获取连接
     42         Connection conn = DbUtil.getConnection();
     43         //sql, 每行加空格
     44         String sql = "UPDATE imooc_goddess" +
     45                 " set user_name=?, sex=?, age=?, birthday=?, email=?, mobile=?,"+
     46                 " update_user=?, update_date=CURRENT_DATE(), isdel=? "+
     47                 " where id=?";
     48         //预编译
     49         PreparedStatement ptmt = conn.prepareStatement(sql); //预编译SQL,减少sql执行
     50 
     51         //传参
     52         ptmt.setString(1, g.getUser_name());
     53         ptmt.setInt(2, g.getSex());
     54         ptmt.setInt(3, g.getAge());
     55         ptmt.setDate(4, new Date(g.getBirthday().getTime()));
     56         ptmt.setString(5, g.getEmail());
     57         ptmt.setString(6, g.getMobile());
     58         ptmt.setString(7, g.getUpdate_user());
     59         ptmt.setInt(8, g.getIsDel());
     60         ptmt.setInt(9, g.getId());
     61 
     62         //执行
     63         ptmt.execute();
     64     }
     65 
     66     public void delGoddess(){
     67         //获取连接
     68         Connection conn = DbUtil.getConnection();
     69         //sql, 每行加空格
     70         String sql = "delete from imooc_goddess where id=?";
     71         //预编译SQL,减少sql执行
     72         PreparedStatement ptmt = conn.prepareStatement(sql);
     74         //传参
     75         ptmt.setInt(1, id);
     77         //执行
     78         ptmt.execute();
     79     }
    80 //批量查询 81 public List<Goddess> query() throws SQLException { 82 Connection conn = DbUtil.getConnection(); 83 Statement stmt = conn.createStatement(); ??? PreparedStatement和statement的区别是什么???见下面(ps:这里不需要参数,可以直接用statement)。 84 ResultSet rs = stmt.executeQuery("SELECT user_name, age FROM imooc_goddess"); 85 86 List<Goddess> gs = new ArrayList<Goddess>(); 87 Goddess g = null; 88 while(rs.next()){ 89 g = new Goddess(); 90 g.setUser_name(rs.getString("user_name")); 91 g.setAge(rs.getInt("age")); 93 gs.add(g); 94 } 95 return gs; 96 }
    97 //单个查询 98 public Goddess querySingle(){ 99 Goddess g = null; 100 //获取连接 101 Connection conn = DbUtil.getConnection(); 102 //sql, 每行加空格 103 String sql = "select * from imooc_goddess where id=?"; 104 //预编译SQL,减少sql执行 105 PreparedStatement ptmt = conn.prepareStatement(sql);??? PreparedStatement和statement的区别是什么???见下面。 106 //传参 107 ptmt.setInt(1, id); 108 //执行 109 ResultSet rs = ptmt.executeQuery(); 110 while(rs.next()){ 111 g = new Goddess(); 112 g.setId(rs.getInt("id")); 113 g.setUser_name(rs.getString("user_name")); 114 g.setAge(rs.getInt("age")); 115 g.setSex(rs.getInt("sex")); 116 g.setBirthday(rs.getDate("birthday")); 117 g.setEmail(rs.getString("email")); 118 g.setMobile(rs.getString("mobile")); 119 g.setCreate_date(rs.getDate("create_date")); 120 g.setCreate_user(rs.getString("create_user")); 121 g.setUpdate_date(rs.getDate("update_date")); 122 g.setUpdate_user(rs.getString("update_user")); 123 g.setIsDel(rs.getInt("isdel")); 124 } 125 return g; 126 } 127 }

    4.PreparedStatement和statement的区别是什么

    参考来自:http://www.importnew.com/5006.html

    PreparedStatement是用来执行SQL查询语句的API之一。

    Java提供了 StatementPreparedStatement 和 CallableStatement三种方式来执行查询语句:

    Statement 用于通用查询
    PreparedStatement 用于执行参数化查询
    CallableStatement则是用于存储过程

    有几个面试常用的问题:

    1 Statement与PreparedStatement的区别?
    2 为什么要用PreparedStatement?
    3 使用PreparedStatement有什么样的优势?
    4 PreparedStatement又是如何避免SQL注入攻击的?

    4.1 Statement与PreparedStatement的区别

    前面已经提过,Statement执行通用化查询,PreparedStatement执行参数化查询。

    1 conn.createStatement();
    2 conn.prepareStatement(sql);

    4.2 用PreparedStatement的优势

    使用PreparedStatement,数据库系统会对sql语句进行预编译处理(如果JDBC驱动支持的话),预处理语句将被预先编译好,这条预编译的sql查询语句能在将来的查询中重用,这样一来,它比Statement对象生成的查询速度更快。

    同时,它还可以防止SQL注入式攻击。

    4.3 PreparedStatement如何避免SQL注入攻击

    在SQL注入攻击里,恶意用户通过SQL元数据绑定输入,比如:某个网站的登录验证SQL查询代码为:

    strSQL = "SELECT * FROM users WHERE name = '" + userName + "' and pw = '"+ passWord +"';"

    恶意填入:

    userName = "1' OR '1'='1";
    passWord = "1' OR '1'='1";

    那么sql语句就变成了:

    strSQL = "SELECT * FROM users WHERE name = '1' OR '1'='1' and pw = '1' OR '1'='1';"

    即:(因此可以无账号密码直接登录。)

    strSQL = "SELECT * FROM users;"

    然而使用PreparedStatement的参数化的查询可以阻止大部分的SQL注入。在使用参数化查询的情况下,数据库系统(eg:MySQL)不会将参数的内容视为SQL指令的一部分来处理,而是在数据库完成SQL指令的编译后,才套用参数运行,因此就算参数中含有破坏性的指令,也不会被数据库所运行。

    4.4 PreparedStatement的局限

    为了防止SQL注入攻击,PreparedStatement不允许一个占位符(?)有多个值,在执行有**IN**子句查询的时候这个问题变得棘手起来。下面这个SQL查询使用PreparedStatement就不会返回任何结果:

    SELECT * FROM loan WHERE loan_type IN (?)
    preparedSatement.setString(1, "'personal loan', 'home loan', 'gold loan'");

    如何解决呢?作者写在下篇博客里???下篇博客在哪???

    4.5 PreparedStatement总结

    当然可以使用Statement对象用来做做测试。但是在生产环境下一定要考虑使用 PreparedStatement 。

    1. PreparedStatement可以写参数化查询,比Statement能获得更好的性能。
    2. 对于PreparedStatement来说,数据库可以使用已经编译过及定义好的执行计划,这种预处理语句查询比普通的查询运行速度更快。
    3. PreparedStatement可以阻止常见的SQL注入式攻击。
    4. PreparedStatement可以写动态查询语句
    5. “?” 叫做占位符。
    7. PreparedStatement查询默认返回FORWARD_ONLY的ResultSet,你只能往一个方向移动结果集的游标。当然你还可以设定为其他类型的值如:”CONCUR_READ_ONLY”。
    8. 不支持预编译SQL查询的JDBC驱动,在调用connection.prepareStatement(sql)的时候,它不会把SQL查询语句发送给数据库做预处理,
      而是等到执行查询动作的时候(调用executeQuery()方法时)才把查询语句发送个数据库,这种情况和使用Statement是一样的。 9. 占位符的索引位置从1开始而不是0,如果填入0会导致*java.sql.SQLException invalid column index*异常。
    所以如果PreparedStatement有两个占位符,那么第一个参数的索引时1,第二个参数的索引是2.
  • 相关阅读:
    Linux 安装nginx
    Linux服务器svn与项目同步
    Linux服务器安装svn
    Thinkphp5模板继承
    Thinkphp5 Route用法
    一键切换hosts文件
    lnmp手动新建虚拟机
    wamp 配置虚拟主机
    百度编辑器
    百度编辑器:上传图片二
  • 原文地址:https://www.cnblogs.com/lyh421/p/7085757.html
Copyright © 2011-2022 走看看