JAVA--高级基础开发JDBC

Day03【JDBC】

 第一章JDBC

1.1  JDBC概述

  1. JDBC((Java DataBase Connectivity 数据库链接)是java操做数据库的标准解决方案,是一种执行SQL 语句的java Api, JDBC 是java访问数据库的标准规范,能够为不一样的关系型数据库提供统一的访问,它由一组java语言 编写的接口和类组成。
  2. JDBC 须要链接驱动,驱动是两个设备之间进行通讯的,知足必定数据通讯格式,数据格式由设备提供商规定,设备提供商为设备提供驱动软件,经过软件就能够与设备进行通讯,咱们以MYSQL为主,因此须要下载mysql 的驱动程序。
  3. C:\Program Files (x86)\MySQL\Connector J 8.0\mysql-connector-java-8.0.12.jar
  4. Jar 包就是Java 程序最终生成的文件格式。
  5. JDBC规范掌握四个核心对象
  • DriverManager:用于注册驱动。
  • Connection:表示与数据库建立的链接。
  • Statement:操做数据库SQL语句的对象。
  • ResultSet:结果集对象

1.2  JDBC原理

  1. Java提供访问数据库规范,而生产厂商提供规范的实现类称为驱动。
  2. Jdbc是接口,驱动是接口的实现,没有驱动将没法完成数据库的链接,从而就不能操做数据库链接,每一个数据库厂商都须要提供本身的驱动,用来链接本身公司的数据库,也就是说驱动通常使用数据库厂商提供的。
  3. 入门示例:和API讲解。
      1. 准备数据

第一步:以分类表为例:java

create table category(mysql

cid int primary key auto_increment,sql

cname varchar(20)数据库

);安全

1.2.2 导入驱动Jar架包

1.在工程中建立lib目录,存放MYSQL的驱动包。ide

2.选择MYSQL驱动包,右键选择Add  as Libray 完成Jar包的导入。工具

3.开发的步骤:this

  • 注册驱动
  • 得到链接对象
  • 得到执行SQL语句的对象
  • 执行SQL语句,并返回结果
  • 处理结果
  • 释放资源

1.2.3  API详解 注册驱动

为何要注册驱动??url

  1. 就是为了可以让java程序和目标数据库进行交互。

方式一:spa

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

通常状况下,咱们不建议使用这种方式:缘由有两个: 1是由于致使驱动被注册两次。2是强烈依赖数据库的驱动Jar包。

解决方案:

Class.forName(“ com.mysql.cj.jdbc.Driver”);

1.2.4  API详解 得到链接

  • 须要提供数据库的URL
  • user  用户名
  • password 密码

    URL 的语法规则:

    Jdbc:数据库名称://地址:端口号/数据库名

    Mysql的URL: 示例:

    Jdbc: mysql://localhost:3306/数据库名称
  • DriverMannger 驱动管理,提供了一个静态的方法:
  • static Connection getConnection(String  url,String user,String password); 就能够根据提供的链接参数获的一个链接对象。

private static String url;

    private static String user;

    private static String password;

    static {

        url="jdbc:mysql://localhost:3306/ab_wzy";

        user="root";

        password="105104";

}

  // 得到数据库的链接对象 Connection

 Connection  meth=DriverManager.getConnection(url,user,password);

1.2.4 API详解 获取Statement对象

  1. Statement 是用来执行SQL语句的,经过Connection对象中的createStatement()方法就能够获取对象,返回的就是一个Statement对象。
  2. Statement中经常使用的方法:
  • Int  exeuteUpdate(String sql):是用来执行 insert、update、delete语句的,返回值为int类型,表示的是影响的行数。
  • ResultSet  executeQuery(String  sql):是用来执行select语句的。主要是查询。      

1.2.5 处理结果集

ResultSet实际上就是一张二维的表格, 咱们能够调用boolean next()方法指向某行记录,当第一次调用next()方法时,使指向第一行记录的位置。这时就可使用ResultSet提供的getXxx(String str),方法说明:Xxx表示的是数据类型,参数表示的列名;getXxx(int index),Xxx表示数据类型,参数表示列的索引(这里的索引是从1开始的)。

1.2.5 API详解,释放资源

  1. 与IO流同样,使用后的东西都须要关闭,关闭的顺序是先获得的后关闭,后获得的先关闭。
  2. Set.close(); State.close(); Con.close():

import java.sql.Connection;

import java.sql.DriverManager;

import java.sql.SQLException;

import java.sql.Statement;

//建立表

public class JDBCdemo1 {

    private static String url;

    private static String user;

    private static String password;

    static {

        url="jdbc:mysql://localhost:3306/ab_wzy?serverTimezone=UTC&characterEnconding=utf8";

        user="root";

        password="105104";

    }

    public static void main(String[] args) {

        Connection  meth=null;

        Statement  state=null;

        try{

            //1 加载驱动

            Class.forName("com.mysql.cj.jdbc.Driver");

            // 2 得到数据库的链接对象 Connection

              meth=DriverManager.getConnection(url,user,password);

            if(meth!=null){

                System.out.println("链接成功");

            }else{

                System.out.println("链接失败");

            }

            // 3 获取Statement执行SQL语句的对象

             state=meth.createStatement();

            //4准备SQL语句

            String sql="create  table student(id int primary key auto_increment," +

                    "name  varchar(32) not null,gender varchar(32) not null,birthday date)";

            // 5 执行SQL(DDL没有返回结果)

            int  i=state.executeUpdate(sql);

            System.out.println("表建立成功");

        }catch(ClassNotFoundException  ce){

            ce.printStackTrace();

        }catch(SQLException  ce){

            ce.printStackTrace();

        }finally {

             try{

                 if(state!=null){

                     state.close();

                 }

             }catch (SQLException  ce){

                 ce.printStackTrace();

             }

            try{

                if(meth!=null){

                    meth.close();

                }

            }catch (SQLException  ce){

                ce.printStackTrace();

            }

        }

 

    }

}

package day01;

 

import java.sql.Connection;

import java.sql.DriverManager;

import java.sql.SQLException;

import java.sql.Statement;

 

//添加表信息

public class JDBCdemo2 {

    private static String url;

    private static String user;

    private static String password;

    static {

        url="jdbc:mysql://localhost:3306/ab_wzy?serverTimezone=UTC&characterEnconding=utf8";

        user="root";

        password="105104";

    }

    public static void main(String[] args){

        Connection meth=null;

        Statement state=null;

        try{

//            //1 加载驱动

//            Class.forName("com.mysql.cj.jdbc.Driver");

            // 2 得到数据库的链接对象 Connection

            meth= DriverManager.getConnection(url,user,password);

            if(meth!=null){

                System.out.println("链接成功");

            }else{

                System.out.println("链接失败");

            }

            // 3 获取Statement执行SQL语句的对象

            state=meth.createStatement();

            //4准备SQL语句

 

            String  sql1="insert  into student(name,gender,birthday)values('李文杰','男','1996-01-05')";

            String  sql2="insert  into student(name,gender,birthday)values('陈天意','男','1997-01-05')";

            String  sql3="insert  into student(name,gender,birthday)values('郭朝旭','男','1993-01-05')";

            String  sql4="insert  into student(name,gender,birthday)values('桑凤娇','女','1998-01-05')";

            String  sql5="insert  into student(name,gender,birthday)values('星仔','男','1998-01-05')";

 

            //执行SQL语句

            state.executeUpdate(sql1);

            state.executeUpdate(sql2);

            state.executeUpdate(sql3);

            state.executeUpdate(sql4);

            state.executeUpdate(sql5);

        }catch (SQLException  ce){

            ce.printStackTrace();

        }finally {

            //释放资源

            try{

                if(state!=null){

                    state.close();

                }

            }catch (SQLException  ce){

                ce.printStackTrace();

            }

            try{

                if(meth!=null){

                    meth.close();

                }

            }catch (SQLException  ce){

                ce.printStackTrace();

            }

        }

    }

}

import java.sql.*;

//查询表中的信息

public class JDBCdemo3 {

    private static String url;

    private static String user;

    private static String password;

    static{

        url="jdbc:mysql://localhost:3306/ab_wzy?serverTimezone=UTC&character=utf8";

        user="root";

        password="105104";

    }

    public static void main(String[] args){

        Connection  con=null;

        Statement   state=null;

       try{

           // 2 得到数据库的链接对象 Connection

         con=DriverManager.getConnection(url,user,password);

         //3 获的StateMent执行SQL语句的对象

           state=con.createStatement();

 

         //4 准备SQL 语句

         String  sql="select *  from  student ";

         //5 执行SQL

           ResultSet  set=state.executeQuery(sql);

           while (set.next()){

           //获取数据

               System.out.println("id"+set.getInt("id"));

               System.out.println("name"+set.getString("name"));

               System.out.println("gender"+set.getString("gender"));

               System.out.println("birthday"+set.getDate("birthday"));

           }

           set.close();

       }catch(SQLException  ce){

           ce.printStackTrace();

       }finally {

 

           try{

               if(state!=null){

                   state.close();

               }

           }catch (SQLException  ce){

               ce.printStackTrace();

           }

           try{

               if(con!=null){

                   con.close();

               }

           }catch (SQLException  ce){

               ce.printStackTrace();

           }

 

       }

    }

} package day01;

 

import java.sql.Connection;

import java.sql.DriverManager;

import java.sql.SQLException;

import java.sql.Statement;

 

//修改表中的信息

public class JDBCdemo4 {

    private  static  String url;

    private  static  String user;

    private  static  String password;

    static {

        url="jdbc:mysql://localhost:3306/ab_wzy?serverTimezone=UTC&character=utf8";

        user="root";

        password="105104";

    }

    public static void main(String[] args) {

        Connection  con=null;

        Statement  state=null;

 

        try{

            //1 获取数据库的链接对象

            con=DriverManager.getConnection(url,user,password);

            //2 获取Statement执行数据库语句的对象

            state=con.createStatement();

            // 3准备SQL 语句

            String sql="update student set name='李杰杰',gender='男生' where id=1";

            //4 执行SQL语句

            int i=state.executeUpdate(sql);

            if(i>0){

                System.out.println("修改为功");

            }else{

                System.out.println("修改失败");

            }

        }catch (SQLException  ce){

            ce.printStackTrace();

        }finally {

            try{

                if(state!=null){

                    state.close();

                }

            }catch (SQLException  ce){

                ce.printStackTrace();

            }

            try{

                if(con!=null){

                    con.close();

                }

            }catch (SQLException  ce){

                ce.printStackTrace();

            }

        }

 

    }

}

package day01;

 

import java.sql.Connection;

import java.sql.DriverManager;

import java.sql.SQLException;

import java.sql.Statement;

 

//JDBC之删除

public class JDBCdemo5 {

    private  static  String url;

    private  static  String user;

    private  static  String password;

    static{

        url="jdbc:mysql://localhost:3306/ab_wzy?serverTimezone=UTC&character=utf8";

        user="root";

        password="105104";

    }

    public static void main(String[] args) {

        Connection  con=null;

        Statement  state=null;

        try{

            // 1. 获取数据库的链接对象

            con= DriverManager.getConnection(url,user,password);

            // 2. 获取Statement 执行数据库的SQL语句

            state=con.createStatement();

            // 3. 准备SQL语句

            String sql="delete  from  student";

            // 4.执行SQL语句

            int i=state.executeUpdate(sql);

            if(i>0){

                System.out.println("删除成功");

            }else{

                System.out.println("删除失败");

            }

        }catch (SQLException  ce){

            ce.printStackTrace();

        }finally {

            try{

                if(state!=null){

                    state.close();

                }

            }catch (SQLException  ce){

                ce.printStackTrace();

            }

            try{

                if(con!=null){

                    con.close();

                }

            }catch (SQLException  ce){

                ce.printStackTrace();

            }

        }

    }

}

1.3  JDBC工具类

获取的数据库链接、关闭数据库相应的对象释放资源,这些操做在任何的增、删、改、查中都会用到,因此以上写的代码,增、删、改、查方法中存在着大量的重复性代码。为了提升代码的可重用性,咱们能够将重复代码封装成一个工具类JdbcUtils。

  • 数据库链接参数封装
  • 在src根目录下,新建立一个jdbc.properties

driverClass=com.mysql.cj.jdbc.Driver

url=jdbc:mysql://localhost:3306/ab_wzy?serverTimezone=UTC&character=utf8

user=root

password=105104

//封装JDBC工具包

import java.io.IOException;

import java.io.InputStream;

import java.sql.*;

import java.util.Properties;

public class JdbcUtils {

    private  static String  url;

    private  static String  user;

    private  static String password;

    private  static Properties P;

    static {

        P=new Properties();

        //读取属性文件

        InputStream  input=Thread.currentThread().getContextClassLoader().getResourceAsStream("jdbc.properties");

        //加载P对象

        try{

            P.load(input);

        }catch(IOException  ce){

            ce.printStackTrace();

        }

 

        //根据键获取值

       url=P.getProperty("url");

       user=P.getProperty("user");

       password=P.getProperty("password");

    }

 

    //获取数据库链接对象

    public  static Connection  getConnection()throws SQLException {

        Connection con= DriverManager.getConnection(url,user,password);

        return con;

    }

    //关闭数据库链接对象之insert  delete update的操做

    public static  void  close(Connection  con, Statement state)throws SQLException{

        con.close();;

        state.close();

    }

    //关闭数据库链接的对象之 select 查找查询的操做

    public static  void close(Connection  con, Statement  state, ResultSet  set)throws SQLException{

         set.close();

         state.close();

         con.close();

    }

    //关闭获取数据库链接对象

    public  static  void  close(Connection  con)throws SQLException{

        con.close();

    }

    // 关闭执行Statement执行SQL 语句的对象

    public static  void close(Statement  state)throws SQLException{

        state.close();

    }

    //关闭结果集对象ResultSet对象

    public static  void close(ResultSet  set)throws SQLException{

        set.close();

    }

}

1.4 综合实例,用户登陆

  1. 新建立一张用户表

create table user(

id int primary key auto_increment,

name varchar(32),

password varchar(50)

);

  1. 实现登陆

 

//案例:用户登陆

public class jdbc_demo1 {

    public static void main(String[] args) {

        Scanner  input=new Scanner(System.in);

        System.out.println("请输入用户名");

        String  name=input.nextLine();

        System.out.println("请输入密码");

        String  password=input.nextLine();

        Login(name,password);

    }

    // 用户登陆的方法

    public  static  void Login(String name,String  password){

        Connection  con=null;

        Statement  state=null;

        ResultSet  set=null;

        //经过工具类来获取链接对象

        try{

            con= JdbcUtils.getConnection();

            //获取Statement执行SQL语句的对象

            state=con.createStatement();

            //准备登陆的SQL语句。登陆就是从数据库表中查询数据

            String  sql="select  * from user  where name='"+name+"'and password='"+password+"'";

            // 执行SQL语句

            set=state.executeQuery(sql);

            if(set.next()){

                System.out.println("登陆成功,欢迎"+name);

            }else{

                System.out.println("登陆失败");

            }

        }catch(SQLException ce){

            ce.printStackTrace();

        }finally {

            try{

                JdbcUtils.close(con,state,set);

            }catch(SQLException  ce){

                ce.printStackTrace();

            }

 

        }

    }

}

  1. SQL 注入的问题

1  select * from user where name='haha' and password='a' or '1'='1'

2  name=’haha’ and password=’a’ 结果是 false

3  or ‘1’=’1’ 永远成立。True

至关于select * from user where true;

  • 咱们让用户输入的密码和 SQL 语句进行字符串拼接,用户输入的内容做为了 SQL 语句语法的一部分,改变了原有 SQL 真正的含义,以上问题称为 SQL 注入。要解决 SQL 注入就不能让用户输入的密码和咱们的 SQL 语句进行简单的字符串拼接。

1.5  PreparedStatement接口

  1. PreparedStatement 是 Statement 接口的子接口,继承了父接口中的全部方法,它是一个预编译的 SQL 语句。
  • PreparedStatement 的执行原理:
  • Statement 对象执行一条 SQL 语句都会先获得 SQL 语句发送给数据库,数据库在进行编译和执行;若是有 1 万条 SQL 语句,数据库须要编译 1 万次,执行 1 万次,效率低。
  • PreparedStatement 会先将 SQL 语句发送给数据库预编译,PreparedStatement 会引用预编译后的结果,能够屡次传入不一样的参数给 PreparedSatement 对象执行。若是有 1 万条插入语句,数据库只须要编译一次,传入 1 万次不一样的参数并执行,减小了 SQL 语句编译的次数,提供了执行效率。
  • 由于有预先编译的功能,提升 SQL 的执行效率
  • 能够有效的防止 SQL 注入的问题,安全性更高。

1.6  Connection 建立 PreparedSatement 对象

  • 方法: PreparedStatement  preareStatement(sql); 指定预编译的 SQL 语句,SQL 语句中使用占位符?表示参数,建立一个语句对象。

1.7  PreparedStatement 接口中的方法

  • int executeUpdate(); 执行 DML 语句,也就是insert、delete、update。
  • ResultSet executeQuery();执行DQL语句.用来查询select的语句。

1.8  PreparedStatement 的做用

  1. preareStatement()会先将 SQL 语句发送给数据库预编译,PreparedStatement 会引用预编译后的结果,能够屡次传入不一样的参数给 PreparedStatement 对象并执行,减小 SQL 编译次数,提升效率。
  2. 安全性更高,没有 SQL 注入的隐患
  3. 提升了程序的可读性

package day03;

 

import day02.JdbcUtils;

 

import java.sql.Connection;

import java.sql.PreparedStatement;

import java.sql.ResultSet;

import java.sql.SQLException;

import java.util.Scanner;

 

//使用reparedStatement接口是Statement的子接口

public class jdbc_demo2 {

    public static void main(String[] args) {

        Scanner input=new Scanner(System.in);

        System.out.println("请输入用户名");

        String  name=input.nextLine();

        System.out.println("请输入密码");

        String  password=input.nextLine();

        Login(name,password);

    }

    //定义用户登陆的方法

    public static  void  Login(String  name,String password){

        Connection con=null;

        PreparedStatement  statement=null;

        ResultSet set=null;

        try{

            //根据工具包获取链接对象

            con= JdbcUtils.getConnection();

            //准备登陆的SQL语句

            String  sql="select *  from user where name=? and password=?";

            //获取PreparedStatement执行的SQL语句的对象

            statement=con.prepareStatement(sql);

            //给占位符赋值

            statement.setString(1,name);

            statement.setString(2,password);

            //执行SQL语句

            set=statement.executeQuery();

            if(set.next()){

                System.out.println("登陆成功,欢迎"+name);

            }else{

                System.out.println("登陆失败");

            }

        }catch(SQLException  ce){

            ce.printStackTrace();

        }finally {

            try{

                JdbcUtils.close(con,statement,set);

            }catch(SQLException  ce){

                ce.printStackTrace();

            }

 }

    }

}

1.9 表与类之间的关系

  1. 能够把整个表看作一个类
  2. 表的一行称为记录,对应类的实例对象
  3.  表中的一行表明类的具体的实例

package day03;

 

import java.io.Serializable;

import java.util.Date;

 

public class Student implements Serializable {

    private static final long serialVersionUID = 8394954963273410188L;

    private int  id;

    private String name;

    private String gender;

    private Date birthday;

    public Student(){

 

    }

    public Student(int id, String name, String gender, Date birthday) {

        this.id = id;

        this.name = name;

        this.gender = gender;

        this.birthday = birthday;

    }

 

    public static long getSerialVersionUID() {

        return serialVersionUID;

    }

 

    public int getId() {

        return id;

    }

 

    public void setId(int id) {

        this.id = id;

    }

 

    public String getName() {

        return name;

    }

 

    public void setName(String name) {

        this.name = name;

    }

 

    public String getGender() {

        return gender;

    }

 

    public void setGender(String gender) {

        this.gender = gender;

    }

 

    public Date getBirthday() {

        return birthday;

    }

 

    public void setBirthday(Date birthday) {

        this.birthday = birthday;

    }

 

    @Override

    public String toString() {

        return "Student{" +

                "id=" + id +

                ", name='" + name + '\'' +

                ", gender='" + gender + '\'' +

                ", birthday='" + birthday + '\'' +

                '}';

    }

}

//表与类之间的关系

public class jdbc_demo3 {

    public static void main(String[] args) {

        List<Student>list=finAll();

        for(Student  ss:list){

            System.out.println(ss);

        }

    }

    //查询表中全部的信息

    public static List<Student> finAll(){

 

        Connection  con=null;

        PreparedStatement  state=null;

        ResultSet  set=null;

        List<Student>list=new ArrayList<>();

        try{

            //获取链接对象

            con= JdbcUtils.getConnection();

            //准备SQL 语句

            String sql="select  *  from  student";

            //获取PrepareStatement对象

            state=con.prepareStatement(sql);

            set=state.executeQuery();

            //先声明的对象

            Student  student=null;

            while(set.next()){

        //每次建立的对象,都会把上次对象给覆盖掉,始终保持只占用一块内存空间

               student=new Student();

               student.setId(set.getInt("id"));

               student.setName(set.getString("name"));

               student.setGender(set.getString("gender"));

               student.setBirthday(set.getDate("birthday"));

               list.add(student);

            }

        }catch(SQLException  ce){

            ce.printStackTrace();

        }

        return list;

}

}

2.0  JDBC的事物处理

1 以前咱们使用 MYSQL 的命令来处理事务,JDBC 也支持基于事务的操做。

  1. 准备数据库

Create  table  common(

Id int primary key auto_increment,

Name varchar(32) not null,

Varchar money(32) not null

)

  1. 方法:
  • void  setAutoCommit(Boolean flag): 参数时 true 或 false,若是设置为 false,表示关闭自动提交,至关于开启事务,默认是 true 自动提交。
  • void  commit(); 提交事物
  • void  rollback(); 回滚事物

事物的示例:

package day03;

import day02.JdbcUtils;

import java.sql.Connection;

import java.sql.PreparedStatement;

import java.sql.SQLException;

 

//JDBC 事物的处理

public class jdbc_demo5 {

    public static void main(String[] args) {

        Connection  con=null;

        PreparedStatement state=null;

        try{

            //获取Connection对象

            con= JdbcUtils.getConnection();

            //开启事物 默认为fasle

            con.setAutoCommit(false);

            //给李文杰扣钱

            String  sql="update common set  money=money-? where id=?";

            state=con.prepareStatement(sql);

            //给占位符赋值

            state.setString(1,"500");

            state.setInt(2,1);

            //执行SQL语句

            state.executeUpdate();

            //给郭朝旭加钱

 

            String  sql2="update common set money=money+? where id=?";

            state=con.prepareStatement(sql2);

            //给占位符赋值

            state.setString(1,"500");

            state.setInt(2,2);

            //执行SQL语句

           int i=state.executeUpdate();

           if(i>0){

               System.out.println("转帐成功");

           }

            //执行完毕,关闭事物

            con.commit();

 

        }catch(SQLException  ce){

            ce.printStackTrace();

            //若是发生异常,就回滚 rollback

            try{

                con.rollback();

            }catch(SQLException  ces){

                ces.printStackTrace();

            }

            System.out.println("转帐失败");

        }finally {

            try{

                JdbcUtils.close(con,state);

            }catch(SQLException  ce){

                ce.printStackTrace();

           }

    }

}

相关文章
相关标签/搜索