美文网首页
JDBC(Java DataBase Connection)

JDBC(Java DataBase Connection)

作者: ticktackdong | 来源:发表于2018-05-07 18:12 被阅读0次

一.Hello JDBC

1.通过Class.forName("com.mysql.jdbc.Driver");

     初始化驱动类com.mysql.jdbc.Driver
     Class.forName是把这个类加载到JVM中
     加载的时候,就会执行其中的静态初始化块,完成驱动的初始化的相关工作。

2.

 Connection c = DriverManager.getConnection(
                     "jdbc:mysql://127.0.0.1:port/databaseName?
     characterEncoding=UTF-8",user,password);
3.
        // 注意:使用的是 java.sql.Statement
        // 不要不小心使用到: com.mysql.jdbc.Statement;
        Statement s = c.createStatement();

4.

         // 准备sql语句
        // 注意: 字符串要用单引号'
        String sql = "insert into hero values(null,"+"'提莫'"+","+313.0f+","+50+")";
        s.execute(sql);

5.

    先关闭Statement后关闭Connection
    可以在finally中关闭也可使用try-with-resource的方式自动关闭连接

   finally {
        // 数据库的连接时有限资源,相关操作结束后,养成关闭数据库的好习惯
        // 先关闭Statement
        if (s != null)
            try {
                s.close();
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        // 后关闭Connection
        if (c != null)
            try {
                c.close();
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

    }



    因为Connection和Statement都实现了AutoCloseable接口
      try (
        Connection c = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/how2java?characterEncoding=UTF-8",
            "root", "admin");
        Statement s = c.createStatement();             
    )
    {
        String sql = "insert into hero values(null," + "'提莫'" + "," + 313.0f + "," + 50 + ")";
        s.execute(sql);
          //增删改都是用这种方法,查询请看下一小节
    } catch (SQLException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

6.PreparedStatement

         String sql = "insert into hero values(null,?,?,?)";
    try (Connection c = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/how2java?characterEncoding=UTF-8","root", "admin");
        // 根据sql语句创建PreparedStatement
        //与Statement区别一
        PreparedStatement ps = c.prepareStatement(sql);
    ) {
         
        // 设置参数,与Statement区别二
        ps.setString(1, "提莫");
        ps.setFloat(2, 313.0f);
        ps.setInt(3, 50);
        // 执行
        ps.execute();
  } 
 Statement需要进行字符串拼接,可读性和维护性比较差
PreparedStatement使用参数设置,可读性好,不易犯错,有预编译机制性能较快
     // Statement执行10次,需要10次把SQL语句传输到数据库端
        // 数据库要对每一次来的SQL语句进行编译处理
        for (int i = 0; i < 10; i++) {
            String sql0 = "insert into hero values(null," + "'提莫'" + ","
                    + 313.0f + "," + 50 + ")";
            s.execute(sql0);
        }
        s.close();

        // PreparedStatement 执行10次,只需要1次把SQL语句传输到数据库端
        // 数据库对带?的SQL进行预编译

        // 每次执行,只需要传输参数到数据库端
        // 1. 网络传输量比Statement更小
        // 2. 数据库不需要再进行编译,响应更快
        for (int i = 0; i < 10; i++) {
            ps.setString(1, "提莫");
            ps.setFloat(2, 313.0f);
            ps.setInt(3, 50);
            ps.execute();
        }
    PreparedStatement还可以防止SQL注入式攻击

二.基本操作

1.查询

    String sql = "select * from hero";
    ResultSet rs = s.executeQuery(sql);
    while(rs.next()){
        int id = rs.getInt("id");//可以使用字段名
        String name = rs.getString(2);//也可以使用字段的顺序,基1(Java自带的api里面唯二的基1的地方,另一个是PrepaeredStatement)
     }

2.SQL语句判断账号密码是否正确

       根据账号和密码到表中去找数据,
       如果有数据,就表明密码正确了,
       如果没数据,就表明密码错误。
       String name = "dashen";
        //正确的密码是:thisispassword
        String password = "thisispassword1";

        String sql = "select * from user where name = '" + name +"' and password = '" + password+"'";
          
        // 执行查询语句,并把结果集返回给ResultSet
        ResultSet rs = s.executeQuery(sql);
          
        if(rs.next())
            System.out.println("账号密码正确");
        else
            System.out.println("账号密码错误");

3.获取总数

       String  sql = "select count(*) from hero";
        ResultSet rs = s.executeQuery(sql);
        int total = 0;
        while (rs.next()) {
            total = rs.getInt(1);  }

4.分页查询

          String sql = "select * from hero limit " +start + "," + count;
           start 表示开始页数,count表示一页显示的总数
           start = 0, count = 5表示第一页,一共显示5条数据
           start=10,count=5表示第三页,一共显示5条数据

三.其他

1.execute与executeUpdate的区别

       在执行增,删,改时没区别
 execute可以执行查询语句,把结果集取出来,返回boolean类型,true表示执行的是查询语句
 executeUpdate不能执行查询语句返回int表示有多少条数据受到了影响

2.获取自增长id

  PreparedStatement ps = c.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS); 
//通常不用加Statement.RETURN_GENERATED_KEYS
// JDBC通过getGeneratedKeys获取该id
        ResultSet rs = ps.getGeneratedKeys();
        if (rs.next()) {
            int id = rs.getInt(1);
            System.out.println(id);
        }

3.事务

  在Mysql中,只有当表的类型是INNODB的时候,才支持事务,
   在事务中的多个操作,要么都成功,要么都失败
  通过 c.setAutoCommit(false);关闭自动提交
  //这里有多个操作,要么都成功要么都失败
  使用 c.commit();进行手动提交

4.ORM(Object Relationship Database Mapping),对象和关系数据库的映射

 简单说,一个对象,对应数据库里的一条记录

5.DAO(DataAccess Object) 数据库访问对象

6.数据库连接池

 1. ConnectionPool() 构造方法约定了这个连接池一共有多少连接

 2. 在init() 初始化方法中,创建了size条连接。 注意,这里不能使用try-with-resource这种自动关闭连接的方式,因为连接恰恰需要保持不关闭状态,供后续循环使用

 3. getConnection, 判断是否为空,如果是空的就wait等待,否则就借用一条连接出去

 4. returnConnection, 在使用完毕后,归还这个连接到连接池,并且在归还完毕后,调用notifyAll,通知那些等待的线程,有新的连接可以借用了。
  public class ConnectionPool {

List<Connection> cs = new ArrayList<Connection>();

int size;

public ConnectionPool(int size) {
    this.size = size;
    init();
}

public void init() {
      
    //这里恰恰不能使用try-with-resource的方式,因为这些连接都需要是"活"的,不要被自动关闭了
    try {
        Class.forName("com.mysql.jdbc.Driver");
        for (int i = 0; i < size; i++) {
            Connection c = DriverManager
                    .getConnection("jdbc:mysql://127.0.0.1:3306/how2java?characterEncoding=UTF-8", "root", "admin");

            cs.add(c);

        }
    } catch (ClassNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (SQLException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

public synchronized Connection getConnection() {
    while (cs.isEmpty()) {
        try {
            this.wait();
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    Connection c = cs.remove(0);
    return c;
}

public synchronized void returnConnection(Connection c) {
    cs.add(c);
    this.notifyAll();
}

}

相关文章

网友评论

      本文标题:JDBC(Java DataBase Connection)

      本文链接:https://www.haomeiwen.com/subject/fxtvrftx.html