zoukankan      html  css  js  c++  java
  • JDBC总结

    ###JDBC

    学习目的:通过java代码访问数据库
    - 什么是JDBC: Java Database Connectivity java数据库连接,实际上JDBC就是java语言中一套和数据库交互的api

    - 为什么使用JDBC:因为Java程序员工作时需要连接多种数据库(Mysql、oracle,db2等)为了避免每一个数据库都学习一套新的api,Sun公司定义了JDBC接口(方法的声明),各个数据库厂商去写实现类(驱动),这样Java程序员只需要掌握JDBC的调用 即可访问任何数据库。

                                                                     (JDBC接口:一套统一标准的接口

    ####如何使用JDBC

    - 从maven私服中搜索mysql  找到 5.1.6版本的jar坐标 复制到自己的pom文件中。

    登陆达内的私服:maven.tedu.cn
    登陆阿里私服:maven.aliyun.com
    truncate table jdbc01;//删除表并且重建表

    具体操作如下:

    1. 创建maven工程
    2. 下载mysql相关jar包 
    - 首页搜索栏输入mysql 搜索
    - 找到5.1.6版本 复制坐标 到自己工程的pom.xml文件里

    - 实现代码如下:
    //1.注册驱动
    Class.forName("com.mysql.jdbc.Driver");
    //2.获取连接对象
    Connection conn = DriverManager.getConnection(
    "jdbc:mysql://localhost:3306/db3",
    "root", "root");
    //3.创建sql执行对象
    Statement stat = conn.createStatement();
    //4. 执行sql
    String sql = 
    "create table if not exists jdbct1(id int,name varchar(10))";
    stat.execute(sql);
    System.out.println("执行完成!");
    //5. 关闭资源
    stat.close();
    conn.close();

    ###JUnit 单元测试
    - 可以在一个类中添加多个可执行的方法
    - 在无参无返回值的方法上面添加 @Test 右键 run as

    package cn.tedu;
    
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.ResultSet;
    import java.sql.Statement;
    
    import org.junit.Test;
    
    public class Demo02 {
    //JUnit单元测试: 在需要运行的方法上面添加@Test注解,
    //要求方法必须是无参无返回值。
    
    @Test
    public void test01(){
    System.out.println("方法一执行");
    }
    @Test
    public void test02(){
    System.out.println("方法二执行");
    }
    
    @Test
    public void insert() throws Exception{
    Class.forName("com.mysql.jdbc.Driver");//注册驱动
    Connection conn = 
    DriverManager.getConnection(
    "jdbc:mysql://localhost:3306/db3",
    "root", "root");//获取连接
    Statement stat = conn.createStatement();//执行sql对象
    String sql = 
    "insert into jdbc01 values(null,'Tom',18)";
    stat.executeUpdate(sql);
    System.out.println("新增完成");
    //关闭资源
    stat.close();
    conn.close();
    }
    
    
    @Test
    public void delete() throws Exception{
    Class.forName("com.mysql.jdbc.Driver");//注册驱动
    Connection conn = 
    DriverManager.getConnection(
    "jdbc:mysql://localhost:3306/db3",
    "root", "root");//获取连接
    Statement stat = conn.createStatement();//执行sql对象
    String sql = 
    "delete from jdbc01 where id=1";
    stat.executeUpdate(sql);
    System.out.println("删除完成");
    //关闭资源
    stat.close();
    conn.close();
    }
    
    @Test
    public void update() throws Exception{
    Class.forName("com.mysql.jdbc.Driver");//注册驱动
    Connection conn = 
    DriverManager.getConnection(
    "jdbc:mysql://localhost:3306/db3",
    "root", "root");//获取连接
    Statement stat = conn.createStatement();//执行sql对象
    String sql = 
    "update jdbc01 set age=200 where id=2";
    stat.executeUpdate(sql);
    System.out.println("修改完成");
    //关闭资源
    stat.close();
    conn.close();
    }
    
    
    @Test
    public void findAll() throws Exception{
    
    Class.forName("com.mysql.jdbc.Driver");
    Connection conn = 
    DriverManager.getConnection(
    "jdbc:mysql://localhost:3306/db3", 
    "root", "root");
    Statement stat = conn.createStatement();
    //执行查询
    ResultSet rs = 
    stat.executeQuery("select * from jdbc01");
    while(rs.next()){
    //int id = rs.getInt("id");
    String name = rs.getString("name");
    System.out.println("name:"+name);
    }
    //关闭资源
    rs.close();
    stat.close();
    conn.close();
     
    }
    
    //查询emp表中所用员工的姓名+工资 控制台输出 
    //小明每月工资3000元
    
    
     
    
     
    
     
    
     
    
     
    
    package cn.tedu;
    /*把死的写活*/
    import java.io.IOException;
    import java.io.InputStream;
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.sql.Statement;
    import java.util.Properties;
    
    public class DBUtils2 {
    private static String driver;
    private static String url;
    private static String username;
    private static String password;//全局变量  方便调用
          static {
        //创建属性对象
      Properties prop = new Properties();
      //得到文件的输入流
      InputStream ips = 
      DBUtils2.class.getClassLoader()
      .getResourceAsStream("jdbc.properties");
      //把文件加载到属性对象中
      try {
    prop.load(ips);
    //读取数据
         driver = prop.getProperty("driver");
         url = prop.getProperty("url");
         username = prop.getProperty("username");
       } catch (IOException e) {
    e.printStackTrace();
    }
      
          }//static提高执行效率  
          
    //1. 获取连接
    public static Connection getConn() 
    throws Exception{
    
    //注册驱动
    Class.forName(driver);
    //获取连接对象
    Connection conn = 
    DriverManager.getConnection(
    url,username,password);
    return conn;
    }
    //2. 关闭资源
    public static void close(ResultSet rs,
    Statement stat,Connection conn){
    //关闭resultset
    try {
    if(rs!=null){
    rs.close();
    }
    } catch (SQLException e) {
    e.printStackTrace();
    }
    //关闭stat
    try {
    if(stat!=null){
    stat.close();
    }
    } catch (SQLException e) {
    e.printStackTrace();
    }
    //关闭连接
    try {
    if(conn!=null){
    conn.close();
    }
    } catch (SQLException e) {
    e.printStackTrace();
    }
    }
    
    }


    ####Statement的相关函数
    - execute: 可以执行任意sql 但是推荐执行DDL(什么是DDL?这个也比较重要看看前面的笔记)
    返回值代表的是 是否有结果集(了解)
    - executeUpdate: 推荐执行DML (增删改)
    返回值代表的生效行数
    - executeQuery:执行DQL
    返回值是ResultSet

    ###测试插入,修改,删除数据 代码参见 Demo02.java
     

    ###ResultSet
    - 此对象中保存着从数据库查询回的数据
    - next(): 判断是否有下一条数据有则返回true,并且内部的游标向下移动一格 
    - 从对象中获取数据的两种方式:
    1.  String name = rs.getString("name");
    2.  String name = rs.getString(2); //从1开始

    ###数据库类型和java类型对比 
    mysql数据库               java
    int                  getInt
    varchar              getString
    float/double         getFloat/getDouble
    datetime/timestamp   getDate

    ###解决jdbc乱码问题
    在url后面添加    (从?开始)
    jdbc:mysql://localhost:3306/db3?useUnicode=true&characterEncoding=UTF-8

     

    ###数据库连接池 DBCP(http://maven.tedu.cn/ ----> dbcp)
    - DataBase Connection Pool: 数据库连接池

    - 为什么使用: 如果没有连接池,每一次业务都需要和数据库服务器建立一次连接,业务处理完还要断开连接,如果有上万次业务请求则会有上万次的开关连接,频繁开关连接非常浪费资源,使用数据库连接池可以重复使用连接池中的连接,从而提高网站的响应能力。

    (在处理业务时,多次频繁地连接和断开,容易降低效率,而使用数据库连接池中的连接,可以大大提高网站的响应能力)


    - 如何使用:
    1. 下载相关jar包: 从maven.tedu.cn中搜索dbcp 
    2. 关键代码:

    //创建数据源对象
    BasicDataSource dataSource = 
    new BasicDataSource();
    //设置数据库连接信息 
    dataSource.setDriverClassName("com.mysql.jdbc.Driver");
    dataSource.setUrl("jdbc:mysql://localhost:3306/db3");
    dataSource.setUsername("root");
    dataSource.setPassword("root");
    //设置连接池参数
    dataSource.setInitialSize(3);//初始连接数量
    dataSource.setMaxActive(5);//最大连接数量
    //获取连接池中的连接
    Connection conn = dataSource.getConnection();
    
    System.out.println(conn);
    package cn.tedu;
    
    /*数据库连接池的使用*/
    import java.io.IOException;
    import java.io.InputStream;
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.sql.Statement;
    import java.util.Properties;
    
    import org.apache.commons.dbcp.BasicDataSource;
    
    public class DBUtils3 {
    private static String driver;
    private static String url;
    private static String username;
    private static String password;// 全局变量 方便调用
    private static BasicDataSource dataSource;
    static {
    // 创建属性对象
    Properties prop = new Properties();
    // 得到文件的输入流
    InputStream ips = DBUtils3.class.getClassLoader().getResourceAsStream("jdbc.properties");
    // 把文件加载到属性对象中
    try {
    prop.load(ips);
    // 读取数据
    driver = prop.getProperty("driver");
    url = prop.getProperty("url");
    username = prop.getProperty("username");
    
    // 创建基础数据源
    BasicDataSource dataSource = new BasicDataSource();
    // 设置数据库连接信息
    dataSource.setDriverClassName("com.mysql.jdbc.Driver");
    dataSource.setUrl(url);
    dataSource.setUsername(username);
    dataSource.setPassword(password);
    // 设置连接池参数
    dataSource.setInitialSize(3);// 初始化数据库连接数量
    dataSource.setMaxActive(5);// 最大连接数量
    } catch (IOException e) {
    e.printStackTrace();
    }
    
    }// static提高执行效率
    
    // 1. 获取连接
    public static Connection getConn() throws Exception {
    
    Connection conn = dataSource.getConnection();
    System.out.println(conn);
    return conn;
    }
    
    // 2. 关闭资源
    public static void close(ResultSet rs, Statement stat, Connection conn) {
    // 关闭resultset
    try {
    if (rs != null) {
    rs.close();
    }
    } catch (SQLException e) {
    e.printStackTrace();
    }
    // 关闭stat
    try {
    if (stat != null) {
    stat.close();
    }
    } catch (SQLException e) {
    e.printStackTrace();
    }
    // 关闭连接
    try {
    if (conn != null) {
    conn.close();
    }
    } catch (SQLException e) {
    e.printStackTrace();
    }
    }
    
    }

    PreparedStatement

    • 预编译的Sql执行对象
    • 好处:
    • 代码可读性更高,不容易出错(因为statement拼接字符串又麻烦又易出错)
    • 带有预编译效果,执行效率比statement略高
    • 可以避免sql注入, 因为预编译的时候已经sql语句的逻辑固定,替换?进去的内容只能以值的形式体现,如果包含逻辑sql内容 则无效

    • sql中有变量就用preparedStatement 没有变量就用statement

    • 使用方式:

    • 关键步骤:
    • //创建预编译sql执行对象
          String sql = 
                  "insert into user values(null,?,?)";
          stat = conn.prepareStatement(sql);
          //把?替换成真正的值 
          stat.setString(1, name);
          stat.setInt(2, age);
          //执行sql
          stat.executeUpdate();//返回执行有效的行数

    通过登陆案例演示sql注入

    create table tlogin (id int primary key autoincrement,username varchar(10),password varchar(10)); insert into t_login values(null,'libai','admin'),(null,'lisi','admin');

    select count(*) from t_login where username='sdfsd' and password='' or '1'='1';

    注入代码 ' or '1'='1

    批量操作 batch

    • 批量操作:可以把多次sql合并成一次执行,避免了频繁和数据库服务器进行交互,从而提高执行效率

    • 代码参见:TestBatch.java

    批量插入避免内存溢出

    //创建sql执行对象
            String sql = "insert into user values"
                    + "(null,?,?)";
            stat = conn.prepareStatement(sql);
            for(int i=0;i<100;i++){
                stat.setString(1, "name"+i);
                stat.setInt(2, i);
                //添加到批量处理
                stat.addBatch();
                if (i%20==0) {
                    stat.executeBatch();
                    //清空执行过的sql 不然会重复添加
                    stat.clearBatch();
                }
            }
            //执行sql
            stat.executeBatch();
            System.out.println("执行完成!");

    分页查询 limit 跳过数量和每页条数

    在控制台输入页数和每页的数量 得到对应的内容

    如: 输入 页数输入3 每页数量输入 5 则得到 第11-15条数据,
           关键点:即分页机制,第一个参数是跳过的页数,第二个参数是每一页多少行记录。

    事务(思路)

    1. 设置自动提交的状态 conn.setAutoCommit(true/false);
    2. 提交 conn.commit();
    3. 回滚 conn.rollback();
    成年人的世界没有那么多的童话,也没有那么多的逆袭。
  • 相关阅读:
    性能测试
    怎样开始用selenium进行自动化测试
    手机自动化测试的原理
    黑盒测试与白盒测试的区别
    白盒测试方法
    黑盒测试概念及设计方法
    接口测试的概念及常用方法
    运用c语言和Java写九九乘法表
    appium键值对的应用
    压力测试和负载测试的区别
  • 原文地址:https://www.cnblogs.com/shijinglu2018/p/9357548.html
Copyright © 2011-2022 走看看