JDBC数据库管理

1.JDBC概念

1.1. 概念:Java DataBase Connectivity Java 数据库连接, Java语言操作数据库

* JDBC本质:其实是官方(sun公司)定义的一套操作所有关系型数据库的规则,即接口。各个数据库厂商去实现这套接口,提供数据库驱动jar包。我们可以使用这套接口(JDBC)编程,真正执行的代码是驱动jar包中的实现类。

2 . 快速入门JDBC

2.1.步骤:

(1)导入驱动jar包;

(2)注册驱动;

(1)获取数据库连接对象Connection;

(1)定义sql;

(1)获取执行sql语句的对象Statement;

(1)执行sql,接收返回结果;

(1)处理结果;

(1)释放资源;

执行代码如下:

public class JdbcDemo1 {
    public static void main(String[] args) throws ClassNotFoundException, SQLException {
        //1.导入jar包
        //2.注册驱动
     Class.forName("com.mysql.jdbc.Driver");
     //3.获取数据库连接对象
        Connection conn= DriverManager.getConnection("jdbc//DESKTOP-B38BEST:3306/db1","root","root");
       //4.定义sql语句
        String sql="update account set balance = 500 where id = 1";
        //5.获取执行sql的对象Statement
        Statement stmt=conn.createStatement();
        //6.执行sql
        int count = stmt.executeUpdate(sql);
        //7.处理结果
        System.out.println(count);
        //8.释放资源
        stmt.close();
        conn.close();
    }
}

3.详解各个对象

3.1.DriverManger(类):驱动管理对象

功能:

(1)注册驱动:告诉程序该使用哪一个数据库驱动jar

static void registerDriver(Driver driver) :注册与给定的驱动程序 DriverManager 。

写代码使用:  Class.forName("com.mysql.jdbc.Driver");

在jar包E:\黑马java\M06-java2020最新\【第02部分】mysql-connector-java-5.1.37\src\com\mysql\jdbc路径下Driver.java下有块静态代码块:

   static {
        try {
            java.sql.DriverManager.registerDriver(new Driver());
        } catch (SQLException E) {
            throw new RuntimeException("Can't register driver!");
        }
    }

(2)获取数据库连接对象

*方法:static Connection getConnection(String url, String user, String password)

* 参数:

* url:指定连接的路径

* 语法:jdbc:mysql://ip地址(域名):端口号/数据库名称

* 例子:jdbc:mysql://192.168.0.24:3306/db3

* 细节:如果连接的是本机mysql服务器,并且mysql服务默认端口是3306,则url可以简写为:jdbc:mysql:///数据库名称

3.2.Connection(接口):数据库连接对象

1. 获取执行sql 的对象

 Statement   createStatement()

 PreparedStatement     prepareStatement(String sql)  

2. 管理事务:

开启事务:setAutoCommit(boolean autoCommit) :调用该方法设置参数为false,即开启事务

 提交事务:commit()

 回滚事务:rollback()

3.3.Statement(接口):执行sql对象

3.1. 执行sql

3.1.1. boolean execute(String sql) :可以执行任意的sql (了解)

3.1.2. int executeUpdate(String sql) :执行DML(insert、update、delete)语句、DDL(create,alter、drop)语句

* 返回值:影响的行数,可以通过这个影响的行数判断DML语句是否执行成功 返回值>0的则执行成功,反之,则失败。

3. ResultSet executeQuery(String sql)  :执行DQL(select)语句

2. 练习:

1. account表 添加一条记录

2. account表 修改记录

3. account表 删除一条记录

实力添加一条数据代码:


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

//向db3中account表插入如一条数据
public class JdbcDemo3 {
    public static void main(String[] args) {
        Statement stm=null;
        Connection conn=null;
        try {
            Class.forName("com.mysql.jdbc.Driver");
            String sql="insert into account values(1,'李白',3000)";
            conn = DriverManager.getConnection("jdbc:mysql:///db3","root","root");
             stm = conn.createStatement();
            int count = stm.executeUpdate(sql);
            if (count>0){
                System.out.println("添加成功");
            }else{
                System.out.println("添加失败");
            }



        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            //避免sql语句由于错误没有执行从而造成空指针异常,所以用if
            if (stm!=null){
                try {
                    stm.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }

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

        }

    }
}

3.4.ResultSet(接口):结果集对象

* boolean next(): 游标向下移动一行,判断当前行是否是最后一行末尾(是否有数据),如果是,则返回false,如果不是则返回true

* getXxx(参数):获取数据

* Xxx:代表数据类型   如: int getInt() , String getString()

* 参数:

1. int:代表列的编号,从1开始   如: getString(1)

2. String:代表列名称。 如: getDouble("balance")

* 注意:

* 使用步骤:

1. 游标向下移动一行

2. 判断是否有数据

3. 获取数据

   //循环判断游标是否是最后一行末尾。

            while(rs.next()){

                //获取数据

                //6.2 获取数据

                int id = rs.getInt(1);

                String name = rs.getString("name");

                double balance = rs.getDouble(3);

                System.out.println(id + "---" + name + "---" + balance);

            }

* 练习:

* 定义一个方法,查询emp表的数据将其封装为对象,然后装载集合,返回。

1. 定义Emp类

2. 定义方法 public List<Emp> findAll(){}

3. 实现方法 select * from emp;

示例代码:

package jdbc;

import shiyan.Emp;

import java.sql.*;
import java.util.ArrayList;
import java.util.List;

public class JdbcDemo6 {
    public static void main(String[] args) {
        System.out.println(findALL());
    }

