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);
}
}
连接池:
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();
}
}
}
JDBC使用
其实很简单,方法如下:
首先Connection conn 创立一个连接,之后String sql =“mysql语句”,这个看本事了
创建PreparedStatement对象,java.sql.PrepareStatement pst=conn.prepareStatement(sql)
获取结果用ResultSet对象,java.sql.ResultSet rs = pst.executeQuery();
得到 数据库数据 String Stuname = rs.getString(1);//从第一列获取数据
遍历结果 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();
}
}
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();//回滚事务
}
Java的一些特性:
关于接口实例化,在我原来的印象中,接口是不能实例化的,但是有经常看到:
public void lendbooks(String readerId,Collection<String> barcodes)
Map<String,Integer> mp = HashMap<String,Integer>();
就很疑惑,Collection不是接口吗?为什么也可以当类一样实例化?
原因是接口不能被实例化,但是可以通过实现接口的子类创建对象赋值给接口,子类创建对象赋值给接口后,接口再赋值给子类需要强制转换。
可以看这篇博客
IDEA的一小问题:
明明感觉没有错误,但是一堆飘红,解决方法:重启IDEA。
解决Cannot resolve symbol的方法
Update:
今天写实验的时候,发现了update视图会报错,具体错误如下:
同时,发现数据库中的数据进行了更新,视图中的数据也会更新,并不需要新建视图?
奇怪:那视图是不是就一直不用更新了?
The target table view_book of the UPDATE is not updatable
查阅资料发现:具体可以看这篇博客
定义视图的select语句不能包含以下任何元素,否则无法修改:
聚合函数,如:min,max,sum,avg,count等。
DISTINCT子句
GROUP BY子句
HAVING子句
左连接或外连接。
UNION或UNION ALL子句
SELECT子句中的子查询或引用该表的where子句中的子查询出现在FROM子句中。
引用FROM子句中的不可更新视图
仅引用文字值
对基表的任何列的多次引用
事务批处理
简单来说就是一次处理多个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);
}
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;
后面只写了登录界面和用户管理,之后会更新