• JDBC 基础用法学习


    JDBC概述

      java 数据库链接,sun公司退出的 java 访问数据库的标准规范接口

      是一种用于执行SQL语句的 java API

      可以作为多种关系数据库提供统一接口

      是一组 java 工具类和接口的组成。

    JDBC 原理

      

      JDBC是接口,驱动接口的实现,没有驱动无法完成数据库链接,而不能操作数据库。

      每个数据库厂商都需要提供自己的驱动,用来链接自己公司的数据库

      也就是说,驱动一般由数据库厂商提供。

      当然还有第三方公司专门为某一数据库提供驱动,这样的驱动往往不会是开源免费的!

      例如:mysql 驱动包 是 mysql-connector-java-5.1.28-bin.jar

       

    创建项目

    1. 修改项目的编码格式为 UTF-8

      点击 window -> workspace -> 修改UTF-8  点击应用 ok。

      

    2. 创建新项目

      

     3.  导入jar包

      首先new一个文件夹

      创建一个 lib 文件夹存放 jar 包

      将 mysql-connector-java-5.1.28-bin.jar 放入 lib 文件夹

      然后:

       

      完成之后

      

    4. 单元测试

      先创建一个包,然后建立一个类

      

    编辑代码

    package cn.study.test;
    
    import org.junit.Test;
    
    public class TestJunit {
    
        /**
         * @param args
         */
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            
        }
        
        @Test
        public void testJunit(){
            System.out.println("hello junit");
        }
        
    }

      

      右击 @Test 点击运行

      

      

      修改代码

    package cn.study.test;
    
    import org.junit.After;
    import org.junit.Before;
    import org.junit.Test;
    
    public class TestJunit {
    
        /**
         * @param args
         */
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            
        }
        
        @Test
        public void testJunit(){
            System.out.println("hello junit");
        }
        
        @Before
        public void testBefore() {
            System.out.println("before!");
        }
        
        @After
        public void testAfter() {
            System.out.println("after!");
        }
    
    }

      

     JDBC开发步骤

      1. 注册驱动

      2. 获得链接

      3. 获得语句执行者

      4. 执行 sql 语句

      5. 处理结果

      6. 释放资源

    API详解:注册驱动

    代码:

    class.forName(“com.mysql.jdbc.Driver”)

    分析步骤1 :

      JDBC规范定义驱动接口:java.sql.Driver

      mysql 驱动包提供了实现类:com.mysql.jdbc.Driver

    分析步骤2:

      DriverManager工具类提供注册驱动的方法

      方法的参数是 java.sql.Driver 所以我们可以通过如下语句进行注册

      DriverManager.registerDriver(new com.mysql.jdbc.Driver());

      以上代码不推荐使用,存在两方面不足

        1. 硬编码,后期不易于拓展和维护

        2. 驱动被注册两次

    分析步骤3:

      通常开发我们使用 Class.forName() 加载一个使用字符串描述的驱动类。

      如果使用Class.forName() 将类加载到内存,该类的静态代码将自动执行。

      通过查询 com.mysql.jdbc.Driver 源码,我们发现Driver类主动将自己进行注册。

     API 详解:获取链接

    代码:

    Connection con=DriverManager.getConnection{"jdbc:mysql://localhost:3306/mydb1","root","123456"};

      获取链接需要使用方法 DriverManager.getConnection(url , username , password)

      URL 表示链接数据库的位置(网址)

        user 表示用户名

        password :表示数据库密码

        jdbc:mysql://localhost:3306/mydb1

      URL由三部分组成,每部分用逗号隔开

        第一部分 jdbc 为固定的

        第二部分是数据库名称

        第三部分为数据库厂商制定:数据库服务地址ip、端口、数据库名称。

      拓展参数:

    jdbc:mysql://localhost:3306/mydb1?useUnicode=true&characterEncoding=UTF8

     API 详解:获取语句执行

    String sql = "insert into category(cid,cname) value ( 'c107' ,  '分类' )"

    Statemet 语句执行代码: 

    Statement stmt = con.createStatement();

    执行sql语句:

    执行  insert   update   delete 语句

    int executeUpdate(string sql); 

    执行select语句

    ResultSet executeQuery( string sql );

    执行 select 语句返回 true ,执行其他语句返回 false

    boolean execute(string sql); 

      如果返回true 需要使用 getResultSet() 获取查询结果。

      如果返回 false 需要使用 getUpdateCount() 获取影响行数。

    执行批处理:

    addBatch(string sql);
    
    clearBath();
    
    executeBatch();

    如果有参数需要在sqql语句中进行拼凑,存在sql注入问题。

    API 详解:处理结果集

    ResultSet 实际上就是一张二维表格,内部有一个行光标,光标默认位置在第一行上方,我们可以调用 rs 对象的 next() 方法把 行光标向下移动一行,当第一次调用 next() 的时候,行光标就到了第一行记录的位置,这时候就可以使用 resultSet 提供的 getXXX(int col)方法来获取指定的列数据了。

    光标移动到第一行

    rs.next();  

    获取第一行第一列数据

    rs.getInt(1);  

      

    常用的方法有:

    获取任意对象

    object getObject(int col) 

    获取字符串

    string getString(inr col) 

    获取整形

    int getInt(int col) ;

     获取双精度浮点数

    double getDouble(int col);

    API 详解:释放资源

    与IO流一样,使用后的东西都需要关闭!关闭的顺序是先得到的后关闭,后得到的先关闭!

    rs.close();
    
    stmt.close();
    
    con.close();

    案例代码:

    package cn.study.test;
    
    import java.sql.DriverManager;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    
    import java.sql.Connection;
    
    import java.sql.Statement;
    
    import org.junit.Test;
    
    /**
     * 测试sql注入问题
     * @author Administrator
     *
     */
    public class TestLogin {
    
        @Test
        public void testLogin() {
            try {
                login("wjw", "20");
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } 
        }
        
        
        /**
         * 用户登录方法
         * @param username
         * @param password
         * @throws ClassNotFoundException
         * @throws SQLException
         */
        public void login(String username,String password) throws ClassNotFoundException, SQLException {
            
            // 1. 注册驱动
            Class.forName("com.mysql.jdbc.Driver");
            // 2. 获取链接
            Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/dbtest","root","123456");
            // 3. 创建执行sql语句的对象
            Statement stmt = conn.createStatement();
            // 4. 书写sql语句
            String sql = "select * from student where "+"name='"+username+"' and age='"+password+"'";
            // 5. 执行sql语句
            ResultSet rs =  stmt.executeQuery(sql);
            // 6.对结果集进行处理
            if (rs.next()) {
                System.out.println("恭喜你 "+username +" 登录成功!");
                System.out.println(sql);
            }else{
                System.out.println("账号或密码错误!");
            }
            // 7. 释放资源
            if (rs!=null) rs.close();
            if (stmt!=null) stmt.close();
            if (conn!=null) conn.close();
        }
    }

    sql 注入问题

    防止sql攻击

      过滤用户输入的数据是否包含非法字符。—— 很难做到

      分布校验,先使用用户名来查询用户,如果查找到了在比较密码。

      使用 PrepareStatement。

    PrepareStatement是什么?

      PrepareStatement 叫预编译声明。

      PrepareStatement是Statement的子接口,可以使用 PrepareStatement 来替代 Statement。

    PrepareStatement 的好处:

      防止sql攻击

      提高代码可读性和可维护性

      提高效率

    PreparedStatement的使用:

      使用 Connection 的 prepareStatement(string sql):即创建它时就让他与一条sql锁定。

      调用PrepareStatement 的 setXXX() 系列方法为问号设置值。

      调用 executeUpdate() 或 executeQuery() 方法,但要注意,调用没有参数的方法。

    package cn.study.test;
    
    import java.sql.DriverManager;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    
    import java.sql.Connection;
    
    import java.sql.Statement;
    
    import org.junit.Test;
    
    /**
     * 测试sql注入问题
     * 
     * @author Administrator
     * 
     */
    public class TestLogin {
    
        @Test
        public void testLogin() {
            try {
                login("wjw", "20");
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    
        /**
         * 用户登录方法
         * 
         * @param username
         * @param password
         * @throws ClassNotFoundException
         * @throws SQLException
         */
        public void login1(String username, String password)
                throws ClassNotFoundException, SQLException {
    
            // 1. 注册驱动
            Class.forName("com.mysql.jdbc.Driver");
            // 2. 获取链接
            Connection conn = DriverManager.getConnection(
                    "jdbc:mysql://localhost:3306/dbtest", "root", "123456");
            // 3. 编写sql语句
            String sql = "select * from student where name=? and age=?";
            // 4. 创建预处理对象
            PreparedStatement pstmt = conn.prepareStatement(sql);
            // 5. 设置参数
            pstmt.setString(1, "fasda");
            pstmt.setString(2, "365351");
            // 6. 执行查询编辑
            ResultSet rs = pstmt.executeQuery();
            // 7.对结果集进行处理
            if (rs.next()) {
                System.out.println("恭喜你 " + username + " 登录成功!");
                System.out.println(sql);
            } else {
                System.out.println("账号或密码错误!");
            }
            // 8. 释放资源
            if (rs != null)
                rs.close();
            if (pstmt != null)
                pstmt.close();
            if (conn != null)
                conn.close();
        }
    
    }

     

     分页查询 limit

    (limit , 2 , 2)第一个起始位置,要查询(第几页-1)*第二个参数,   第二个是数量。

    项目代码https://github.com/wjw1014/JavaMysqlStudy/tree/master/my_JDBC (小白操作,仅供参考!)

  • 相关阅读:
    单位根反演学习笔记
    省选模拟测试17
    省选模拟测试16
    省选模拟测试15
    省选模拟测试14
    省选模拟测试13
    P4491 [HAOI2018]染色
    省选模拟测试12
    P4389 付公主的背包
    洛谷P3403
  • 原文地址:https://www.cnblogs.com/wjw1014/p/10849521.html
Copyright © 2020-2023  润新知