    public static List<Emp> findALL(){
        Statement stm=null;
        Connection conn=null;
        ResultSet res=null;
        List<Emp> li=null;

        try {
            Class.forName("com.mysql.jdbc.Driver");
            String sql="select * from student";
            conn = DriverManager.getConnection("jdbc:mysql:///db1","root","root");
             stm = conn.createStatement();
             res = stm.executeQuery(sql);
//遍历结果集,封装对象,装载集合
           li = new ArrayList<Emp>();
            Emp emp=null;
            while (res.next()){
                int id = res.getInt(1);
                String name=res.getString("name");
                int age=res.getInt(3);
                String sex=res.getString("sex");
                String address=res.getString("address");
                int math=res.getInt(6);
                int english=res.getInt(7);
                emp=new Emp();
                emp.setId(id);
                emp.setName(name);
                emp.setAge(age);
                emp.setSex(sex);
                emp.setAddress(address);
                emp.setMath(math);
                emp.setEnglish(english);

                li.add(emp);

            }


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

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

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

        return li;
    }
}

3.5.PreparedStatement(接口):执行sql对象

1. SQL注入问题:在拼接sql时,有一些sql的特殊关键字参与字符串的拼接。会造成安全性问题

2. 输入用户随便,输入密码:a' or 'a' = 'a

    sql:select * from user where username = 'fhdsjkf' and password = 'a' or 'a' = 'a'

3. 解决sql注入问题:使用PreparedStatement对象来解决

4. 预编译的SQL:参数使用?作为占位符

5. 步骤:

(1) 导入驱动jar包 mysql-connector-java-5.1.37-bin.jar

(2) 注册驱动

(3) 获取数据库连接对象 Connection

(4) 定义sql

* 注意:sql的参数使用?作为占位符。 如:select * from user where username = ? and password = ?;

(5) 获取执行sql语句的对象 PreparedStatement  Connection.prepareStatement(String sql)

(6) 给?赋值:

* 方法: setXxx(参数1,参数2)

* 参数1:?的位置编号 从1 开始

* 参数2:?的值

(7)执行sql,接受返回结果,不需要传递sql语句

(8) 处理结果

(9) 释放资源

6. 注意:后期都会使用PreparedStatement来完成增删改查的所有操作

(1) 可以防止SQL注入

(2) 效率更高

7.抽取JDBC工具类 : JDBCUtils

* 目的:简化书写

* 分析:

(1) 注册驱动也抽取

(2) 抽取一个方法获取连接对象

需求:不想传递参数(麻烦),还得保证工具类的通用性。

* 解决:配置文件

jdbc.properties

url=

user=

password=

(3) 抽取一个方法释放资源

示例代码:


import util.JdbcUtils;

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

public class JdbcDemo7 {
    public static void main(String[] args) {

        Scanner sc=new Scanner(System.in);
        System.out.println("请输入用户名:");
        String user = sc.nextLine();
        System.out.println("请输入密码:");
        String password = sc.nextLine();
        boolean flag = new JdbcDemo7().login(user, password);
        if (flag){
            System.out.println("登陆成功");
        }else{
            System.out.println("输入错误");
        }


    }
    public boolean login(String user,String password){
        if (user==null||password==null){
            return false;
        }
        Connection conn=null;
        Statement stm=null;
        ResultSet res=null;
        PreparedStatement pstmt=null;
        try {
             conn= JdbcUtils.getConnection();
            String sql="select * from user where user=? and password=?";
            //获取执行sql的对象
             pstmt = conn.prepareStatement(sql);
            //给?赋值
            pstmt.setString(1,user);
            pstmt.setString(2,password);
            //执行查询,不需要传递sql
            res = pstmt.executeQuery();
           //如果有下一行,则返回true
            return res.next();


        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            JdbcUtils.close(res,stm,conn);
        }
        return false;
    }
}

4.JDBC工具类:


/**
 * JDBC工具类
 */
public class JDBCUtils {
    private static String url;
    private static String user;
    private static String password;
    private static String driver;
    /**
     * 文件的读取,只需要读取一次即可拿到这些值。使用静态代码块
     */
    static{
        //读取资源文件,获取值。

        try {
            //1. 创建Properties集合类。
            Properties pro = new Properties();

            //获取src路径下的文件的方式--->ClassLoader 类加载器
            ClassLoader classLoader = JDBCUtils.class.getClassLoader();
            URL res  = classLoader.getResource("jdbc.properties");
            String path = res.getPath();
           // System.out.println(path);///D:/IdeaProjects/itcast/out/production/day04_jdbc/jdbc.properties
            //2. 加载文件
           // pro.load(new FileReader("D:\\IdeaProjects\\itcast\\day04_jdbc\\src\\jdbc.properties"));
            pro.load(new FileReader(path));

            //3. 获取数据,赋值
            url = pro.getProperty("url");
            user = pro.getProperty("user");
            password = pro.getProperty("password");
            driver = pro.getProperty("driver");
            //4. 注册驱动
            Class.forName(driver);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }


    /**
     * 获取连接
     * @return 连接对象
     */
    public static Connection getConnection() throws SQLException {

        return DriverManager.getConnection(url, user, password);
    }

    /**
     * 释放资源
     * @param stmt
     * @param conn
     */
    public static void close(Statement stmt,Connection conn){
        if( stmt != null){
            try {
                stmt.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

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


    /**
     * 释放资源
     * @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();
            }
        }
    }

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值