jdbc基础

一.java 数据库连接 JDBC

1.全称:jdbc: java database connectivity 直译:java 数据库连接
2.表面意思:java连接并操作数据库 -- 解释jdbc是干什么的
3.本质含义:jdbc是sun公司制定的一套连接关系型数据库需要遵循的规范,即接口。而各个关系型数据库厂商自己来实现这个接口。程序员只需要面向接口编程。解释jdbc如何实现连接并操作数据库的.
即:jdbc通过定义了一些接口,借助接口中定义的抽象方法,来规定java要如何连接数据库,如何操作数据库。而接口中的抽象方法的具体实现,会因为数据库的不同实现方式也不一样,但是这个不是我们关心的,因为这些实现类是数据库厂商提供的,我们只需会调用接口中的方法就可以了

2.快速入门

  • 入门小案例
public class Hello3 {

    private Connection con;
    private Statement state=null;
    private ResultSet rs=null;

    @Before         //创建链接
    public void init(){
        try {
            Class.forName("com.mysql.jdbc.Driver");
            String url="jdbc:mysql://localhost:3306/db1";
            con= DriverManager.getConnection(url,"root","123456");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    @Test  //查询
    public void test1(){
        Statement state=null;
        ResultSet rs=null;
        try {
            //定义sql
            String sql="select * from emp";
            //获取执行sql的对象
             state = con.createStatement();
            //执行sql  返回一个结果集合rs--集合加上迭代器
             rs = state.executeQuery(sql);
            ArrayList<Emp> emps = new ArrayList<>();
            while (rs.next()){
                int id=rs.getInt("id");
                String name = rs.getString("NAME");
                String gender = rs.getString("gender");
                double salary = rs.getDouble("salary");
                Date join_date = rs.getDate("join_date");
                int dept_id=rs.getInt("dept_id");

                //调用有参构造
                Emp emp = new Emp(id,name,gender,salary,join_date,dept_id);
                emps.add(emp);//对象装到集合中
            }
            System.out.println(emps);
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            //释放资源  倒关
            if(rs != null){
                try {
                    rs.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            if(con != null){
                try {
                    con.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            if(state != null){
                try {
                    state.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }
    
    @After
    public void closeResources(){
        if(rs != null){
            try {
                rs.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        if(con != null){
            try {
                con.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        if(state != null){
            try {
                state.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}
  • 总结流程
  1. 导入jar包
  2. 加载驱动
  3. 构建连接对象
  4. 生成statement对象
  5. 执行sql
  6. 处理结果
  7. 释放资源

3.核心类详解

3.1 DriverManager
  1. 两个功能

1. 管理和注册驱动:查看源码解释

2. 获取连接对象

  1. 获取连接对象的方法
public class Hello1 {
    @Test           //入门案例---获取连接对象  方式3
    public void test3(){

        try{
            //1.注册驱动 Driver
            Class.forName("com.mysql.jdbc.Driver");
            //2.DriverManager 获取连接数据库对象
            String url = "jdbc:mysql://localhost:3306/shop";
            //3.使用类加载器加载jdbc.properties文件,返回一个字节流,和Properties关联在一起
            InputStream is = Hello1.class.getClassLoader().getResourceAsStream("jdbc.properties");
            Properties p = new Properties();
            p.load(is);
            Connection con = DriverManager.getConnection(url,p);
            System.out.println(con);


        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    @Test           //入门案例---获取连接对象  方式2
    public void test2(){

        try {
            //1.注册驱动 Driver
            Class.forName("com.mysql.jdbc.Driver");
            //2.DriverManager 获取连接数据库对象
            String url = "jdbc:mysql://localhost:3306/shop";
            //3.创建 Properties对像
            Properties p = new Properties();
            p.setProperty("user","root");
            p.setProperty("password","123456");
            Connection con = DriverManager.getConnection(url,p);
            System.out.println(con);


        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Test           //入门案例---获取连接对象  方式1
    public void test1(){

        try {
            //1.注册驱动 Driver
            Class.forName("com.mysql.jdbc.Driver");
            //2.DriverManager 获取连接数据库对象
            String url = "jdbc:mysql://localhost:3306/shop";
            Connection con = DriverManager.getConnection(url, "root", "123456");
            System.out.println(con);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

  1. 连接数据库四大参数

1.驱动类的字符串名com.mysq.jdbc.Driver – 在jar文件的META-INF/services文件夹下

2.连接协议路径字符串url:不同的数据库url是不同的,mysql的写法
jdbc:mysql://localhost:3306/数据库名[?参数名=参数值]

3.数据库用户名:root

4.数据库登录密码:123456

  1. url 是什么?
  • 是一个连接数据库的路径,用于标识数据库的位置

  • 包含:jdbc协议,mysql子协议,数据库所在主机名,数据库服务器的端口号,数据库名

  • 如果是本地服务器,端口号是3306,可简写:

jdbc:mysql:///数据库名

  1. 乱码处理
  • 如果使用jdbc对数据库进行操作时出现中文乱码,可以在url后指定字符集编码参数,表示让数据库以UTF-8编码来处理数据

jdbc:mysql:///数据库?characterEncoding=utf8

  • mysql8还需要指定时区

jdbc:mysql:///数据库名?useSSL=false&serverTimezone=UTC&characterEncoding=utf8

  1. 案例
@Test           //入门案例---获取连接对象
    public void test2(){

        try {
            //1.注册驱动 Driver
            Class.forName("com.mysql.jdbc.Driver");
            //2.DriverManager 获取连接数据库对象
            String url = "jdbc:mysql://localhost:3306/shop";
            //3.创建 Properties对像
            Properties p = new Properties();
            p.setProperty("user","root");
            p.setProperty("password","123456");
            Connection con = DriverManager.getConnection(url,p);
            System.out.println(con);


        } catch (Exception e) {
            e.printStackTrace();
        }
    }
3.2 Connection
  • Connection是一个接口具体的实现类由数据库厂商提供实现,代表一个连接对象
  • 功能:
  1. 获取执行sql 的对象
Statement createStatement()

PreparedStatement prepareStatement(String sql)  //预编译对象,效率更高  
3.3 Statement
  • 功能:用于发送sql语句给服务器,用于执行静态sql语句并返回结果

  • 方法

//用于发送dml语句,执行增删改的操作,返回对数据库影响的行数,还可以执行ddl语句
int executeUpdate(String sql) 

//用于发送dql语句,执行查询的操作,返回结果集对象
ResultSet executeQuery(String sql)
  • 释放资源

1.需要释放的对象 ResultSet Statement Connection
2.释放原则:先开的后关,后开的先关 ResultSet --> Statement --> Connection
3.放在finally代码块中

finally {
            //释放资源  倒关
            if(rs != null){
                try {
                    rs.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            if(con != null){
                try {
                    con.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            if(state != null){
                try {
                    state.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
3.5 ResultSet
  • 作用:封装数据库查询的结果集,并提供了遍历结果集的方法,取出每一条记录

  • 方法

boolean next()  -- 每调用一次,行光标向下移动1行,返回true表示还有下一条记录,否则返回false

数据类型 getXxx()  可以通过列名或列号获取某一行的某一列的数据
  • 代码演示---------查询员工表,并封装结果集到list集合中
 /**
     * 查询所有emp对象
     * @return
     */
    public List<Emp> findAll(){
        Connection conn = null;
        Statement stmt = null;
        ResultSet rs = null;
        List<Emp> list = null;
        try {
            //1.注册驱动
            Class.forName("com.mysql.jdbc.Driver");
            //2.获取连接
            conn = DriverManager.getConnection("jdbc:mysql:///db3", "root", "root");
            //3.定义sql
            String sql = "select * from emp";
            //4.获取执行sql的对象
            stmt = conn.createStatement();
            //5.执行sql
            rs = stmt.executeQuery(sql);
            //6.遍历结果集,封装对象,装载集合
            Emp emp = null;
            list = new ArrayList<Emp>();
            while(rs.next()){
                //获取数据
                int id = rs.getInt("id");
                String ename = rs.getString("ename");
                int job_id = rs.getInt("job_id");
                int mgr = rs.getInt("mgr");
                Date joindate = rs.getDate("joindate");
                double salary = rs.getDouble("salary");
                double bonus = rs.getDouble("bonus");
                int dept_id = rs.getInt("dept_id");
                // 创建emp对象,并赋值
                emp = new Emp();
                emp.setId(id);
                emp.setEname(ename);
                emp.setJob_id(job_id);
                emp.setMgr(mgr);
                emp.setJoindate(joindate);
                emp.setSalary(salary);
                emp.setBonus(bonus);
                emp.setDept_id(dept_id);

                //装载集合
                list.add(emp);
            }

        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            if(rs != null){
                try {
                    rs.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }

            if(stmt != null){
                try {
                    stmt.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }

            if(conn != null){
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
        return list;
    }

- 核心步骤:

1.获得连接对象
2.执行查询
3.封装查询结果集

二.jdbc使用

  1. 工具类
  • 工具类的作用:
    1.实现注册驱动 和 连接对象的获取
    2.释放资源

JDBC工具类

/**
 * JDBC工具类
 */
public class JdbcUtil {


    private static Connection con;
    private static Properties p;

    /**
     * 文件的读取,只需要读取一次即可拿到这些值。使用静态代码块
     */

    static{
        //读取资源文件,获取值。
        try {
            FileInputStream is = new FileInputStream("day05-web/src/jdbc.properties");
            p = new Properties();
            p.load(is);
            System.out.println(is);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    /**
     * 获取连接
     * @return 连接对象
     */
    public static Connection getConnection() {

        try {
            return DriverManager.getConnection(p.getProperty("url"),p);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return null;
    }
    /**
     * 释放资源
     * @param stmt
     * @param conn
     */
    public static void close(ResultSet rs, Statement stmt, Connection conn){
        if( rs != null){
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

        if( stmt != null){
            try {
                stmt.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

        if( conn != null){
            try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }

}
  1. 登录案例
public class Hello1 {
    private Connection conn;
    private Statement stmt;
    private ResultSet rs;

    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入您的用户名:");
        String name = sc.next();
        System.out.println("请输入您的密码:");
        String psw = sc.next();
        //boolean isLogin=login1(name,psw);
        boolean isLogin=login2(name,psw);
        System.out.println(isLogin);
    }

    private static boolean login1(String name, String psw) {
        if(name == null || psw == null){
            System.out.println("null");
            return false;
        }
        Connection conn = null;
        Statement stmt =  null;
        ResultSet rs = null;
        //获取连接对象
        try {
            conn = JdbcUtil.getConnection();
            //定义sql
            String sql1 = "select * from users where name = '"+name+"' and  psw = '"+psw+"'";
            System.out.println(sql1);
            //获取执行sql对象
            stmt=conn.createStatement();
            System.out.println(name);
            System.out.println(psw);
            //执行
            rs=stmt.executeQuery(sql1);
            return rs.next();//如果有下一行,则返回true
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            JdbcUtil.close(rs, stmt, conn);
        }
        return false;
    }

    //预编译对象优化登录案例
    private static boolean login2(String name, String psw){
        if(name == null || psw == null){
            System.out.println("null");
            return false;
        }
        Connection conn = null;
        PreparedStatement pstm =  null;
        ResultSet rs = null;
        //获取连接对象
        try {
             conn = JdbcUtil.getConnection();
            //定义sql
            String sql1 = "select * from users where name= ? and psw= ? ";
            System.out.println(sql1);
            //获取执行sql对象
            pstm=conn.prepareStatement(sql1);
            //之占位符赋值
            pstm.setString(1,name);
            pstm.setString(2,psw);
            //System.out.println(name);
            //System.out.println(psw);
            //执行
            rs=pstm.executeQuery();
            return rs.next();//如果有下一行,则返回true
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            JdbcUtil.close(rs, pstm, conn);
        }
        return false;
    }
}
  1. 管理事务:
  • 开启事务:setAutoCommit(boolean autoCommit) :调用该方法设置参数为false,即开启事务
  • 提交事务:commit() try的最后一行
  • 回滚事务:rollback() 放在catch代码块
public class Hello2 {
    public static void main(String[] args) {
        //获取连接对象
        Connection con=JdbcUtil.getConnection();
        //定义sql
        String sql1="update account set balance=balance-? where id=?";
        String sql2="update account set balance=balance+? where id=?";
        //获取执行sql对象
        PreparedStatement ps1=null;
        PreparedStatement ps2=null;
        try {
            //开启事务管理  ---  设置手动提交
            con.setAutoCommit(false);
            ps1=con.prepareStatement(sql1);
            ps2=con.prepareStatement(sql2);
            //赋值
            ps1.setDouble(1,500);
            ps1.setInt(2,1);
            ps2.setDouble(1,500);
            ps2.setInt(2,2);
            //执行sql
            ps1.executeUpdate();
            //主动制造异常
            //int i=7/0;
            ps2.executeUpdate();
            //提交事务
            con.commit();
        } catch (SQLException e) {
            e.printStackTrace();
            try {
                //回滚事务
                con.rollback();
            } catch (SQLException ex) {
                ex.printStackTrace();
            }
        }finally {
            JdbcUtil.close(null,ps1,con);
        }
    }
}

记得给占位符?赋值

  • 两种实现方式的差异:

1.sql语句不再是拼接参数 ,使用?代替参数

2.在创建stmt对象时,空参 ; 在创建pstm对象时,传入sql模板 --预编译

3.pstm对象还需要为?填充参数值

4.stmt对象执行sql时,需要传入sql ; pstm对象执行sql时,不用再传sql

优点:
1.PreparedStatement对象可以防止sql注入,Statement对象不可以
2.PreparedStatement对象是预编译方式执行sql,会提前检查sql是否有语法错误,因此执行效率更高

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值