15.1 Java之JDBC

本文详细介绍了Java中的JDBC使用,从Mysql的安装开始,讲解了JDBC的基础,包括驱动初始化、连接创建、Statement与PreparedStatement的区别,以及execute和executeQuery、executeUpdate的方法用法。还探讨了JDBC事务的管理,ORM的概念,以及数据库连接池的重要性与实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Mysql

在使用JDBC之前要先安装Mysql,这里不详说如何安装。
安装配置完成之后,打开cmd,输入mysql -V,若有版本号则安装成功。

JDBC基础

  1. 导入jar包,Maven的pom.xml
    在这里插入图片描述

  2. 初始化驱动:Class.forName("com.mysql.jdbc.Driver");将该类加载到JVM中。

  3. 建立连接:三个参数:数据库url,用户名,密码

    //数据库url:"jdbc:mysql://本地连接:端口号/数据库名称?数据格式"
     Connection connection = DriverManager
            		.getConnection("jdbc:mysql://127.0.0.1:3306/mydb3?characterEncoding=UTF-8","root","123456");
    
  4. 创建Statement(Statement用来执行sql语句) :Statement s = c.createStatement();

  5. 执行sql语句:

    String sql = "insert into tb_stu values('number1','zhangsan',20,'male')";
    s.execute(sql);
    

    先创建sql语句,sql语句为String字符串。执行sql语句:s.execute(sql)。(sql语句中插入字符串要单引号。)

  6. 关闭资源:Statement.close();Connection.close();,还可以使用try(){}语句关闭资源。

JDBC增删改查

JDBC中的增删改只需要修改sql语句即可,Statement.execute()只是负责提交sql语句。
而查询语句不同,因为有返回值。
查询:

  1. 编写sql语句

  2. 使用Statement.executeQuery(sql);方法返回值为ResultSet类型。

  3. 迭代ResultSet集合,输出迭代的元素。

    try(Connection connection = 
        		DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/mydb3?characterEncoding=UTF-8","root","123456");
        		Statement statement = connection.createStatement();
        	){
        	String sql = "select count(*) from tb_stu";
        	ResultSet rs = statement.executeQuery(sql);
        	int total = 0;
            while (rs.next()) {
                total = rs.getInt(1);
            }
        	System.out.println(total);
        } catch (SQLException e) {
    		// TODO Auto-generated catch block
    		e.printStackTrace();
    	}
    

预编译PreparedStatement

PreparedStatement与Statement相同,都是执行sql语句,但PreparedStatement提前将sql语句在创建时传入,且sql语句内参数用"?"表示。

String sql = "insert into tb_stu values(?,?,?,?)";
		try(Connection connection = 
				DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/mydb3?characterEncoding=UTF-8","root","123456");
				PreparedStatement ps = connection.prepareStatement(sql);
				){
			ps.setString(1, "number103");
			ps.setString(2, "cas");
			ps.setInt(3, 20);
			ps.setString(4, "famale");
			System.out.println(ps);
			ps.execute();			
		}catch (Exception e) {
			// TODO: handle exception
		}

优点:

  • 参数设置方便
  • 性能较好,效率高
  • 能防止sql注入攻击(用户提交数据中有sql语句,容易被数据库识别从而进行无效的操作。)

execute和executeQuery以及executeUpdate

他们都是Statement中的方法。

  • execute(String sql):返回类型boolean,可执行任何语句,若是查询语句则返回值为true,表示有返回ResultSet。若是增删改操作则返回false。
  • executeQuery(String sql):返回类型ResultSet,执行查询语句。
  • executeUpdate(String sql):返回int类型,表示所受到影响的行数,只能执行增删改操作。

JDBC中的事务

在之前,我们执行一条语句:s.execute(sql);就能自动提交一个事务,但有时候我们需要两个事务同时提交,若一个事务发生错误,则另一个事务也停止提交,显然使用以前自动提交事务的方法已经不可行了,因此我们使用手动提交事务。

c.setAutoCommit(false);//设置事务不自动提交
  
// 创建事务1
String sql1 = "update hero set hp = hp +1 where id = 22";
s.execute(sql1);
  
// 创建事务2
// 不小心写错写成了 updata(而非update)
  
String sql2 = "updata hero set hp = hp -1 where id = 22";
s.execute(sql2);
  
// 手动提交,这样一来,只要事务2出现错误,整个提交就结束。
c.commit();

ORM(Object Relationship Database Mapping:对象和关系数据库的映射)

理解:一个对象对应数据库中的一条记录。
DAO(Data Access Object):数据库访问对象。
DAO接口:

package jdbc;
  
import java.util.List;
 
import charactor.Hero;
  
public interface DAO{
    //增加
    public void add(Hero hero);
    //修改
    public void update(Hero hero);
    //删除
    public void delete(int id);
    //获取
    public Hero get(int id);
    //查询
    public List<Hero> list();
    //分页查询
    public List<Hero> list(int start, int count);
}

实现DAO接口:
将上边的接口中的方法实现,添加两个方法,第一个构造方法:在构造方法内部加载驱动,因为驱动只需要加载一次。第二个getConnection方法,这个方法获取到连接connection。

数据库连接池

与线程连接池相似,一个数据库的连接总数有限,不断创建连接会消耗数据连接总数的资源,因此创建连接池,每次线程只能借用,用完归还,若连接池中无资源,则线程等待其他资源释放。
创建连接池ConnectionPool:

package jdbc;
  
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
  
public class ConnectionPool {
  
    List<Connection> cs = new ArrayList<Connection>();
  
    int size;
  
    public ConnectionPool(int size) {
        this.size = size;
        init();
    }
  
    public void init() {
          
        //这里恰恰不能使用try-with-resource的方式,因为这些连接都需要是"活"的,不要被自动关闭了
        try {
            Class.forName("com.mysql.jdbc.Driver");
            for (int i = 0; i < size; i++) {
                Connection c = DriverManager
                        .getConnection("jdbc:mysql://127.0.0.1:3306/how2java?characterEncoding=UTF-8", "root", "admin");
  
                cs.add(c);
  
            }
        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
  
    public synchronized Connection getConnection() {
        while (cs.isEmpty()) {
            try {
                this.wait();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        Connection c = cs.remove(0);
        return c;
    }
  
    public synchronized void returnConnection(Connection c) {
        cs.add(c);
        this.notifyAll();
    }
  
}

注意这四个方法:

  • ConnectionPool()构造方法:确定了该连接池有几个连接。
  • init():创建连接。
  • getConnection():获取连接,获取之前判断连接池是否为空。
  • returnConnection():归还连接。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值