本帖最后由 小石姐姐 于 2018-5-11 10:01 编辑
学习笔记
Java-Web-Day07-JQuery&MySQL
JQuery看官网文档
【MySQL数据库存储的方式】
存储方式的描述
一台数据库服务器中会创建很多数据库(一个项目,会创建一个数据库)。在数据库中会创建很多张表(一个实体会创建一个表)。在表中会有很多记录(一个对象的实例会添加一条新的记录)。
【SQL的概念】
什么是SQL
结构化查询语句(Structured Query Language),是一种数据库查询和程序设计语言,用于存取数据以及查询,更新和管理关系数据库系统;同时也是数据库脚本文件的扩展名.
【SQL的分类】
1.4.2.1 DDL:数据定义语言
create,drop,alter..
1.4.2.2 DCL:数据控制语言
grant,if…
1.4.2.3 DML:数据操纵语言
insert,update,delete…
1.4.2.4 DQL:数据查询语言
select
【SQL对数据库进行操作】
1.5.1.1 创建数据库
语法:
create database 数据库名称 [character set 字符集 collate 字符集校对规则];
1.5.1.2 查看数据库
语法:
查看数据库服务器中所有的数据库:show databases;
查看某个数据库的定义信息: show create database 数据库名称;
1.5.1.3 修改数据库
语法:
alter database 数据库名称 character set 字符集 collate 校对规则;
1.5.1.4 删除数据库
语法:
drop database 数据库名称;
1.5.1.5 其他数据库操作
切换数据库:use 数据库名称;
查看当前正在使用的数据库:select database();
【1.5.2 SQL对数据库表进行操作】
1.5.2.1 SQL创建表
语法:
create table 表名称(字段名称 字段类型(长度) 约束,字段名称 字段类型(长度) 约束…);
字段类型
一个实体对应一个表,一个实体属性对应表的一个字段。
Java中的类型--------------MySQL中的类型
byte/short/int/long--------------tinyint/smallint/int/bigint
float--------------float
double--------------double
boolean--------------bit
char/String--------------char和varchar类型
Date--------------date/time/datetime/timestamp
File--------------BLOB/TEXT
char和varchar的区别:
* char代表是固定长度的字符或字符串。
* 定义类型char(8),向这个字段存入字符串hello,那么数据库使用三个空格将其补全。
* varchar代表的是可变长度的字符串。
* 定义类型varchar(8), 向这个字段存入字符串hello,那么存入到数据库的就是hello。
datetime和timestamp区别
* datetime就是既有日期又有时间的日期类型,如果没有向这个字段中存值,数据库使用null存入到数据库中
* timestamp也是既有日期又有时间的日期类型,如果没有向这个字段中存值,数据库使用当前的系统时间存入到数据库中。
约束
约束作用:保证数据的完整性
单表约束分类:
主键约束:primary key 主键约束默认就是唯一 非空的
唯一约束:unique
非空约束:not null
1.5.2.2 SQL查看表
查看某个数据库下的所有的表
语法:show tables;
查看某个表的结构信息
语法:desc 表名;
1.5.2.3 SQL删除表
删除表
语法:drop table 表名;
1.5.2.4 SQL修改表
修改表:添加列
alter table 表名 add 列名 类型(长度) 约束;
修改表:修改列类型,长度和约束
alter table 表名 modify 列名 类型(长度) 约束;
修改表:删除列
alter table 表名 drop 列名;
修改表:修改列名称
alter table 表名 change 旧列名 新列名 类型(长度) 约束;
修改表:修改表名
rename table 表名 to 新的表名;
修改表:修改表的字符集
alter table 表名 character set 字符集;
【1.5.3 SQL对数据库表的记录进行操作(重点)】
1.5.3.1 SQL添加表的记录
语法:
向表中插入某些列:insert into 表名 (列名1,列名2,列名3…) values (值1,值2,值3…)
向表中插入所有列:insert into 表名 values (值1,值2,值3…);
注意事项
注意事项
1.值的类型与数据库中表列的类型一致。
2.值的顺序与数据库中表列的顺序一致。
3.值的最大长度不能超过列设置最大长度。
4.值的类型是字符串或者是日期类型,使用单引号引起来。
直接向数据库中插入中文记录会出现错误!!!
解决方法:
show variables like '%character%'; --查看数据库中与字符集相关参数:
需要将MySQL数据库服务器中的客户端部分的字符集改为gbk。
找到MySQL的安装路径:my.ini文件,修改文件中[client]下的字符集
1.5.3.2 SQL修改表的记录
语法:
update 表名 set 列名=值,列名=值 [where 条件];
注意事项
注意事项
1.值的类型与列的类型一致。
2.值的最大长度不能超过列设置的最大长度。
3.字符串类型和日期类型添加单引号。
1.5.3.3 SQL删除表的记录
语法:
delete from 表名 [where 条件];
注意事项
注意事项
1.删除表的记录,指的是删除表中的一行记录。
2.删除如果没有条件,默认是删除表中的所有记录。
删除表中的记录有两种做法:
delete from user;
删除所有记录,属于DML语句,一条记录一条记录删除。事务可以作用在DML语句上的
truncate table user;
删除所有记录,属于DDL语句,将表删除,然后重新创建一个结构一样的表。事务不能控制DDL的
1.5.3.4 SQL查看表的记录(重点)
基本查询
语法:select [distinct] *|列名 from 表 [条件];
查询所有学生考试成绩信息
select * from exam;
查询所有学生的姓名和英语成绩
select name,english from exam;
查询英语成绩信息(不显示重复的值)
select distinct english from exam;
查看学生姓名和学生的总成绩
select name,english+chinese+math from exam;
别名查询
select name,english+chinese+math as sum from exam;
条件查询
使用where子句
> , < , >= , <= , <> ,=
like:模糊查询
in:范围查询
条件关联:and , or ,not
查询李四学生的成绩:
select * from exam where name = '李四';
查询名称叫李四学生并且英文大于90分
select * from exam where name = '李四' and english > 90;
查询姓李的学生的信息
like可以进行模糊查询,在like子句中可以使用_或者%作为占位符。_只能代表一个字符,而%可以代表任意个字符。
* like ‘李_’ :名字中必须是两个字,而且是姓李的。
* like ‘李%’ :名字中姓李的学生,李子后可以是1个或任意个字符。
* like ‘%四’ :名字中以四结尾的。
* like ‘%王%’ :只要名称中包含这个字就可以。
select * from exam where name like '李%';
查询英语成绩是69,75,89学生的信息
select * from exam where english in (69,75,89);
排序查询
使用order by 字段名称 asc/desc;(默认asc正序排列)
查询学生信息,并且按照语文成绩倒序排序:
select * from exam order by chinese desc;
查询学生信息,并且按照语文成绩进行排序:
select * from exam order by chinese;
查询学生信息,先按照语文成绩进行倒序排序,如果成绩相同再按照英语成绩升序排序
select * from exam order by chinese desc,english asc;
查询姓李的学生的信息,按照英语成绩降序排序
select * from exam where name like '李%' order by english desc;
分组统计查询
聚合函数使用
sum();
获取所有学生的英语成绩的总和:
select sum(english) from exam;
获取所有学生的英语成绩和数学成绩总和:
select sum(english),sum(math) from exam;
查询姓李的学生的英语成绩的总和
select sum(english) from exam where name like '李%';
查询所有学生各科的总成绩:
select sum(english)+sum(chinese)+sum(math) from exam;
此条命令求和是先求当前字段列的和,然后三个字段列的和再加一起求和
select sum(english+chinese+math) from exam;
与上面的语句有什么不同?
* 上面的语句是按照列的方式统计,英语成绩总和+语文成绩总和+数学成绩总和。
* 下面的语句先计算英语+数学+语文然后再求和。
* 使用ifnull的函数
select sum(ifnull(englist,0)+chinese+math)from exam;
count();
获得学生的总数
select count(*) from exam;
获得姓李的学生的个数
select count(*) from exam where name like '李%';
max();
获得数学成绩的最高分:
select max(math) from exam;
min();
获得语文成绩的最小值
select min(chinese) from exam;
avg();
获取语文成绩的平均值
select avg(chinese) from exam;
分组查询
语法:使用group by 字段名称;
按商品名称统计,每类商品所购买的个数:
select product,count(*) from orderitem group by product;
按商品名称统计,每类商品所花费的总金额:
select product,sum(price) from orderitem group by product;
按商品名称统计,统计每类商品花费的总金额在5000元以上的商品
***** where的子句后面不能跟着聚合函数。如果现在使用带有聚合函数的条件过滤(分组后条件过滤)需要使用一个关键字having
select product,sum(price) from orderitem group by product having sum(price) > 5000;
按商品名称统计,统计每类商品花费的总金额在5000元以上的商品,并且按照总金额升序排序
select product,sum(price) from orderitem group by product having sum(price) > 5000 order by sum(price) asc;
总结
S(select)… F(from)…W(where)…G(group by)…H(having)…O(order by);
Java-Web-Day09-MySQL多表&事务
【多表设计之外键约束】
1.1.1.1 约束的作用
约束是用来保证数据的完整性
1.1.1.2 单表约束
主键约束
唯一约束
非空约束
1.1.1.3 多表约束
外键约束:用来保证数据完整性(多表之间)。
1.1.3 添加外键约束
1.1.3.1 在员工表上添加外键
alter table employee add foreign key (dno) references dept(did);
1.1.3.2 设置外键为非空
alter table employee modify dno int not null;
【多表设计之表关系的介绍】
1.1.1.1 一对多的关系
一对多的例子:
一个部门下可以有多个员工,一个员工只能属于某一个部门。
在多的一方创建外键指向一的一方的主键
1.1.1.2 多对多的关系
多对多的例子:
一个学生可以选择多门课程,一门课程可以被多个学生选择。
需要创建中间表,中间表中至少两个字段,分别作为外键指向多对多双方的主键
1.1.1.3 一对一的关系
一对一的例子:
一个公司可以有一个注册地址,一个注册地址只能对一个公司。
唯一外键对应
假设是一对多,在多的一方创建外键指向一的一方的主键,将外键设置为unique。
主键对应
将两个表的主键建立对应关系即可。
【多表查询的分类】
1.1.1.1 连接查询
交叉连接:cross join
交叉连接:查询到的是两个表的笛卡尔积。
语法:
select * from 表1 cross join 表2;
select * from 表1,表2;
内连接:inner join(inner是可以省略的)
显示内连接:在SQL中显示的调用inner join关键字
语法:select * from 表1 inner join 表2 on 关联条件;
隐式内连接:在SQL中没有调用inner join关键字
语法:select * from 表1,表2 where 关联条件;
外连接:outer join(outer可以省略的)
左外连接:
语法:select * from 表1 left outer join 表2 on 关联条件;
右外连接
语法:select * from 表1 right outer join 表2 on 关联条件;
1.1.1.2 子查询
子查询:一个查询语句条件需要依赖另一个查询语句的结果。
【多表查询详细命令】
1.1.1 交叉连接
1.1.1.1 使用cross join关键字
select * from classes cross join student;
1.1.1.2 不使用cross join关键字
SELECT * FROM classes,student;
1.1.1 内连接
1.1.1.1 显示内连接
select * from classes c inner join student s on c.cid = s.cno;
1.1.1.2 隐式内连接
SELECT * FROM classes c,student s WHERE c.cid = s.cno;
内连接查询: 只显示匹配的结果,如果不匹配则不显示
1.1.1 外连接
1.1.1.1 左外连接
SELECT * FROM classes c LEFT OUTER JOIN student s ON c.cid = s.cno;
1.1.1.2 右外连接
select * from classes c right outer join student s on c.cid = s.cno;
左外查询:以左表为基准,查询所有,如果没有匹配,左边表则返回NULL
右外查询: 以右表为基准,查询所有,如果没有匹配,右边表返回null
1.1.1 子查询
1.1.1.1 带in的子查询
查询学生生日在91年之后的班级的信息。
select * from classes where cid in (SELECT cno FROM student WHERE birthday > '1991-01-01');
1.1.1.2 带exists的子查询
查询学生生日大于91年1月1日,如果记录存在,前面的SQL语句就会执行
select * from classes where exists (SELECT cno FROM student WHERE birthday > '1991-01-01');
1.1.1.3 带any的子查询
SELECT * FROM classes WHERE cid > ANY (SELECT cno FROM student )
1.1.1.4 带all的子查询
SELECT * FROM classes WHERE cid > ALL (SELECT cno FROM student)
【事务的概述】
事务:指的是逻辑上的一组操作,组成这组操作的各个逻辑单元,要么全都成功,要么全都失败。
事务的隔离界别:
1.1.1 如果不考虑隔离性,引发一些安全问题
隔离性:一个事务的执行,不应该受到其他事务的干扰。
如果不考虑隔离性(一个事务执行受到其他的事务的干扰),引发一些安全问题,主要体现在读取数据上:
脏读:一个事务读到了另一个事务未提交的数据,导致查询结果不一致
不可重复读:一个事务读到了另一个事务已经提交的update的数据,导致多次查询结果不一致。
虚读/幻读:一个事务读到了另一个事务已经提交的insert的数据,导致多次查询结果不一致。
1.1.2 解决这些安全性问题:
设置事务的隔离级别:
read uncommitted :脏读,不可重复读,虚读都有可能发生
read committed :避免脏读。但是不可重复读和虚读是有可能发生
repeatable read :避免脏读和不可重复读,但是虚读有可能发生。
serializable :避免脏读,不可重复读,虚读。
acid
原子性:事务必须同时完成,
一致性:
隔离性:事务并发的安全性
持久性:一旦事务提交,事务要持久保存到硬盘中
【事务隔离级别的演示】
1.1.1 演示脏读
开启两个窗口A,B
设置A窗口的隔离级别为read uncommitted;
SET SESSION TRANSACTION ISOLATION LEVEL read uncommitted;
在A,B两个窗口中开启事务
start transaction;
在B窗口中完成转账的功能:
update account set money = money - 1000 where name= '小张';
update account set money = money + 1000 where name= '小凤';
***** 事务未提交!!!
在A窗口中进行查询
select * from account;
*****发现A窗口中已经查询到转账成功了!!!已经发生了脏读:一个事务中已经读到了另一个事务未提交的数据。
1.1.1 避免脏读,演示不可重复读发生
开启两个窗口A,B
设置A窗口的隔离级别为read committed;
SET SESSION TRANSACTION ISOLATION LEVEL read committed;
分别在两个窗口中开启事务:
start transaction;
在B窗口中完成转账
update account set money = money - 1000 where name= '小张';
update account set money = money + 1000 where name= '小凤';
***** 没有提交事务!!!
在A窗口中进行查询:
select * from account;
***** 发现这个时候没有转账成功!!!(没有查询到另一个事务未提交的数据:说明已经避免了脏读)。
在B窗口中提交事务
commit;
在A窗口查询
select * from account;
***** 发现这次的结果已经发生了变化!!!(已经发生不可重复读:一个事务已经读到了另一个事务提交的update的数据,导致多次查询结果不一致。)
1.1.1 演示避免不可重复读
分别开启两个窗口A,B
设置A窗口的隔离级别:repeatable read;
SET SESSION TRANSACTION ISOLATION LEVEL repeatable read;
在A,B两个窗口中开启事务:
start transaction;
在B窗口完成转账
update account set money = money - 1000 where name= '小张';
update account set money = money + 1000 where name= '小凤';
***** 未提交事务!!!
在A窗口中进行查询
select * from account;
***** 发现没有转账成功:说明避免脏读!!!
在B窗口中提交事务
commit;
在A窗口中再次查询:
***** 发现在一个事务中的多次查询结果是一致!!!(已经避免不可重复读)。
1.1.1 演示串行化
开启两个窗口A,B
设置A窗口的隔离级别:serializable
SET SESSION TRANSACTION ISOLATION LEVEL serializable;
分别在两个窗口中开启事务:
start transaction;
在B窗口中插入一条记录
insert into account values (null,'小李',10000);
在A窗口中进行查询
select * from account;
*****发现A窗口已经卡住了(说明事务不允许出现并发,A窗口需要等待B窗口事务执行完成以后,才会执行A窗口的事务。)当B窗口的事务结束(提交或者回滚),那么A窗口马上就会出现结果。
Java-Day10-JDBC
【1.1 JDBC的概述】
1.1.1 什么是JDBC
JDBC(Java DataBase Connectivity,java数据库连接)是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问,它由一组用Java语言编写的类和接口组成。JDBC提供了一种基准,据此可以构建更高级的工具和接口,使数据库开发人员能够编写数据库应用程序
1.1.2 什么是数据库驱动
驱动:两个设备(应用)之间通信的桥梁。
1.1.3 为什么学习JDBC
没有JDBC的时候,如果现在要开发一套系统,使用Java连接MySQL数据库,那么这时候Java程序员需要了解MySQL驱动API,如果使用Java连接Oracle数据库,那么这个时候Java程序员需要了解Oracle数据库驱动API。
SUN公司提供一套统一的规范(接口)。然后各个数据库生产商提供这套接口的实现。这套接口规范就是JDBC的规范。
【1.1 JDBC的入门】
1.1.1.2 创建项目,引入jar包
1.1.2.1 JDBC的开发步骤
第一步:加载驱动
第二步:获得连接
第三步:基本操作
1.1.2.2 JDBC的代码实现
import org.junit.Test;
/**
* JDBC的入门程序
* @author jt
*
*/
public class JDBCDemo1 {
@Test
/**
* JDBC的入门
*/
public void demo1() throws Exception{
// 1.加载驱动
Class.forName("com.mysql.jdbc.Driver");
// 2.获得连接
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/web_test3", "root", "abc");
// 3.基本操作:执行SQL
// 3.1获得执行SQL语句的对象
Statement statement = conn.createStatement();
// 3.2编写SQL语句:
String sql = "select * from user";
// 3.3执行SQL:
ResultSet rs = statement.executeQuery(sql);
// 3.4遍历结果集:
while(rs.next()){
System.out.print(rs.getInt("id")+" ");
System.out.print(rs.getString("username")+" ");
System.out.print(rs.getString("password")+" ");
System.out.print(rs.getString("nickname")+" ");
System.out.print(rs.getInt("age"));
System.out.println();
}
// 4.释放资源
rs.close();
statement.close();
conn.close();
}
}
【1.1 JDBC的API详解之DriverManager】
1.1.1 DriverManager:驱动管理类
1.1.1.1 作用一:注册驱动
这个方法可以完成驱动的注册,但是实际开发中一般不会使用这个方法完成驱动的注册!!!
原因:
如果需要注册驱动,就会使用DriverManager.registerDriver(new Driver());,但是查看源代码发现,在代码中有一段静态代码块,静态代码块已经调用了注册驱动的方法。
如果再手动调用该方法注册驱动,就会导致驱动被注册两次。实际开发中一般会采用:
Class.forName("com.mysql.jdbc.Driver");
1.1.1.2 作用二:获得连接
static Connection getConnection(String url, String user, String password)
试图建立到给定数据库 URL 的连接。
这个方法就是用来获得与数据库连接的方法:这个方法中有三个参数:
url :与数据库连接的路径
user :与数据库连接的用户名
password :与数据库连接的密码
主要关注的是url的写法:
jdbc:mysql://localhost:3306/web_test3
url如果连接的是本机的路径,可以简化为如下格式:
jdbc:mysql:///web_test3
jdbc :连接数据库的协议
mysql :是jdbc的子协议
localhost :连接的MySQL数据库服务器的主机地址。(连接是本机就可以写成localhost),如果连接不是本机的,就需要写上连接主机的IP地址。
3306 :MySQL数据库服务器的端口号
web_test3 :数据库名称
【1.1 JDBC的API详解之Connection】
1.1.1 Connection:与数据库连接对象
1.1.1.1 作用一:创建执行SQL语句的对象
执行SQL语句对象:
Statement :执行SQL
CallableStatement :执行数据库中存储过程
PreparedStatement :执行SQL.对SQL进行预处理。解决SQL注入漏洞。
1.1.1.2 作用二:管理事务
void setAutoCommit(boolean autoCommit)
将此连接的自动提交模式设置为给定状态。
void rollback()
取消在当前事务中进行的所有更改,并释放此 Connection 对象当前持有的所有数据库锁。
void commit()
使所有上一次提交/回滚后进行的更改成为持久更改,并释放此 Connection 对象当前持有的所有数据库锁。
【1.1 JDBC的API详解之Statement】
1.1.1 Statement:执行SQL
1.1.1.1 作用一:执行SQL
执行SQL的方法
boolean execute(String sql);
执行查询,修改,添加,删除的SQL语句。
ResultSet executeQuery(String sql);
执行查询(执行select语句)。
int executeUpate(String sql);
执行修改,添加,删除的SQL语句。
1.1.1.2 作用二:执行批处理
void addBatch(String sql)
将给定的 SQL 命令添加到此 Statement 对象的当前命令列表中。
void clearBatch()
清空此 Statement 对象的当前 SQL 命令列表。
int[] executeBatch()
将一批命令提交给数据库来执行,如果全部命令执行成功,则返回更新计数组成的数组。
【1.1 JDBC的API详解之ResultSet】
1.1.1 ResultSet:结果集。
通过select语句的查询结果。
1.1.1.1 结果集的遍历
boolean next()
将光标从当前位置向前移一行
代码实现:
while(xx.next()){
syso(xx.getIne("xx"))
syso(xx.getString("xx"))
...
}
1.1.1.2 结果集的获取
结果集获取可以使用结果集中的:
getXXX();方法通常都会有一个重载的方法。
getXXX(int columnIndex);
getXXX(String columnName);
【1.1 JDBC的资源释放】
1.1.1 JDBC资源释放
JDBC程序执行结束后,将与数据库进行交互的对象释放掉,通常是ResultSet,Statement,Connection。
这几个对象中尤其是Connection对象是非常稀有的。这个对象一定要做到尽量晚创建,尽早释放掉。
将资源释放的代码写入到finally的代码块中。
资源释放的代码应该写的标准:
if(rs !=null){
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
rs = null;
}
if(statement !=null){
try {
statement.close();
} catch (SQLException e) {
e.printStackTrace();
}
statement = null;
}
if(conn !=null){
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
conn = null;
}
【1.1 JDBC的CRUD操作之增-删-改-查操作代码演示】
1.1 JDBC的CRUD操作之保存操作
@Test
/**
* 保存操作的代码实现
*/
public void demo1(){
Connection conn = null;
Statement stmt = null;
try{
// 注册驱动:
Class.forName("com.mysql.jdbc.Driver");
// 获得连接:
conn = DriverManager.getConnection("jdbc:mysql:///web_test3", "root", "abc");
// 执行操作:
// 创建执行SQL语句对象:
stmt = conn.createStatement();
// 编写SQL语句:
String sql = "insert into user values (null,'eee','123','阿黄',21)";
// 执行SQL语句:
int num = stmt.executeUpdate(sql);
if(num > 0){
System.out.println("保存用户成功!!!");
}
}catch(Exception e){
e.printStackTrace();
}finally{
// 资源释放:
if(stmt != null){
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
stmt = null;
}
if(conn != null){
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
conn = null;
}
}
}
1.1 JDBC的CURD操作之修改操作
@Test
/**
* 修改操作的代码实现
*/
public void demo2(){
Connection conn = null;
Statement stmt = null;
try{
// 注册驱动:
Class.forName("com.mysql.jdbc.Driver");
// 获得连接
conn = DriverManager.getConnection("jdbc:mysql:///web_test3", "root", "abc");
// 执行操作:
// 创建执行SQL语句的对象:
stmt = conn.createStatement();
// 编写SQL语句:
String sql = "update user set password='abc',nickname='旺财' where id = 5";
// 执行SQL语句:
int num = stmt.executeUpdate(sql);
if(num > 0){
System.out.println("修改用户成功!!!");
}
}catch(Exception e){
e.printStackTrace();
}finally{
// 资源释放:
if(stmt != null){
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
stmt = null;
}
if(conn != null){
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
conn = null;
}
}
}
1.1 JDBC的CRUD操作之删除操作
@Test
/**
* 删除操作的代码实现
*/
public void demo3(){
Connection conn = null;
Statement stmt = null;
try{
// 注册驱动:
Class.forName("com.mysql.jdbc.Driver");
// 获得连接:
conn = DriverManager.getConnection("jdbc:mysql:///web_test3", "root", "abc");
// 创建执行SQL语句对象:
stmt = conn.createStatement();
// 编写SQL:
String sql = "delete from user where id = 5";
// 执行SQL:
int num = stmt.executeUpdate(sql);
if(num > 0){
System.out.println("删除用户成功!!!");
}
}catch(Exception e){
e.printStackTrace();
}finally{
// 资源释放:
if(stmt != null){
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
stmt = null;
}
if(conn != null){
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
conn = null;
}
}
}
1.1 JDBC的CRUD操作之查询操作
1.1.1 查询多条记录
@Test
/**
* 查询多条记录
*/
public void demo4(){
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
try{
// 注册驱动
Class.forName("com.mysql.jdbc.Driver");
// 获得连接
conn = DriverManager.getConnection("jdbc:mysql:///web_test3", "root", "abc");
// 执行操作
// 创建执行SQL语句的对象:
stmt = conn.createStatement();
// 编写SQL:
String sql = "select * from user";
// 执行SQL:
rs = stmt.executeQuery(sql);
// 遍历结果集:
while(rs.next()){
System.out.println(rs.getInt("id")+" "+rs.getString("username")+" "+rs.getString("password"));
}
}catch(Exception e){
e.printStackTrace();
}finally{
// 资源释放:
if(rs != null){
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
rs = null;
}
if(stmt != null){
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
stmt = null;
}
if(conn != null){
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
conn = null;
}
}
}
1.1.2 查询一条记录
@Test
/**
* 查询一条记录
*/
public void demo5(){
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
try{
// 注册驱动
Class.forName("com.mysql.jdbc.Driver");
// 获得连接
conn = DriverManager.getConnection("jdbc:mysql:///web_test3", "root", "abc");
// 执行SQL
// 创建执行SQL语句对象:
stmt = conn.createStatement();
// 编写SQL:
String sql = "select * from user where id = 4";
rs = stmt.executeQuery(sql);
// 判断就可以:
if(rs.next()){
System.out.println(rs.getInt("id")+" "+rs.getString("username")+" "+rs.getString("password"));
}
}catch(Exception e){
e.printStackTrace();
}finally{
// 资源释放:
if(rs != null){
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
rs = null;
}
if(stmt != null){
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
stmt = null;
}
if(conn != null){
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
conn = null;
}
}
}
【1.1 JDBC的工具类的抽取】
1.1.1 抽取一个JDBC的工具类
因为传统JDBC的开发,注册驱动,获得连接,释放资源这些代码都是重复编写的。所以可以将重复的代码提取到一个类中来完成。
/**
* JDBC的工具类
* @author jt
*
*/
public class JDBCUtils {
private static final String driverClassName;
private static final String url;
private static final String username;
private static final String password;
static{
driverClassName="com.mysql.jdbc.Driver";
url="jdbc:mysql:///web_test3";
username="root";
password="abc";
}
/**
* 注册驱动的方法
*/
public static void loadDriver(){
try {
Class.forName(driverClassName);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
/**
* 获得连接的方法
*/
public static Connection getConnection(){
Connection conn = null;
try{
// 将驱动一并注册:
loadDriver();
// 获得连接
conn = DriverManager.getConnection(url,username, password);
}catch(Exception e){
e.printStackTrace();
}
return conn;
}
/**
* 释放资源的方法
*/
public static void release(Statement stmt,Connection conn){
if(stmt != null){
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
stmt = null;
}
if(conn != null){
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
conn = null;
}
}
public static void release(ResultSet rs,Statement stmt,Connection conn){
// 资源释放:
if(rs != null){
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
rs = null;
}
if(stmt != null){
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
stmt = null;
}
if(conn != null){
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
conn = null;
}
}
}
1.1.2 测试工具类
@Test
/**
* 查询操作:使用工具类
*/
public void demo1(){
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
try{
// 获得连接:
conn = JDBCUtils.getConnection();
// 创建执行SQL语句的对象:
stmt = conn.createStatement();
// 编写SQL:
String sql = "select * from user";
// 执行查询:
rs = stmt.executeQuery(sql);
// 遍历结果集:
while(rs.next()){
System.out.println(rs.getInt("id")+" "+rs.getString("username")+" "+rs.getString("password"));
}
}catch(Exception e){
e.printStackTrace();
}finally{
// 释放资源:
JDBCUtils.release(rs, stmt, conn);
}
}
【1.1 JDBC的配置信息提取到配置文件】
1.1.1 配置文件
属性文件
格式:扩展名是.properties
内容:key=value
XML文件
1.1.2 提取信息到配置文件
定义一个配置文件
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql:///web_test3
username=xxx
password=xxx
1.1.3 在工具类中解析属性文件
获取到具体内容为常量赋值
【1.1 JDBC的CRUD操作之PreparedStatement的增-删-改-查操作】
1.1.1 保存操作代码实现
@Test
/**
* 保存操作
*/
public void demo1(){
Connection conn = null;
PreparedStatement pstmt = null;
try{
// 获得连接:
conn = JDBCUtils.getConnection();
// 编写SQL语句:
String sql = "insert into user values (null,?,?,?,?)";
// 预编译SQL:
pstmt = conn.prepareStatement(sql);
// 设置参数:
pstmt.setString(1, "eee");
pstmt.setString(2, "abc");
pstmt.setString(3, "旺财");
pstmt.setInt(4, 32);
// 执行SQL
int num = pstmt.executeUpdate();
if(num > 0){
System.out.println("保存成功!");
}
}catch(Exception e){
e.printStackTrace();
}finally{
JDBCUtils.release(pstmt, conn);
}
}
1.1.1 修改操作代码实现
@Test
/**
* 修改操作
*/
public void demo2(){
Connection conn = null;
PreparedStatement pstmt = null;
try{
// 获得连接:
conn = JDBCUtils.getConnection();
// 编写SQL语句:
String sql = "update user set username = ?,password =?,nickname=?,age = ? where id = ?";
// 预编译SQL:
pstmt = conn.prepareStatement(sql);
// 设置参数:
pstmt.setString(1, "abc");
pstmt.setString(2, "1234");
pstmt.setString(3, "旺旺");
pstmt.setInt(4, 23);
pstmt.setInt(5, 6);
// 执行SQL:
int num = pstmt.executeUpdate();
if(num > 0){
System.out.println("修改成功!");
}
}catch(Exception e){
e.printStackTrace();
}finally{
JDBCUtils.release(pstmt, conn);
}
}
1.1.1 删除操作的代码实现
@Test
/**
* 删除操作
*/
public void demo3(){
Connection conn = null;
PreparedStatement pstmt = null;
try{
// 获得连接:
conn = JDBCUtils.getConnection();
// 编写SQL语句:
String sql = "delete from user where id = ?";
// 预编译SQL
pstmt = conn.prepareStatement(sql);
// 设置参数:
pstmt.setInt(1, 4);
// 执行SQL:
int num = pstmt.executeUpdate();
if(num > 0){
System.out.println("删除成功!");
}
}catch(Exception e){
e.printStackTrace();
}finally{
JDBCUtils.release(pstmt, conn);
}
}
1.1.1 查询操作代码实现
@Test
/**
* 查询操作
*/
public void demo4(){
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
try{
// 获得连接:
conn = JDBCUtils.getConnection();
// 编写SQL:
String sql = "select * from user";
// 预编译SQL:
pstmt = conn.prepareStatement(sql);
// 设置参数:
// 执行SQL:
rs = pstmt.executeQuery();
// 遍历结果集:
while(rs.next()){
System.out.println(rs.getInt("id")+" "+rs.getString("username")+" "+rs.getString("password")+" "+rs.getString("nickname"));
}
}catch(Exception e){
e.printStackTrace();
}finally{
JDBCUtils.release(rs, pstmt, conn);
}
}
【1.1 JDBC的批处理操作】
1.1.1 什么是批处理
之前进行JDBC的操作的时候,都是一条SQL语句执行。现在如果使用批处理,可以将一批SQL一起执行。
1.1.2 批处理基本使用
@Test
/**
* 批处理基本操作
*/
public void demo1(){
Connection conn = null;
Statement stmt = null;
try{
// 获得连接:
conn = JDBCUtils.getConnection();
// 创建执行批处理对象:
stmt = conn.createStatement();
// 编写一批SQL语句:
String sql1 = "create database test1";
String sql2 = "use test1";
String sql3 = "create table user(id int primary key auto_increment,name varchar(20))";
String sql4 = "insert into user values (null,'aaa')";
String sql5 = "insert into user values (null,'bbb')";
String sql6 = "insert into user values (null,'ccc')";
String sql7 = "update user set name = 'mmm' where id = 2";
String sql8 = "delete from user where id = 1";
// 添加到批处理
stmt.addBatch(sql1);
stmt.addBatch(sql2);
stmt.addBatch(sql3);
stmt.addBatch(sql4);
stmt.addBatch(sql5);
stmt.addBatch(sql6);
stmt.addBatch(sql7);
stmt.addBatch(sql8);
// 执行批处理:
stmt.executeBatch();
}catch(Exception e){
e.printStackTrace();
}finally{
JDBCUtils.release(stmt, conn);
}
}
1.1.3 批量插入(使用PreparedStatement)
@Test
/**
* 批量插入记录:
* * 默认情况下MySQL批处理没有开启的,需要在url后面拼接一个参数即可。
*/
public void demo2(){
// 记录开始时间:
long begin = System.currentTimeMillis();
Connection conn = null;
PreparedStatement pstmt = null;
try{
// 获得连接:
conn = JDBCUtils.getConnection();
// 编写SQL语句:
String sql = "insert into user values (null,?)";
// 预编译SQL:
pstmt = conn.prepareStatement(sql);
for(int i=1;i<=10000;i++){
pstmt.setString(1, "name"+i);
// 添加到批处理
pstmt.addBatch();
// 注意问题:
// 执行批处理
if(i % 1000 == 0){
// 执行批处理:
pstmt.executeBatch();
// 清空批处理:
pstmt.clearBatch();
}
}
}catch(Exception e){
e.printStackTrace();
}finally{
JDBCUtils.release(pstmt, conn);
}
long end = System.currentTimeMillis();
System.out.println((end-begin));
}
|