JDBC

public class Demo1 {
	public static void main(String[] args) throws SQLException, ClassNotFoundException {
		//String url = "jdbc:mysql://localhost:3306/day14?user=root&password=xxc";如果写成这样,那么在getConnection(sql)只需要一个参数就行
		String url = "jdbc:mysql://localhost:3306/day14";//连接哪台机器上的哪个数据库 如果连接本机的话可以简写成jdbc:mysql:///day14;
		String userName = "root";
		String passWord = "xxc";
		//1.加载驱动  jar包下的com.mysql.jdbc下的Driver类
		/*
		 * DriverManager.registerDriver(new com.mysql.jdbc.Driver());
		 * 不推荐这种方式来注册驱动,原因是,Driver类中有个静态代码快(在对象创建前就执行了)
		 * 块中也有一句DriverManager.registerDriver(new Driver());
		 * 所以会造成产生两个驱动对象(构造方法创建一个,静态代码块一个)
		 * 而mysql帮助文档中Class.forName("com.mysql.jdbc.Driver").newInstance();
		 * 感觉没什么必要,因为在加载这个类的时候就已经执行静态代码块里的new Driver()操作了。
		 */
		Class.forName("com.mysql.jdbc.Driver");
		//2.获取数据库连接  注意导的包是java.sql.Connection;而不是com.mysql.jdbc.Connection
		Connection conn = DriverManager.getConnection(url, userName, passWord);
		//3.获得用于向数据库发送sql语句的statement对象
		Statement st = conn.createStatement();
		String sql = "SELECT * FROM USER";
		ResultSet rs = st.executeQuery(sql);
		//4.从结果集中取出结果
		while(rs.next()){
			System.out.println(rs.getObject("id"));
			System.out.println(rs.getObject("name"));
			System.out.println(rs.getObject("password"));
			System.out.println(rs.getObject("email"));
			System.out.println(rs.getObject("birthday"));
			System.out.println("---------------------------");
		}
		//释放资源  相当重要!!!
		st.close();
		rs.close();
		conn.close();
	}
}


批处理:










JDBC翻页

package com.xxc.utils;

import java.util.List;

public class Page {
	private int pageNum;// 当前第几页
	private int allPageCount;// 共几页
	private int pageSize = 2;// 每页显示多少条
	private int startIndex;// 页面上的页数在数据库中起始数据条数
	private List list;// 封装的是分页数据
	private int startPage;// 页面中起始索引
	private int endPage;// 页面中结束索引

	public Page(Integer pageNum, Integer allCount) {
		this.pageNum = pageNum;
		this.startIndex = (pageNum - 1) * this.pageSize;
		int count = allCount % this.pageSize;
		if (count == 0) {
			allPageCount = allCount / this.pageSize;
		} else {
			allPageCount = allCount / this.pageSize + 1;
		}

		if (allPageCount < 10) {//当总页数小于10,就让页面中起始到结束所以为1至总页数
			this.startPage = 1;
			this.endPage = this.allPageCount;
		} else {//当总页数大于10
			if (this.pageNum < 10) {//当前页索引小于10,起始为1,结束为10
				this.startPage = 1;
				this.endPage = 10;
			} else if (this.pageNum >= 10) {//当前页大于10
				this.startPage = this.pageNum - 4;
				this.endPage = this.pageNum + 5;
				if(this.startPage < 0){//起始页小于0,则让起始页为1,结束页为10
					this.startPage = 1;
					this.endPage = 10;
				}else if(this.endPage > this.allPageCount){//结束页索引大于了总页数,就让结束页索引为总页数,起始页索引为总页数-10
					this.endPage = this.allPageCount;
					this.startPage = this.endPage - 10;
				}
			}
		}
	}

	public int getStartPage() {
		return startPage;
	}

	public void setStartPage(int startPage) {
		this.startPage = startPage;
	}

	public int getEndPage() {
		return endPage;
	}

	public void setEndPage(int endPage) {
		this.endPage = endPage;
	}

	public int getAllPageCount() {
		return allPageCount;
	}

	public void setAllPageCount(int allPageCount) {
		this.allPageCount = allPageCount;
	}

	public int getPageNum() {
		return pageNum;
	}

	public void setPageNum(int pageNum) {
		this.pageNum = pageNum;
	}

	public int getPageSize() {
		return pageSize;
	}

	public void setPageSize(int pageSize) {
		this.pageSize = pageSize;
	}

	public int getStartIndex() {
		return startIndex;
	}

	public void setStartIndex(int startIndex) {
		this.startIndex = startIndex;
	}

	public List getList() {
		return list;
	}

	public void setList(List list) {
		this.list = list;
	}
}



JDBC事务:

在命令行中,

开启事务:start transaction(开启事务后,后面执行的所有sql语句都是整体执行的,要不全部失败,要不全部成功)

