JavaWeb学习笔记(五)JDBC

JDBC操作MySQL

添加操作
  • Class.forName(diverClassName);是为了兼容老版本,老版本驱动为com.mysql.jdbc.Driver,之后的驱动为com.mysql.cj.jdbc.Driver,可以自动加载驱动,不用写forName语句
  • 新版?要在url的数据库名后加?serverTimezone=UTC&useSSL=false进行其他设置
  • 使用Statement对象的话导入的是 java.sql.Statement这个包,不是mysql。也可以使用java.sql.PreparedStatement里的PreparedStatement预编译。
  • 数据库名datasheet,数据表名person,表内字段"name",“age”,“gender”。
package com.cc;

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

public class Test {
	public static void main(String[] args) throws Exception {

		// 四个参数
		String diverClassName = "com.mysql.cj.jdbc.Driver";
		String url = "jdbc:mysql://127.0.0.1:3306/datasheet?serverTimezone=UTC&useSSL=false";
		String name = "root";
		String passWord = "123123";

		// 为兼容老版本加载驱动,之后可以不写,自动加载驱动
		Class.forName(diverClassName);
		// 创建连接
		Connection c = DriverManager.getConnection(url, name, passWord);
//-------------------------------方案一---------------------------------------
		// SQL语句
		String sql = "INSERT INTO person VALUES('bb','12','dd')";
		// 得到Statement对象(注意:使用的是 java.sql.Statement)
		Statement stmt = c.createStatement();
		// 执行sql语句
		stmt.executeUpdate(sql);
		// 关闭操作
		stmt.close();
		c.close();
//-------------------------------方案二---------------------------------------
		// sql语句
		String sql = "INSERT INTO person VALUES(?,?,?)";

		// 预编译
		PreparedStatement preparedStatement = connection.prepareStatement(sql);
		preparedStatement.setString(1, "chen");
		preparedStatement.setInt(2, 122);
		preparedStatement.setString(3, "hh");

		preparedStatement.execute();

		// 关闭连接
		preparedStatement.close();
		connection.close();

	}

}
		                    

删除和更改操作和添加操作只是在sql语句上不同,其他基本一致。
删除语句:DELETE FROM person WHERE name=“星星”;
更新语句: UPDATE person SET age=18 WHERE name=“星星”;

查询操作
package com.cc;

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

public class Test {
	public static void main(String[] args) throws Exception {

		// 四个参数
		String diverClassName = "com.mysql.cj.jdbc.Driver";
		String url = "jdbc:mysql://127.0.0.1:3306/datasheet?serverTimezone=UTC&useSSL=false";
		String name = "root";
		String passWord = "123123";

		// 为兼容老版本加载驱动,之后可以不写,自动加载驱动
		Class.forName(diverClassName);
		// 创建连接
		Connection c = DriverManager.getConnection(url, name, passWord);
		// SQL语句
//		String sql = "INSERT INTO person VALUES(?,?,?)";
		String sql = "select * from person where name = ?";
		// 预编译对象
		PreparedStatement preparedStatement = c.prepareStatement(sql);
		preparedStatement.setString(1, "星星");

		ResultSet resultSet = preparedStatement.executeQuery();
		while (resultSet.next()) {
			System.out.println(resultSet.getString("name") + resultSet.getInt("age") + resultSet.getString("gender"));
		}

		//关闭连接
		resultSet.close();
		preparedStatement.close();
		c.close();

	}

}

JDBC连接池

与传统方式不同,连接池在使用之前,就会创建好一定数量的连接。
如果有任何线程需要使用连接,那么就从连接池里面借用,而不是自己重新创建.
使用完毕后,又把这个连接归还给连接池供下一次或者其他线程使用。
倘若发生多线程并发情况,连接池里的连接被借用光了,那么其他线程就会临时等待,直到有连接被归还回来,再继续使用。
整个过程,这些连接都不会被关闭,而是不断的被循环使用,从而节约了启动和关闭连接的时间。

  1. ConnectionPool() 构造方法约定了这个连接池一共有多少连接

  2. 在init() 初始化方法中,创建了size条连接。 注意,这里不能使用try-with-resource这种自动关闭连接的方式,因为连接恰恰需要保持不关闭状态,供后续循环使用

  3. getConnection, 判断是否为空,如果是空的就wait等待,否则就借用一条连接出去

  4. returnConnection, 在使用完毕后,归还这个连接到连接池,并且在归还完毕后,调用notifyAll,通知那些等待的线程,有新的连接可以借用了。

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();
    }
  
}

事务的四大特性

  • 原子性
    事务中的操作是不可分割的原子单位,要么全部成功,要么全部失败
  • 一致性
    事务执行后,数据库的状态与其他业务规则保持一致,如转账,无论成功与否,参与转账的两个账号余额是不变的
  • 隔离性
    在并发操作中,不同的事务应隔离开,每个并发中的事务不会相互干扰
  • 持久性
    事务提交成功,事务中所有的数据操作都必须持久化到数据库中,及时崩溃也能恢复数据
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值