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