JavaEE基础(二)JDBC存取数据

JDBC(Java DataBase Connectivity)

​ 作用:是Java与数据库之间的桥梁。可为多种关系型DBMS提供统一的访问方式。

JDBC简单架构:
在这里插入图片描述

JDBC基本流程:

  1. 与数据库建立连接。
  2. 使用sql进行CUDR(增删改查)。
  3. 返回处理结果。

初始化驱动

try {
    Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException e) {
    e.printStackTrace();
}

连接数据库

使用DriverManager.getConnection(URL,userName,userPwd)获取连接。

url是数据库连接字符串。“jdbc:mysql://127.0.0.1:3306/数据库名”

userName是用户名,也就是数据库用户的用户名。(根用户名为root)

userPwd是用户密码。

try{
    Connection connection = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/school", "root", "123456");
}catch (SQLException e) {
    e.printStackTrace();
}

CUDR

增删改

Connection connection = null;
Statement stmt = null;
try{
    connection = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/school", "root", "123456");
    stmt = connection.getStatement();
    String sql = "insert into/delete from/update set......";
    stmt.execute(sql);
    //或者:int n = stmt.executeUpdate(sql),n为成功执行的数据元组数。
}catch (SQLException e) {
    e.printStackTrace();
}finally{
    stmt.close();
    connection.close();
}

使用statement可以进行sql的执行,但是使用statement会导致一个安全问题:sql注入。也就是在查询时写上用户名为322OR1=1–,则1=1永真并且–屏蔽掉后面的代码了,这就导致了用户名密码永远正确。

为了解决这个问题,使用预编译statement(PrepareStatement)

Connection connection = null;
PrepareStatement pstmt = null;
try{
    connection = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/school", "root", "123456");
    pstmt = connection.getPrepareStatement();
    String sql = "insert into/delete from/update set...?, ?, ?";
    pstmt.setInt(1, ...);
    pstmt.setInt(2, ...);
    pstmt.setString(3, ...);
    pstmt.execute(sql);
    //或者:int n = pstmt.executeUpdate(sql),n为成功执行的数据元组数。
}catch (SQLException e) {
    e.printStackTrace();
}finally{
    pstmt.close();
    connection.close();
}

注意:setInt的下标时从1开始的。下标也可以使用数据库表中字段。

查询操作与增删改不同。查询会返回一个结果,结果中可能包含多条查询数据。

Connection connection = null;
PrepareStatement pstmt = null;
Result rs = null;
try{
    connection = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/school", "root", "123456");
    pstmt = connection.getPrepareStatement();
    String sql = "select * from student";
    rs = pstmt.execute(sql);
    
    //rs是一个迭代器。
    while(rs.next()){
        int a = rs.getInt(1);
        int b = rs.getInt(2);
        String c = rs.getString(3);
    }
}catch (SQLException e) {
    e.printStackTrace();
}finally{
    rs.close();
    pstmt.close();
    connection.close();
}

在使用rs的时候不能使用数据库表的字段获取值。并且要注意rs、pstmt、connection需要关闭。

使用自动关闭的rs、pstmt、connection

将这些对象写在try的括号中。

try(Connection connection = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/school", "root", "123456");
   PrepareStatement pstmt = connection.getPrepareStatement();
    Result rs;
   ){
    String sql = "select * from student";
    rs = pstmt.execute(sql);
    
    //rs是一个迭代器。
    while(rs.next()){
        int a = rs.getInt(1);
        int b = rs.getInt(2);
        String c = rs.getString(3);
    }
}catch (SQLException e) {
    e.printStackTrace();
}

JDBC处理大文本及二进制类型数据

varchar最多只能存放4000byte个数据,如果你想存放一本小说那么这是远远不够的。而text类型可以解决这个问题。

处理稍大型数据的方法:

  1. 使用存放路径:

    ​ 通过使用JDBC存储文件路径(文件存放在服务器),读取时通过IO操作进行读取。

    优点:轻便。

    缺点:严格按照路径进行存取,不易移植。

  2. 使用数据库提供的text与blob:

    ​ 直接将文件数据存放在数据库中。

    优点:直接存放在数据库中,不受路径限制。

    缺点:笨重。

存放小说数据:

