mysql之jdbc篇

85 阅读7分钟

一编写步骤

image.png

二 获取数据库连接

2.1 diver接口实现

  • java.sal.Driver接口是说有jdbc驱动程序接口需要实现的接口也

  • 在程序中不需要直接去访问实现了 Driver 接口的类,而是由驱动程序管理器类(java.sql.DriverManager)去调用 这些Driver实现。 Oracle的驱动:oracle.jdbc.driver.OracleDriver mySql的驱动: com.mysql.jdbc.Driver

image.png

image.png

  • 将上述jar包拷贝到Java工程的一个目录中,习惯上新建一个lib文件夹。

image.png

注意:如果是Dynamic Web Project(动态的web项目)话,则是把驱动jar放到WebContent(有的开发工具叫 WebRoot)目录中的WEB-INF目录中的lib目录下即可

2.2 加载与注册jdbc驱动

JDBC URL 用于标识一个被注册的驱动程序,驱动程序管理器通过这个 URL 选择正确的驱动程序,从而建立到 数据库的连接。 JDBC URL的标准由三部分组成,各部分间用冒号分隔。 jdbc:子协议:子名称 协议:JDBC URL中的协议总是jdbc 子协议:子协议用于标识一个数据库驱动程 子名称:一种标识数据库的方法。子名称可以依不同的子协议而变化,用子名称的目的是为了定位数据库 提供足够的信息。包含主机名(对应服务端的ip地址),端口号,数据库名

image.png 几种常用数据库的 JDBC URL MySQL的连接URL编写方式: jdbc:mysql://主机名称:mysql服务端口号/数据库名称?参数=值&参数=值 jdbc:mysql://localhost:3306/atguigu jdbc:mysql://localhost:3306/atguigu?useUnicode=true&characterEncoding=utf8(如果JDBC 程序与服务器端的字符集不一致,会导致乱码,那么可以通过参数指定服务器端的字符集) jdbc:mysql://localhost:3306/atguigu?user=root&password=123456 Oracle 9i的连接URL编写方式: jdbc:oracle:thin:@主机名称:oracle服务端口号:数据库名称 jdbc:oracle:thin:@localhost:1521:atguigu SQLServer的连接URL编写方式: jdbc:sqlserver://主机名称:sqlserver服务端口号:DatabaseName=数据库名称 jdbc:sqlserver://localhost:1433:DatabaseName=atguigu

2.3 要素三:用户名和密码

user,password可以用“属性名=属性值”方式告诉数据库 可以调用 DriverManager 类的 getConnection() 方法建立到数据库的连接

2.4数据库连接方式

1

@Test

public void test(){
  //1 提供java.sql.driver接口实现对象
  Driver driver = bull
  driver = com.mysql.jdbc.dirver();
  
  //2提供url,指明具体操作数据
  string url = "jdbc://mysql://localhost3306/text"
  
  // 3 提供properties对象指名密码 用户名
  Properties info = new Properties();
  in.setProperties("username","root");
  info.setProperties("password","123456");
  
  // 4 调用connect连接数据库
  Connection conn = driver.connect(url,info);
  
  
}

2 使用反射实例化driver 实现连接数据库

@Test

public void test(){
  //1 实例化deiver
  string classname = "com.sql.mysql.driver"
  Class clazz = Class.forName(className);
  Driver driver = (Driver) clazz.newInstance();
  
  //2提供url,指明具体操作数据
  string url = "jdbc://mysql://localhost3306/text"
  
  // 3 提供properties对象指名密码 用户名
  Properties info = new Properties();
  in.setProperties("username","root");
  info.setProperties("password","123456");
  
  // 4 调用connect连接数据库
  Connection conn = driver.connect(url,info);
  
  
}

3 使用drivermanger操作数据库

    String Driver = "com.sql.mysql.Driver"
    String url = "jdbc:mysql://locahost:3306/test"
    string username ="root"
    string password = "123456"
    
    // 实例化driver
    class clazz = class.forname(driver)
    Driver driver = (driver)clazz.newInstance();
    
    // 注册驱动
    Drivermanger.registerDriver(driver)  //可不需要
    
    //获取连接
    Connect con = Drivermanger,getConnection(url,username,password);

4 使用配置文件io流的形式进性配置(类加载器加载)

@test
public void textconnections() throw exception{
    //1 加载配置文件
    InputStream is = ConnectionTest.class.getClassLoader.GetRousoureAssStream("jdbc.properties");
    Properties pros = new Properties();
    
    String user =pros.getProperties("user")
    String password = pros.getProperty("password"); 
    String url = pros.getProperty("url"); 
    String driverClass = pros.getProperty("driverClass");
    
    //加载驱动(可有可无)
    class.forname(driverClass);
    
    // 建立连接
    Connection conn = DriverManneger.getConnection(url,user,password)
}

第3章:使用PreparedStatement实现CRUD操作

操作和访问数据库

数据库连接被用于向数据库服务器发送命令和 SQL 语句,并接受数据库服务器返回的结果。其实一个数据库连 接就是一个Socket连接。

在 java.sql 包中有 3 个接口分别定义了对数据库的调用的不同方式: Statement:用于执行静态 SQL 语句并返回它所生成结果的对象。 PrepatedStatement:SQL 语句被预编译并存储在此对象中,可以使用此对象多次高效地执行该语句。 CallableStatement:用于执行 SQL 存储过程

image.png

2 使用Statement操作数据表的弊端

  • 通过调用 Connection 对象的 createStatement() 方法创建该对象。该对象用于执行静态的 SQL 语句,并且返 回执行结果。

  • Statement 接口中定义了下列方法用于执行 SQL 语句:

