JAVA-JDBC编程(第九天)
一、数据库介绍
数据库:是数据结构来组织、存储和管理数据的软件
数据结构有三种:
- 层次模型
- 网状模型
- 关系模型 -> 关系型数据库 -> 一对多,一对一,多对多
商业版:Oracel sql server DB2 Sybase
开源版:MySQL PostgreSQL
桌面型:Access
表是一个二维表,表有一个主键,作为唯一标识。
外键:关联到其他某个表的主键。
MySQL数据库
本地连接 mysql -u 用户名 -p 密码
远程连接mysql -h 127.0.0.1 -P 3306 -u 用户名 -p 密码
导入sql文件 mysql -u 用户名 -p databasename < …sql
退出 exit
sql格式文件
set names utf8mb4
-- init tables;
drop table if exists tablename;
sql命令,查看系统配置:show variables like “%char%”;
| Variable_name | Value
+--------------------------+--------
| character_set_client | gbk
| character_set_connection | gbk
| character_set_database | utf8mb4
| character_set_filesystem | binary
| character_set_results | gbk
| character_set_server | utf8mb4
| character_set_system | utf8
sql:结构化查询语言,针对关系型数据库设计,各种数据库基本一致,不关心底层存储结构。
- DDL 数据定义语言 create/drop/alter 创建/删除/修改表
- DML 数据操作语言 insert/delete/update 添加/删除/更新记录
- DQL 数据查询语言 select 查询记录
SQL数据类型:
SQL数据类型 | Java数据类型 |
---|---|
CHAR(N) | String |
VARCHAR(N) | String |
BOOLEAN | boolean |
BIT | boolean |
INT | int |
BIGINT | long |
FLOAT | float |
DOUBLE | double |
CHAR, VARCHAR | String |
DECIMAL | BigDecimal |
DATE | java.sql.Date, LocalDate |
TIME | java.sql.Time, LocalTime |
注意:只有最新的JDBC驱动才支持LocalDate和LocalTime。
常用操作:
show databases;//查看数据库列表
use databasename;//选择数据库
show tables;//查看数据表列表
create database databasename;//创建数据库
drop database databasename;//删除数据库
create table tablename(field type);//创建数据表
drop table tablename;//删除数据表
创建表:
create table tablename(id INT NOT NULL AUTO_INCREMENT,PRIMARY KEY(id));
关键字不区分大小写
二、插入数据
insert语句 插入一条记录
insert into 表名(字段1,字段2...) values (数据1,数据2...);//字段可以省略,但是数据顺序和表字段类型顺序一致
三、查询记录
select语句
select * from 表名;//查询所有记录
select * from 表名 where 条件1 and 条件2 limit 限制N条记录;//查询满足where条件的N条记录
select 字段1,字段2,字段3...from 表名;//投影
select count(*) from 表名;//聚合查询->统计
select count(*) number from 表名;//number别名
select count(*) number from 表名 group by 条件;//分组查询
select * from 表1,表2;//联合查询,多表查询->笛卡尔积查询 N*M条记录
select * from 表1 inner join 表2 on 表1.字段=表2.字段;//联合查询
四、修改记录
updata语句
updata tablename set 字段=值;
updata tablename set 字段=值 where 条件;//更新指定条件的记录
updata tablename set 字段1=值1,字段2=值2;
五、删除记录
delete语句
delete from tablename;//删除全部记录
delete from tbalename where 条件1 and 条件2;//删除满足条件的记录
六、JDBC简介
JDBC(Java数据库连接性)是Java API,用于管理与数据库的连接,发出查询和命令以及处理从数据库获得的结果集。
JAVA App->JDBC Interface(JDK)->JDBC Driver->DataBase
导入依赖
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.13</version>//版本号和MySQL 8.0安装的对应
<scope>runtime</scope>
</dependency>
数据库连接
String JDBC_URL = "jdbc:mysql://localhost:3306/databasename";
String JDBC_USER = "username";
String JDBC_PASSWORD = "123456";
Connection conn = DriverManager.getConnection(JDBC_URL,JDBC_USER,JDBC_PASSWORD);
...
conn.close();
JDBC的好处
- 各个数据库使用相同的接口
- 依赖java.sql.*,不依赖数据库的jar包
- 可随时替换底层的数据库,代码不用改变
数据查询
方式一
Statement stmt = conn.createStatement();//获取statement对象
ResultSet rs = stmt.executeQuery("sql语句");//iterator迭代
while(rs.next()){
long id = rs.getLong(1);//索引从1开始
}
缺点:有时sql语句是string类型拼接的,可能存在查询错误。
方式二 推荐使用
String sql = "select * from tablename where id=? and name=?";//‘?’占位符
PrepareStatement ps = conn.prepareStatement(sql);
ps.setObject(1,id);//索引从1开始
ps.setObject(2,name);
ResultSet rs = ps.executeQuery();//执行
while(rs.next()){
int id = rs.getInt("id");
String name = rs.getString(“name”);
}
数据更新
String sql = "update tablename set 字段? = 值? ";//‘?’占位符
PrepareStatement ps = conn.prepareStatement(sql);
ps.setObject(1,id);//索引从1开始
ps.setObject(2,name);
int n = ps.executorUpdate();
插入并获取主键的值
String sql = "insert into tablename (字段1,字段2,...) values (?,?,...)";//‘?’占位符
PrepareStatement ps = conn.prepareStatement(sql,Statement.RETURN_GENERATED_KEYS);//获取主键
ps.setObject(1,id);//索引从1开始
ps.setObject(2,name);
int n = ps.executorUpdate();
Result rs = ps.getGeneratedKeys()
JDBC事务
数据库事务:若干SQL语句构成的一个操作序列,要么全部执行成功,要么全部不执行。
具有ACID特性:原子性(atomicity)、一致性(consistency)、隔离性(isolation)、持久性(durability)
事务的隔离级别:脏读(dirty read)、非重复读(non repeatable read)、幻读(phantom read)
Isolation Level | 脏读(Dirty Read) | 不可重复读(Non Repeatable Read) | 幻读(Phantom Read) |
---|---|---|---|
Read Uncommitted | Yes | Yes | Yes |
Read Committed | - | Yes | Yes |
Repeatable Read | - | - | Yes |
Serializable | - | - | - |
Connection conn = openConnection();
try {
// 关闭自动提交:
conn.setAutoCommit(false);
// 执行多条SQL语句:
insert(); update(); delete();
// 提交事务:
conn.commit();
} catch (SQLException e) {
// 回滚事务:
conn.rollback();
} finally {
conn.setAutoCommit(true);
conn.close();
}
// 设定隔离级别为READ COMMITTED:
conn.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);
连接池
线程池可以复用一个线程
JDBC连接池也可以复用JDBC连接
JDBC连接池实现:HikariCP、C3P0、BoneCP、Druid
HikariCP连接池详细配置参数
使用时需要导入依赖
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
<version>2.7.1</version>
</dependency>
HikariConfig con = new HikariConfig();
con.setJdbcUrl("jdbc:mysql://localhost:3306/databasename");
con.setUsername("root");
con.setPassword("123456");
con.addDataSourceProperty("connectionTimeout", "1000"); // 连接超时:1秒
con.addDataSourceProperty("idleTimeout", "60000"); // 空闲超时:60秒
con.addDataSourceProperty("maximumPoolSize", "10"); // 最大连接数:10
DataSource ds = new HikariDataSource(con);
try (Connection conn = ds.getConnection()) { // 在此获取连接
...
} // 在此“关闭”连接接
编译时会报错
//You must configure either the server or JDBC driver (via the serverTimezone configuration property) to use a more specifc time zone value if you want to utilize time zone support.
con.setJdbcUrl("jdbc:mysql://localhost:3306/databasename?serverTimezone=UTC");//加上serverTimezone=UTC
con.setJdbcUrl("jdbc:mysql://localhost:3306/databasename?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC");//如果还有乱码,可以在加上?useUnicode=true&characterEncoding=UTF-8
从数据库获取表中的数据
String sql="select id,name from student";
PreparedStatement ps = conn.prepareStatement(sql);
ResultSet resultSet = ps.executeQuery();
while (resultSet.next()) {
String id = resultSet.getString("id");
String name = resultSet.getString("name");
System.out.println(id + ":" + name);
System.out.println("---------------------");
}