JDBC学习笔记

Java连接MySQL数据库

什么是JDBC?

Java Database Connectivity(Java语言链接数据库)
JDBC的本质是什么?
 JDBC是SUN公司定制的一套接口(interface)
 接口都有调用者和实现者
 面向接口调用、面向接口实现类,这都属于面向接口编程

JDBC编程六步

第一步:注册驱动(连接所选择的数据库)
第二步:获取连接(JVM的进程和数据库进程之间的通道打开)
第三步:获取数据库操作对象(专门执行sql语句的对象)
第四步:执行SQL语句(DQL、DML…)
第五步:处理查询结果集(只有当第四步执行的是select语句的时候,才有这一步)
第六步:释放资源

注意:查询结果集的方法是 数据库对象.next() 判断将要查找的下一位是否存在,若存在就返回true,不存在就返回false,可以使用while循环判断。类似于指针,或迭代器。

第一种创建数据库对象的方法:Statement

代码实例:
这里用到了资源绑定器,方便修改数据库信息
jdbc.properties

这种方法可能会导致SQL注入
根本原因是?
用户输入的信息中含有sql语句的关键字,这些关键字参与sql语句的编译过程,
导致sql语句原意被扭曲

driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/bjpowernode?serverTimezone=UTC
user=root
password=xxxxx
1234
import java.sql.*;
import java.util.ResourceBundle;
/*
实际开发中不建议把连接数据库的信息写死到java程序中。
*/
//查询结果集
public class JDBCTest {
    public static void main(String[] args) {
        //使用资源绑定器绑定配置文件
        ResourceBundle bundle=ResourceBundle.getBundle("jdbc");
        String driver=bundle.getString("driver");
        String url=bundle.getString("url");
        String user=bundle.getString("user");
        String password=bundle.getString("password");

        Connection connection=null;
        Statement statement=null;
        ResultSet resultSet=null;
        try {
            //1、注册驱动(常用方式)
            Class.forName(driver);
            //2、连接
            connection= DriverManager.getConnection(url,user,password);
            //3、创建数据库对象
            statement=connection.createStatement();
            //4、执行SQL语句(查询结果集)
            String sql="select empno,ename,sal from emp";
            //5、查询结果集
            //专门执行DQL语句的语法,用executeQuery(),返回值ResultSet
            resultSet=statement.executeQuery(sql);
            while (resultSet.next()){
                //取数据
                //getString()方法的特点:不管数据库中数据类型是什么,都以String返回
                String empno=resultSet.getString(1);//JDBC中所有下标从1开始
                String ename=resultSet.getString(2);//第二列
                String sal=resultSet.getString("sal");//第三列(可以写列名)
                System.out.println(empno+","+ename+","+sal);
            }
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
            //6、释放资源
        } finally {
            try {
                //释放查询结果集
                if(resultSet!=null)
                resultSet.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
            try {
                //释放数据库操作对象
                if(statement!=null)
                    statement.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
            try {
                //释放连接
                if(connection!=null)
                    connection.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }
    }
}

注意:

  1. 查询结果集执行DQL语句的语法,用executeQuery(),返回值类型ResultSet
  2. 增删改执行DML语句的语法,用executeUpdate(),返回值类型 int “影响数据库中的记录条数”
  3. 释放资源,遵循从小到大依次关闭,分别对其try…catch

第二种创建数据库对象的方法:PreparedStatement(常用)

这种方法解决SQL注入
只要用户提供的信息不参与SQL语句的编译过程,问题就解决了
使用java.sql.PreparedStatement
PreparedStatement接口继承了java.sql.Statement
PreparedStatement属于预编译的数据库对象
PreparedStatement的原理是:预先对SQL语句的框架进行编译,然后载个SQL语句传“值”
PreparedStatement效率高,编译一次,执行N次

例:
实现功能:
1、需求:
模拟用户登录功能的实现
2、业务描述:
程序运行的时候,提供一个输入的入口,可以让用户输入用户名和密码
用户输入用户名和密码之后,提交信息,java程序收集到用户信息
Java程序连接数据库验证用户名和密码是否合法
合法:显示登陆成功
不合法:登录失败
代码实例:

import java.sql.*;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;

public class JDBCTest {
    private static Object Collection;
    private static Object Statement;

    public static void main(String[] args) {
        //初始化一个界面
        Map<String, String> userLogin = chuShiHuaUI();
        //验证用户名和密码
        Boolean loginSuccess=Login(userLogin);
        //输出结果
        System.out.println(loginSuccess?"登录成功":"登录失败");
    }

    /**
     * 用户登录
     * @param userLogin 用户登录信息
     * @return 返回true/false
     */
    private static Boolean Login(Map<String, String> userLogin) {
        //打标记
        boolean flag=false;

        //单独定义变量
        String u=userLogin.get("loginname");
        String p=userLogin.get("password");

        //JDBC代码
        Connection connection=null;
        PreparedStatement pStatement=null;
        ResultSet resultSet=null;

        try {
            //1、注册驱动
            Class.forName("com.mysql.cj.jdbc.Driver");
            //2、获取连接
            connection= DriverManager.getConnection(
                    "jdbc:mysql://localhost:3306/bjpowernode?serverTimezone=UTC",
                    "root",
                    "XXXXX"
            );
            //3、创建数据库对象
            //SQL语句框架 其中一个 ?表示一个占位符,一个 ?将来接收一个“值”
            String sql="select * from t_user where loginname= ? and password= ? ";
            pStatement=connection.prepareStatement(sql);
            //给占位符 ?传值(第一个问号下标是1,第二个问号下标是2)
            pStatement.setString(1,u);
            pStatement.setString(2,p);
            //4、执行sql
            resultSet=pStatement.executeQuery();
            //5、处理结果集
            if(resultSet.next()){
                flag=true;
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //6、释放资源
            try {
                if(resultSet!=null)
                resultSet.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
            try {
                if(pStatement!=null)
                statement.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
            try {if(connection!=null)
                connection.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }
        return flag;
    }

    /**
     * 初始化用户界面
     * @return 用户输入的用户名和密码信息
     */
    private static Map<String, String> chuShiHuaUI() {
        Scanner s=new Scanner(System.in);
        System.out.print("用户名:");
        String username=s.nextLine();
        System.out.print("密码:");
        String password=s.nextLine();

        Map<String,String> userLogin=new HashMap<>();
        userLogin.put("loginname",username);
        userLogin.put("password",password);

        return userLogin;
    }
}

JDBC中的事务

conn.setAutoCommit(false); 将自动提交机制改为手动提交
conn.commit(); 提交事务
conn.rollback(); 回滚事务

代码实例:

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;

/*
JDBC中事务是自动提交的,若需要控制,则可以修改为手动提交事务
*/
public class JDBCTest08 {
    public static void main(String[] args) {
        Connection conn=null;
        PreparedStatement ps=null;

        try {
            //1.注册驱动
            Class.forName("com.mysql.cj.jdbc.Driver");
            //2.创建连接
            conn= DriverManager.getConnection(
                    "jdbc:mysql://localhost:3306/bjpowernode?serverTimezone=UTC",
                    "root",
                    "xxxxx"
            );
            //将自动提交机制改为手动提交
            conn.setAutoCommit(false);
            //3.获取数据库操作对象
            //4.执行SQL语句
            String sql="update t_user set loginname=?,password=?,name=? where id=?";
            ps=conn.prepareStatement(sql);
            //给?传值
            ps.setString(1,"zhangsan");
            ps.setString(2,"123");
            ps.setString(3,"ZHANGSAN");
            ps.setString(4,"1");
            int count = ps.executeUpdate();
            System.out.println(count==1?"修改成功":"修改失败");

            ps.setString(1,"lisi");
            ps.setString(2,"456");
            ps.setString(3,"LISI");
            ps.setString(4,"2");
            count += ps.executeUpdate();
            System.out.println(count==2?"修改成功":"修改失败");

            //提交事务
            conn.commit();
        } catch (Exception e) {
            //回滚事务
            if(conn!=null){
                try {
                    conn.rollback();
                } catch (SQLException throwables) {
                    throwables.printStackTrace();
                }
            }
            e.printStackTrace();
        } finally {
            //6.释放资源
            if(ps!=null){
                try {
                    ps.close();
                } catch (SQLException throwables) {
                    throwables.printStackTrace();
                }
            }
            if(conn!=null){
                try {
                    conn.close();
                } catch (SQLException throwables) {
                    throwables.printStackTrace();
                }
            }
        }
    }
}

JDBC代码简化(创建工具类)

创建工具类

package util;

import java.sql.*;

/*
JDBC工具类,简化JDBC方法
 */
public class DBUtil {
    /*
    工具类中的构造方法都是私有的
    因为工具类中的方法都是静态的,不需要NEW对象,直接采用类名调用
    防止new对象
     */
    private DBUtil(){ }

    //静态代码块在类加载时执行,并且只执行一次
    static {
        try {
            Class.forName("com.mysql.cj.jdbc.Driver");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

    /**
     * 获取数据库连接对象
     * @return 返回连接对象
     * @throws Exception
     */
    public static Connection getConnection() throws Exception{
        //获取连接
           return DriverManager.getConnection(
                    "jdbc:mysql://localhost:3306/bjpowernode?serverTimezone=UTC",
                    "root",
                    "xxxxx"
            );
    }

    /**
     * 释放资源
     * @param conn 连接对象
     * @param ps 数据库操作对象
     * @param rs 结果集
     */
    public static void close(Connection conn, Statement ps, ResultSet rs){
        if(rs!=null){
            try {
                rs.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }
        if(ps!=null){
            try {
                ps.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }
        if(conn!=null){
            try {
                conn.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }
    }
}

测试类
1.测试DBUtil
2.测试模糊查询

import util.DBUtil;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
/*
1.测试DBUtil
2.模糊查询
 */
public class JDBCTest09 {
    public static void main(String[] args) {
        Connection conn=null;
        PreparedStatement ps=null;
        ResultSet rs=null;
        try {
            //获取连接(DBUtil类加载时就注册驱动了)
            conn= DBUtil.getConnection();
            //获取数据库操作对象
            String sql="select ename from emp where ename like ?";
            ps=conn.prepareStatement(sql);
            ps.setString(1,"_A%");
            rs=ps.executeQuery();
            while (rs.next()){
                System.out.println(rs.getString("ename"));
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //释放资源
            DBUtil.close(conn,ps,rs);
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值