int excuteupdate(String sql) 执行更新操作 update delect insert
ResultSet executeQuery(String sq) 执行查询操作SELECT

缺点

问题一:存在拼串操作,繁琐 问题二:存在SQL注入问题

对于 Java 而言,要防范 SQL 注入,只要用 PreparedStatement(从Statement扩展而来) 取代 Statement 就可 以了。

代码演示

public class statementTest{
    // 使用Statement的弊端:需要拼写sql语句,并且存在SQL注入的问题
    @test
    public void test(){
        scanner scan = new Sacnner(system.in);
        System.out.print("用户名:");
        String userName = scan.nextLine();
        System.out.print("密 码:");
        String password = scan.nextLine();
        String sql = "SELECT user,password FROM user_table WHERE USER = '" + userName + "' AND PASSWORD = '" + password
        
        User user = get(sql, User.class); 
        if (user != null) { 
            System.out.println("登陆成功!");
                } 
            else {
         System.out.println("用户名或密码错误!"); 
         } 
         
        }
    }
}

image.png

image.png

image.png

3.3 PreparedStatement的使用

PreparedStatement介绍

可以通过调用 Connection 对象的 preparedStatement(String sql) 方法获取 PreparedStatement 对象

PreparedStatement 接口是 Statement 的子接口,它表示一条预编译过的 SQL 语句

PreparedStatement 对象所代表的 SQL 语句中的参数用问号(?)来表示,调用 PreparedStatement 对象的setXxx() 方法来设置这些参数. setXxx() 方法有两个参数,第一个参数是要设置的 SQL 语句中的参数的索引(从 1 开始),第二个是设置的 SQL 语句中的参数的值

3.3.2 PreparedStatement vs Statement

PreparedStatement 能最大可能提高性能: DBServer会对预编译语句提供性能优化。因为预编译语句有可能被重复调用,所以语句在被DBServer的 编译器编译后的执行代码被缓存下来,那么下次调用时只要是相同的预编译语句就不需要编译,只要将参 数直接传入编译过的语句执行代码中就会得到执行。 在statement语句中,即使是相同操作但因为数据内容不一样,所以整个语句本身不能匹配,没有缓存语句的意 义.事实是没有数据库会对普通语句编译后的执行代码缓存。这样每执行一次都要对传入的语句编译一次。 (语法检查,语义检查,翻译成二进制命令,缓存)

PreparedStatement 可以防止 SQL 注入

3.3.3 Java与SQL对应数据类型转换

image.png

3.3.4 使用PreparedStatement实现增、删、改操作

//1 加载配置文件
    InputStream is = ConnectionTest.class.getClassLoader.GetRousoureAssStream("jdbc.properties");
    Properties pros = new Properties();
    
    String user =pros.getProperties("user")
    String password = pros.getProperty("password"); 
    String url = pros.getProperty("url"); 
    String driverClass = pros.getProperty("driverClass");
    
    //加载驱动(可有可无)
    class.forname(driverClass);
    
    // 建立连接
    Connection conn = DriverManneger.getConnection(url,user,password)
    
    // 预编译sql语句返回Perparedstatement示例
    
    String sql = "insert into test (name,email , date) values(?,?,?)"
    PerparedStatement pre = conn.PerparedStatement();
    //填充但唯独
    pre.setString(1,“张三")
    pre.setString(2,"2990895005@qq.com")
    pre.setDate(3,"2020/8/8")
    
    //执行sql
    pre.excute();
    
    //关闭
    pre.close();
    conn.colse();
一般jdbc的增删改
public class JDBCUtil{

public Connection getconnection(){
    // 一加载配置文件
    InputStream is = class.ClassLoader().getSystemStream().getSouresStream(jdbc.properties);
    Properties pres = New Properties();
    pres.load(is);
    
    //获取配置文件
    string user =is.getproperties("user")
    string url = is.getproperties("url")
    string password = is.getproperties("psd")
    string driver = is.properties("driver")
    
    // 加载驱动
    class.forname(driver)
    
    //连接数据库
    Connection conn = DriberMannger.getconnection(url,username,password)
    
    return conn
    
   }
   
   
   public class text{
       public void update(string sql , object... args){
           //1 连接数据库
           Connection conn  = JDBCUtil.getconntion();
           // 创建conn的子类statement的子类perparestament的接口
           Perparedstatement st = conn.Perparedastatement(sql);
           // 填充占位符
           1 获取元素局
           for(int i = 0 ; i < args.length(),i++){
               st.setobject(i+1,args[i])
           }
           
           st.execute();
           
           //关闭
       }
   }
    
}

查询操作
  public T List<T> getInstance(class<T> claszz,string sql,onject...args){
     Connection conn = JDBCUtil.getconnection();
     perparedstatment st =conn.ProParedstatement(sql);
     for(int i = 0; i< args.length ;i++){
         st.setobject(i+1,args[i]);
     }
     
     rs = st.executeQuery();
     
     ResultSetmetadata resd = st.getMetadata();
     
     // 6.1通过ResultSetMetaData得到columnCount,columnLabel;通过ResultSet得到列值
     int columnCount = rsmd.getColumnCount();
     
     Arrey<t> List = new Array();
     while(rs.next()){
        T t = clazz.newInstance(); 
        for (int i = 0; i < columnCount; i++) {// 遍历每一个
        // 获取列值 
        Object columnVal = rs.getObject(i + 1);
        // 获取列的别名:列的别名,使用类的属性名充当
        String columnLabel = rsmd.getColumnLabel(i + 1); 
        // 6.2使用反射,给对象的相应属性赋值 
        Field field = clazz.getDeclaredField(columnLabel); 
        field.setAccessible(true); 
        field.set(t, columnVal);
     }
     lisr.add(t);
  }