public class JDBCSaveText {
    public static void main(String[] args) {
        try {
            Class.forName("com.mysql.jdbc.Driver");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }

        String sql = "insert into book values (?, ?, ?)";
        try (Connection connection = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/user_school?characterEncoding=UTF-8", "root", "111111");
             PreparedStatement pstmt = connection.prepareStatement(sql)){

            File file = new File("f:/逆袭1.txt");
            InputStream in = new FileInputStream(file);
            Reader reader = new InputStreamReader(in, "utf-8");
            pstmt.setString(1, "逆袭");
            pstmt.setInt(2, 11);
            pstmt.setCharacterStream(3, reader, (int)file.length());
            pstmt.execute();

        }catch (SQLException e){
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

在存放数据时,以输入流的方式存放在数据库中。这时存放在数据库中的数据使用SQLyog可以看到数据(其他可视化软件可能看不到)。

对文件流对象进行重新编码使用FileReader是不行的,只能使用InputStreamReader进行重新编码。

使用缓冲区读取小说数据:

public class JDBCSaveText {
    public static void main(String[] args) {
        try {
            Class.forName("com.mysql.jdbc.Driver");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }

        String sql = "select content from book where bookName = ?";
        try (Connection connection = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/user_school?characterEncoding=UTF-8", "root", "111111");
             PreparedStatement pstmt = connection.prepareStatement(sql)){
            
            char[] data = new char[100];
            //data作为缓冲区
            pstmt.setString(1, "逆袭");
            ResultSet rs = pstmt.executeQuery();
            if (rs.next()){
                Reader reader = rs.getCharacterStream(1);
                int i = -1;
                while((i = reader.read(data)) != -1){
                    System.out.println(data);
                    //将缓冲区中的数据输出
                }
            }

        }catch (SQLException e){
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

使用缓冲区读取:
在这里插入图片描述

使用reader.read(data)会将数据读入data并返回一个数(读取了的长度),输入流reader中没有数据后再使用read()会返回一个-1。

​ 二进制与大文本处理方法一样,只不过将set/getCharacterStream换成set/getBinaryStream即可进行。

取出二进制数据:

public class JDBCGetBinary {
    public static void main(String[] args) {
        try {
            Class.forName("com.mysql.jdbc.Driver");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }

        String sql = "select imgdata from image where imgName = ?";
        try (Connection connection = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/user_school?characterEncoding=UTF-8", "root", "111111");
             PreparedStatement pstmt = connection.prepareStatement(sql)){
            
            byte[] data = new byte[100];
            //data作为缓冲区
            pstmt.setString(1, "头像.jpg");
            ResultSet rs = pstmt.executeQuery();
            if (rs.next()){
                //设置文件路径
                File file = new File("f:/头像.jpg");
                FileOutputStream out = new FileOutputStream(file);
                InputStream reader = rs.getBinaryStream(1);
                int i = -1;
                while((i = reader.read(data)) != -1){
                    out.write(data, 0, i);
                }
            }

        }catch (SQLException e){
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
是的,JavaEE中可以通过SQL语句或者使用ORM框架来判断数据库中是否存在指定的记录。以下是两个示例: 1. 通过SQL语句判断 ```java // 获取数据库连接池资源 Context context = new InitialContext(); DataSource dataSource = (DataSource)context.lookup("java:comp/env/jdbc/yourDataSourceName"); // 获取数据库连接 Connection connection = dataSource.getConnection(); // 创建 SQL 语句 String sql = "SELECT COUNT(*) FROM yourTableName WHERE column1 = ?"; // 创建 PreparedStatement 对象 PreparedStatement preparedStatement = connection.prepareStatement(sql); // 设置 SQL 语句中的参数 preparedStatement.setString(1, "value1"); // 执行 SQL 查询 ResultSet resultSet = preparedStatement.executeQuery(); // 判断结果集是否有记录 if (resultSet.next()) { int count = resultSet.getInt(1); if (count > 0) { // 数据库中存在指定记录 } else { // 数据库中不存在指定记录 } } // 释放资源 resultSet.close(); preparedStatement.close(); connection.close(); ``` 在上述示例代码中,我们使用了带有参数的 SQL 查询语句,通过设置参数的方式指定了要查询的记录的条件。然后执行查询,判断结果集中是否存在记录,如果记录数量大于0,则说明数据库中存在指定记录,否则不存在。需要注意的是,这里使用了 PreparedStatement 对象来执行 SQL 查询,这样可以避免 SQL 注入攻击。 2. 通过使用ORM框架判断 如果你使用的是ORM框架,比如Hibernate或MyBatis,那么可以直接调用框架提供的API来判断记录是否存在。以Hibernate为例,可以使用下面的代码: ```java // 获取Session对象 Session session = sessionFactory.openSession(); // 创建Criteria对象 Criteria criteria = session.createCriteria(yourEntity.class); // 添加查询条件 criteria.add(Restrictions.eq("column1", "value1")); // 执行查询 List<yourEntity> result = criteria.list(); // 判断查询结果是否为空 if (!result.isEmpty()) { // 数据库中存在指定记录 } else { // 数据库中不存在指定记录 } // 关闭Session session.close(); ``` 在上述示例代码中,我们使用了Hibernate提供的Criteria API来执行查询,通过添加查询条件,可以指定要查询的记录。最后,判断查询结果是否为空即可知道数据库中是否存在指定记录。需要注意的是,这里需要先获取Session对象,并且查询结果是一个List对象,需要通过isEmpty()方法来判断是否为空。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值