JDBC学习总结

本文介绍了在使用JDBC时遇到的版本兼容问题及其解决方案,详细展示了8.1版本MySQL驱动的配置方法。此外,还讲解了数据库连接池的实现,以 ComboPooledDataSource 为例,设置了各种参数以优化性能。接着,文章讨论了JDBC的事务处理,包括事务的四大特性以及如何在Java中进行事务控制。最后,提到了批处理操作在提高效率方面的作用,并给出了批处理的示例代码。

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

JDBC学习总结

遇到的问题:

mysql版本为8.1,而学校jar包为5.6版本导致,数据库驱动不起来,之后写JDBC需要注意

解决方法:安装8.1版本的jar包

8.1版本jar包驱动方式

public class DBUtil {
	private static final String jdbcUrl="jdbc:mysql://localhost:3306/booklib?useUnicode=true&useSSL=false&serverTimezone = GMT";  //booklib为连接的数据库名称,问号后面一加,绝对可以跑
	//	private static final String jdbcUrl="jdbc:mysql://localhost:3306/booklib?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone = GMT";
	private static final String dbUser="root";  //mysql账号密码
	private static final String dbPwd="zucc";
	static{
		try {
			Class.forName("com.mysql.cj.jdbc.Driver");  
			//8版本驱动在mysql.cj.jdbc.Driver,5.6版本在mysql.jdbc.Driver
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	public static Connection getConnection() throws java.sql.SQLException{
		return java.sql.DriverManager.getConnection(jdbcUrl, dbUser, dbPwd);
	}
}

   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

连接池:

package cn.edu.zucc.booklib.util;

import java.sql.Connection;
import java.sql.SQLException;
import java.beans.PropertyVetoException;
import com.mchange.v2.c3p0.ComboPooledDataSource;

public class DBPool {
	private static DBPool dbPool;
	private ComboPooledDataSource dataSource;
	/*static静态块。静态块是一个包含代码的范围,这个范围的代码只被执行一次,
	那什么时候执行呢? 当类代码被加载到内存的时候,执行一次,之后不再执行。*/
	static {
		dbPool = new DBPool();
	}

	public DBPool() {
		try {
			dataSource = new ComboPooledDataSource();
			dataSource.setUser("root");
			dataSource.setPassword("root");
			dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/booklib?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone = GMT");
			dataSource.setDriverClass("com.mysql.cj.jdbc.Driver");
			dataSource.setInitialPoolSize(2);
			dataSource.setMinPoolSize(1);  //定义最小连接数量
			dataSource.setMaxPoolSize(10);
			dataSource.setMaxStatements(50);
			dataSource.setMaxIdleTime(60);
		} catch (PropertyVetoException e) {
			throw new RuntimeException(e);
		}
	}

	public final static DBPool getInstance() {
		return dbPool;
	}

	public final Connection getConnection() {
		try {
			return dataSource.getConnection();
		} catch (SQLException e) {
			throw new RuntimeException("无法从数据源获取连接 ", e);
		}
	}
	public static void main(String[] args) throws SQLException {
		Connection con = null;
		try {
			con = DBPool.getInstance().getConnection();
			java.sql.ResultSet rs=con.createStatement().executeQuery("select * from Beanbook");
			while(rs.next())
				System.out.println(rs.getString(1));
		} catch (Exception e) {

		} finally {
			if (con != null)
				con.close();
		}
	}

}

   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60

JDBC使用

其实很简单,方法如下:
首先Connection conn 创立一个连接,之后String sql =“mysql语句”,这个看本事了
创建PreparedStatement对象,java.sql.PrepareStatement pst=conn.prepareStatement(sql)
获取结果用ResultSet对象,java.sql.ResultSet rs = pst.executeQuery();
遍历结果 while(rs.next){}

		Connection conn = null;
		try {
			conn = DBPool.getInstance().getConnection();
			String sql = "select readerid,count(*) from beanbooklendrecord where returnDate is null GROUP BY readerid";
			java.sql.PreparedStatement pst = conn.prepareStatement(sql);
			java.sql.ResultSet rs = pst.executeQuery();
			while(rs.next()) {
				/*mp.put(rs.getString(1),rs.getInt(2));*/
			}
			pst.close();
			rs.close();
			return mp;
		}catch (SQLException e) {
			e.printStackTrace();
			throw new DbException(e);
		}
		finally{
			if(conn!=null)
				try {
					conn.close();
				} catch (SQLException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
		}

   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

JDBC事务处理

1.事务必须满足的四个条件:

  • 事务的原子性( Atomicity):一组事务,要么成功;要么撤回。
  • 一致性 (Consistency):事务执行后,数据库状态与其他业务规则保持一致。如转账业务,无论事务执行成功否,参与转账的两个账号余额之和应该是不变的。
  • 隔离性(Isolation):事务独立运行。一个事务处理后的结果,影响了其他事务,那么其他事务会撤回。事务的100%隔离,需要牺牲速度。
  • 持久性(Durability):软、硬件崩溃后,InnoDB数据表驱动会利用日志文件重构修改。可靠性和高速度不可兼得

2.MySQL中的事务

  • 开启事务:start transaction
  • 结束事务:commit或rollback

3.JDBC中事务处理
感觉就这里有用

try{
     con.setAutoCommit(false);//开启事务
     ......
     con.commit();//try的最后提交事务      
} catch() {
    con.rollback();//回滚事务
}

   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

详细看这篇博客

Java的一些特性:

关于接口实例化,在我原来的印象中,接口是不能实例化的,但是有经常看到:

public void lendbooks(String readerId,Collection<String> barcodes)
Map<String,Integer> mp = HashMap<String,Integer>();

   
  • 1
  • 2

就很疑惑,Collection不是接口吗?为什么也可以当类一样实例化?

原因是接口不能被实例化,但是可以通过实现接口的子类创建对象赋值给接口,子类创建对象赋值给接口后,接口再赋值给子类需要强制转换。
可以看这篇博客

IDEA的一小问题:

明明感觉没有错误,但是一堆飘红,解决方法:重启IDEA。
解决Cannot resolve symbol的方法

Update:

今天写实验的时候,发现了update视图会报错,具体错误如下:
同时,发现数据库中的数据进行了更新,视图中的数据也会更新,并不需要新建视图?
奇怪:那视图是不是就一直不用更新了?

The target table view_book of the UPDATE is not updatable

   
  • 1

查阅资料发现:具体可以看这篇博客
定义视图的select语句不能包含以下任何元素,否则无法修改:

聚合函数,如:min,max,sum,avg,count等。
DISTINCT子句
GROUP BY子句
HAVING子句
左连接或外连接。
UNION或UNION ALL子句
SELECT子句中的子查询或引用该表的where子句中的子查询出现在FROM子句中。
引用FROM子句中的不可更新视图
仅引用文字值
对基表的任何列的多次引用

   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

事务批处理

简单来说就是一次处理多个sql语句,据说速度会更快,要开事务处理,因为原子特性,要么一起完成,要不都不完成
使用方法如下:以preparedStement为例

		try {
			conn = DBPool.getInstance().getConnection();
			conn.setAutoCommit(false);//开启事务
			String sql = "insert into beanbooklendrecord (readerid,bookBarcode,lendDate,lendOperUserid) values(?,?,Now(),'admin')";
			java.sql.PreparedStatement pst = conn.prepareStatement(sql);
			for(String it:barcodes) {
				pst.setString(1, readerId);
				pst.setString(2, it);
				pst.addBatch();  //添加到同一个批处理
			}
			pst.executeBatch(); //执行批处理
			conn.commit();//try的最后提交事务 
			pst.close();
		}catch (SQLException e) {
			conn.rollback();  
			e.printStackTrace();
			throw new DbException(e);
		}

   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

ZUCC mysql大作业项目:

仅参考

1.建表语句:

create TABLE 	`beanplan` (
`planid` varchar(20) NOT NULL,
`planname` varchar(50) NOT NULL,
`stepNum` int(11) NOT NULL,
`accomplishedStepNum` int(11) NOT NULL,
 PRIMARY KEY (`planid`)
)ENGINE=InnoDB DEFAULT CHARSET =utf8;

create table 	`beanstep` (
`belongplanid` varchar(20) NOT NULL,
`stepname` varchar(50) NOT NULL,
`beginDate` datetime NOT NULL,
`accomplishdate` datetime NOT NULL,
`realbegindate` datetime DEFAULT NULL,
`realaccomplishdate` datetime DEFAULT NULL,
 PRIMARY KEY (`belongplanid`,`stepname`),
 CONSTRAINT `fk_belongplanid` FOREIGN KEY (`belongplanid`) REFERENCES `beanplan` (`planid`) ON DELETE NO ACTION ON UPDATE NO ACTION
)ENGINE=InnoDB DEFAULT CHARSET =utf8;
//这边用planId和stepName做主键,可以确定一条记录

CREATE TABLE `beanuser` (
  `userid` varchar(20) NOT NULL,
  `username` varchar(50) NOT NULL,
  `pwd` varchar(32) NOT NULL,
  `createDate` datetime NOT NULL,
  `removeDate` datetime DEFAULT NULL,
  PRIMARY KEY (`userid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28

后面只写了登录界面和用户管理,之后会更新

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值