回滚:当开启事务后(不开启事务无效),需要回滚数据使用rollback语句。

提交:将开启事务后的所有sql语句整体提交。commit


只要java代码中开启了Transaction,无论是否进行connection.rollback();出现异常后,数据库都会进行数据回滚,但是为了保险起见,还是手动进行下回滚。

package com.xxc.test;

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

public class Test {
	public static void main(String[] args) {
		Connection conn = JdbcUtil.getConnection();
		Savepoint point = null;
		try {
			conn.setAutoCommit(false);//将sql语句的自动提交功能关闭
			String sql = "UPDATE ACCOUNT SET MONEY=MONEY+100 WHERE NAME = ?";
			PreparedStatement ps = conn.prepareStatement(sql);
			ps.setString(1, "aaa");
			ps.executeUpdate();
			
			point = conn.setSavepoint();//设置会滚点
			int a = 1/0;//故意写一个异常,进行回滚操作
			
			sql = "UPDATE ACCOUNT SET MONEY=MONEY-100 WHERE NAME = ?";
			ps = conn.prepareStatement(sql);
			ps.setString(1, "bbb");
			ps.executeUpdate();
			conn.commit();//进行sql数据提交
		} catch (Exception e) {//因为上面是运行异常(By Zero)如果这里还写SqlException,是捕捉不到的,不会进行回滚操作
			try {
				conn.rollback(point);//进行回滚操作,回滚到指定位置
				conn.commit();//如果回滚操作没有全部回滚(即某些sql不需要回滚),那么这里必须要commit,因为上面执行的sql语句是在自动提交关闭的情况下执行的,并没有进行数据提交操作
			} catch (SQLException e1) {
				e1.printStackTrace();
			}
			e.printStackTrace();
		}
	}
}


事务的特性(ACID):

1.原子性(Atomicity):

原子性是指事务是一个不可分割的工作单位,事务中的操作要么全部成功,要么全部失败。

2.一致性(Consistency):

事务必须使数据库从一个一致性状态变换到另一个一致性状态。(举例:a和b各自拥有1000元,a向b转账。转账前a和b的金额总和为2000,转账后也必须为2000,不能说转账后总额多余2000或少于2000了)

3.隔离性(Isolation):

事务的隔离性是多个用户并发访问数据库时,数据库为每一个用户开启的事务,不能被其他事务的操作数据所干扰,多个并发事务之间要相互隔离。

4.持久性(Durability):

持久性是指一个事务一旦被提交,它对数据库中数据的改变就是永久性的,接下来即使数据发生故障也不应该对其有任何影响。


隔离性是重点,事务的隔离级别:

1.脏读:指一个事务读取了另外一个事务未提交的数据。


Mysql默认隔离级别下是不会发生这种情况的,若要查看这种情况,必须将MySql隔离级别设置为最低。

set transaction isolation level read uncommitted;

打开两个命令行窗口a,b。

最初:




在b窗口中设置隔离级别为最低set transaction isolation level read uncommitted;(不设置是默认隔离级别,默认就看不到效果了)


在a和b窗口中都开启事务start transaction(必须都开启事务,b才能看到a的操作)


在a窗口中进行对名字为bbb数据的money+1000操作update account set money=money-100 where name='bbb';

然后在b窗口中进行查看,注意此时a窗口的update语句并未提交。


从上图可以看到,b窗口读到了a窗口未提交的数据,也就是脏读。

此时a窗口进行rollback操作,再在b窗口进行数据查询




2.不可重复读:指在一个事务中多次读取同一条数据,发现两次结果不一样,即有别的事务对这条数据进行了更新操作,就叫不可重复读。




2.虚读(幻读):在同一个事务中查询数据发现第一次和后面几次查询的结果不一样,即有别的事务插入了新的数据




4.设置成最高级别避免脏读,不可重复读,虚读(幻读)



JAVA代码中,实现事务隔离级别

package com.xxc.one;

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

public class TestTransaction {
	public static void main(String[] args) {
		Connection conn = null;
		PreparedStatement ps = null;
		try {
			conn = JdbcUtil.getConnection();
			conn.setAutoCommit(false);//关闭自动提交,打开事务
			conn.setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE);//设置事务隔离级别,这里是最高级别
			
			String sql = "UPDATE ACCOUNT SET MONEY = ? WHERE NAME = ?";
			ps = conn.prepareStatement(sql);
			ps.setInt(1, 2000);
			ps.setString(2, "aaa");
			ps.executeUpdate();
			
			conn.commit();//提交事务
			
			JdbcUtil.closeAllConnection(conn, ps, null);//关闭连接
		} catch (SQLException e) {
			try {
				conn.rollback();
				conn.commit();
			} catch (SQLException e1) {
				e1.printStackTrace();
			}
			e.printStackTrace();
		}
		
	}
}


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值