DataBase 简称:DB
用于存储和管理数据的仓库。
1.持久化存储数据的。其实数据库就是一个文件系统; 2.方便存储和管理数据; 3.使用了统一的方式操作数据库 — SQL
具体自己百度查询
Structured Query Language:结构化查询语言
其实就是定义了操作所有关系数据库的规则。每一种数据库操作的方式存在不一样的地方,称为“方言”。
mysql> create database db1;
Query OK, 1 row affected (0.15 sec)
mysql> create database if not exists db2;
Query OK, 1 row affected (0.18 sec)
mysql> create database db3 character set gbk;
Query OK, 1 row affected (0.16 sec)
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| db1 |
| db2 |
| db3 |
| db4 |
| information_schema |
| mysql |
| performance_schema |
| sys |
+--------------------+
8 rows in set (0.37 sec)
mysql> show create database db3;
+----------+------------------------------------------------------------------------------------------------+
| Database | Create Database |
+----------+------------------------------------------------------------------------------------------------+
| db3 | CREATE DATABASE `db3` /*!40100 DEFAULT CHARACTER SET gbk */ /*!80016 DEFAULT ENCRYPTION='N' */ |
+----------+------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
mysql> alter database db4 character set utf8;
Query OK, 1 row affected, 1 warning (0.49 sec)
mysql> drop database db4;
Query OK, 0 rows affected (0.21 sec)
mysql> drop database if exists db3;
Query OK, 0 rows affected (0.17 sec)
mysql> select database();
+------------+
| database() |
+------------+
| NULL |
+------------+
1 row in set (0.00 sec)
mysql> use db2;
Database changed
mysql> select database();
+------------+
| database() |
+------------+
| db2 |
+------------+
1 row in set (0.00 sec)
create table 表名(
列名1 数据类型1,
列名2 数据类型2,
...
列名n 数据类型n
);
* 注意:最后一列,不需要加逗号(,)
*注意 :5表示总共取5位,2表示小数点后2位
mysql> desc student;
+-------------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------------+-------------+------+-----+---------+-------+
| id | int | YES | | NULL | |
| name | varchar(20) | YES | | NULL | |
| age | int | YES | | NULL | |
| score | double(3,1) | YES | | NULL | |
| birthday | date | YES | | NULL | |
| insert_time | timestamp | YES | | NULL | |
+-------------+-------------+------+-----+---------+-------+
6 rows in set (0.00 sec)
mysql> use db1;
Database changed
mysql> create table student(
-> id int,
-> name varchar(20),
-> age int,
-> score double(3,1),
-> birthday date,
-> insert_time timestamp
-> );
Query OK, 0 rows affected, 1 warning (0.28 sec)
create table 表名 like 被复制的表名;
mysql> use mysql;
Database changed
mysql> show tables;
+---------------------------+
| Tables_in_mysql |
+---------------------------+
| columns_priv |
| component |
| db |
| user |
+---------------------------+
4 rows in set (0.10 sec)
mysql> desc db;
+-----------------------+---------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-----------------------+---------------+------+-----+---------+-------+
| Host | char(255) | NO | PRI | | |
| Db | char(64) | NO | PRI | | |
| User | char(32) | NO | PRI | | |
+-----------------------+---------------+------+-----+---------+-------+
3 rows in set (0.00 sec)
alter table 表名 rename to 新的表名;
alter table 表名 character set 新字符集名称;
alter table 表名 add 列名 数据类型;
1.alter table 表名 change 列名 新列名 新数据类型;
2.alter table 表名 modify 列名 新数据类型; -- 只修改列的数据类型
alter table 表名 drop 列名;
mysql> drop table if exists stu;
Query OK, 0 rows affected (0.68 sec)
* 语法:
insert into 表名(列名1,列名2,...列名n) values(值1,值2,...值n);
insert into 表名 values(值1,值2,...值n);
INSERT INTO stu(id,NAME,age) VALUES(1001,'露娜',18); -- 给指定列添加数据
INSERT INTO stu VALUES(1002,'貂蝉',19,99.9,'2000-01-01',NULL); -- 默认全部添加数据
SELECT * FROM stu; -- 查询表中的数据
* 语法:
delete from 表名 where 条件; -- 删除具体某一行数据
1.delete from 表名; --不推荐使用。有多少条记录就会执行多少次删除操作,效率低;
2.truncate table 表名; --推荐使用,效率更高;先删除表,然后再创建一张一模一样的表。
DELETE FROM stu WHERE id=1001;
DELETE FROM stu;
TRUNCATE TABLE stu;
* 语法:
update 表名 set 列名 = 值1,列名2 = 值2,... [where 条件];
UPDATE stu SET age = 20 WHERE id = 1002; -- 修改某一列某一数据
UPDATE stu SET age = 21; -- 修改表中全部某一数据的值为统一的值
select
字段列表
from
表名列表
where
条件列表
group by
分组字段
having
分组之后的条件
order by
排序
limit
分页限定
select 字段名1,字段名2,... from 表名;
distinct
as : as也可以省略
-- 创建表
CREATE TABLE student (
id INT, -- 编号
NAME VARCHAR(20), -- 姓名
age INT, -- 年龄
sex VARCHAR(5), -- 性别
address VARCHAR(100), -- 地址
math INT, -- 数学
english INT -- 英语
);
-- 添加数据
INSERT INTO student(id,NAME,age,sex,address,math,english) VALUES(1,'马云',55,'男','杭州',66,78),
(2,'马化腾',45,'女','深圳',98,87),(3,'马克涛',55,'男','香港',56,77),(4,'柳岩',20,'女','湖南',76,65),
(5,'柳青',20,'男','湖南',86,NULL),(6,'刘德华',57,'男','香港',99,99),
(7,'马德',22,'女','香港',99,99),(8,'德玛西亚',18,'男','南京',56,65);
-- 查询编号和姓名
SELECT id,NAME FROM student;
-- 查询地址
SELECT address FROM student;
-- 去重,地址里面有重复的
SELECT DISTINCT address FROM student;
-- 计算每个人成绩总分
SELECT NAME,math,english,math + english FROM student;
-- 因为null参加的运算,结果都为null
-- 所以利用ifnull计算
SELECT DISTINCT NAME,math,english,math + IFNULL(english,0) FROM student;
-- 起别名
SELECT DISTINCT NAME AS 姓名,math AS 数学,english AS 英语,math + IFNULL(english,0) AS 总分 FROM student;
-- 起别名 中 AS 也可以省略
SELECT DISTINCT NAME 姓名,math 数学,english 英语,math + IFNULL(english,0) 总分 FROM student;
-- 查询年龄大于20的人
SELECT * FROM student WHERE age > 20;
-- 查询年龄等于20的人
SELECT * FROM student WHERE age = 20;
-- 查询年龄大于等于20的人
SELECT * FROM student WHERE age >= 20;
-- 查询年龄不等于20的人
SELECT * FROM student WHERE age != 20; -- 方式1
SELECT * FROM student WHERE age <> 20; -- 方式2
-- 查询年龄大于等于20,小于等于30的人
SELECT * FROM student WHERE age >= 20 AND age <= 30; -- 方式1
SELECT * FROM student WHERE age >= 20 && age <= 30; -- 方式2
SELECT * FROM student WHERE age BETWEEN 20 AND 30; -- 方式3
-- 查询年龄为22岁,18岁,25岁的人的信息
SELECT * FROM student WHERE age = 22 OR age = 18 OR age = 25; -- 方式1
SELECT * FROM student WHERE age IN (22,18,25);
-- 查询英语成绩为null的人
-- select * from student where english = null; -- 错误写法,NULL值不能使用 = 或者 != 进行判断
SELECT * FROM student WHERE english IS NULL;
-- 查询英语 成绩不为NULL的人
SELECT * FROM student WHERE english IS NOT NULL;
-- 查询姓马的人
SELECT * FROM student WHERE NAME LIKE '马%';
-- 查询名字第二个字为化的人
SELECT * FROM student WHERE NAME LIKE '_化%';
-- 查询名字是3个 字的人
SELECT * FROM student WHERE NAME LIKE '___'; -- "三个_"
-- 查询名字中包含德的人
SELECT * FROM student WHERE NAME LIKE '%德%';
-- 查询数学成绩,按升序排序
SELECT * FROM student ORDER BY math ASC;
-- 查询数学成绩,按降序排序
SELECT * FROM student ORDER BY math DESC;
-- 查询数学成绩,按照降序排序,如果数学成绩一样,按照英语成绩降序排序
SELECT * FROM student ORDER BY math DESC,english DESC;
注意:
-- 计算数学个数
SELECT COUNT(math) FROM student;
-- 计算英语个数
SELECT COUNT(IFNULL(english,0)) FROM student; -- 如果为null,可使用ifnull函数
-- 计算个数
SELECT COUNT(*) FROM student; -- 哪列没有NULL,就自动选取哪列计算个数
-- 计算数学最高分
SELECT MAX(math) FROM student;
-- 计算数学最小分
SELECT MIN(math) FROM student;
-- 计算数学总和
SELECT SUM(math) FROM student;
-- 计算数学平均分
SELECT AVG(math) FROM student;
-- 按照性别分组,分别查询男、女同学的数学平均分
SELECT sex,AVG(math) GROUP BY sex;
-- 按照性别分组,分别查询男、女同学的数学平均分、人数
SELECT sex,AVG(math),COUNT(id) FROM student GROUP BY sex ;
-- 按照性别分组,分别查询男、女同学的数学平均分、人数,要求:分数低于70分的,不参与分组
SELECT sex,AVG(math),COUNT(id) FROM student WHERE math > 70 GROUP BY sex;
-- 按照性别分组,分别查询男、女同学的数学平均分、人数,要求:分数低于70分的,不参与分组,
-- 分组之后,人数要大于2个人
SELECT sex,AVG(math),COUNT(id) FROM student WHERE math > 70 GROUP BY sex HAVING COUNT(id) > 2; -- 方式1
SELECT sex,AVG(math),COUNT(id) 人数 FROM student WHERE math > 70 GROUP BY sex HAVING 人数 > 2; -- 方式2
示例:
-- 每页显示3条记录
SELECT * FROM student LIMIT 0,3; -- 第1页
SELECT * FROM student LIMIT 3,3; -- 第2页
SELECT * FROM student LIMIT 6,3; -- 第3页
-- 创建表时添加非空约束
CREATE TABLE stu (
id INT,
NAME VARCHAR(20) NOT NULL -- name为非空
);
-- 创建完表后,再添加非空约束
ALTER TABLE stu MODIFY NAME VARCHAR(20) NOT NULL;
-- 删除约束
ALTER TABLE stu MODIFY NAME VARCHAR(20); -- 相当于修改
-- 创建表时,添加唯一约束
CREATE TABLE stu (
id INT,
phone_num VARCHAR(20) UNIQUE
);
* 注意:在mySQL中,唯一约束限定的列的值可以有多个NULL
-- 删除唯一约束
ALTER TABLE stu DROP INDEX phone_num;
-- 在创建表后,添加唯一约束
ALTER TABLE stu MODIFY phone_num VARCHAR(20) UNIQUE;
CREATE TABLE stu(
id INT PRIMARY KEY,
NAME VARCHAR(20)
);
ALTER TABLE stu DROP PRIMARY KEY;
ALTER TABLE stu MODIFY id INT PRIMARY KEY;
ALTER TABLE stu MODIFY id INT ;
ALTER TABLE stu MODIFY id INT AUTO_INCREMENT;
CREATE TABLE stu (
id INT PRIMARY KEY AUTO_INCREMENT,
NAME VARCHAR(20)
);
-- 添加数据
INSERT INTO stu(id,NAME) VALUES (1,'露娜');
INSERT INTO stu(id,NAME) VALUES (NULL,'貂蝉');
* 语法:
create table 表名 (
...
外键列,
constraint 外键名称 foreign key (外键列名称) references 主表名称(主表列名称)
);
alter table 表名 drop foreign key 外键名称;
alter table 表名 add constraint 外键名称 foreign key (外键字段名称) references 主表名称(主列表名称);
* 语法:
alter table 表名 add constraint 外键名称
foreign key (外键字段名称) references 主表名称(主表列名称) on update cascade on delete cascade;
CREATE TABLE table_uy (
uid INT , -- 线路id
yid INT , -- 用户id
-- 创建复合主键
PRIMARY KEY(uid,yid), -- 联合主键
-- 分别相互关联对方表的主键
FOREIGN KEY (uid) REFERENCES tab_yead (yid),
FOREIGN KEY (yid) REFERENCES tab_user (uid)
);
设计关系数据库时,遵从不同的规范要求,设计出合理的关系型数据库,这些不同的规范要求被称为不同的范式,各种范式呈递次规范,越高的范式数据库冗余越小。 目前关系数据库有六种范式:第一范式(1NF)、第二范式(2NF)、第三范式(3NF)、巴斯-科德范式(BCNF)、第四范式(4NF)和第五范式(5NF,又称完美范式)
* 主属性:码属性组中所有的属性 * 非主属性:除过码属性组的属性
# 创建部门表
CREATE TABLE dept (
id INT PRIMARY KEY AUTO_INCREMENT,
NAME VARCHAR(20)
);
INSERT INTO dept(NAME) VALUES ('开发部'),('市场部'),('财务部');
# 创建员工表
CREATE TABLE emp (
id INT PRIMARY KEY AUTO_INCREMENT,
NAME VARCHAR(10),
sex CHAR(1),
salary DOUBLE,
jion_date DATE,
dept_id INT,
FOREIGN KEY (dept_id) REFERENCES dept(id) -- 外键,关联部门表(部门表的主键)
);
INSERT INTO emp (NAME,sex,salary,jion_date,dept_id) VALUES ('孙悟空','男',7200,'2013-02-24',1),
('猪八戒','男',3600,'2010-12-02',2),
('唐曾','男',9600,'2008-08-08',2),
('白骨精','女',5000,'2015-10-17',3),
('蜘蛛精','女',4500,'2011-03-04',1);
-- 查询所有员工信息和对应的部门信息
SELECT * FROM emp,dept WHERE emp.dept_id = dept.id;
-- 查询员工表的名称,性别。部门表的名称
SELECT emp.name,emp.sex,dept.name FROM emp,dept WHERE emp.dept_id = dept.id;
-- 标准写法
SELECT
a.name, -- 员工表姓名
a.sex, -- 员工表性别
b.name -- 部门表姓名
FROM
emp a,
dept b
WHERE
a.dept_id = b.id
* 语法:
select 字段列表 from 表名1 [inner] jion 表名2 on 条件
* 示例:
-- 查询所有员工信息和对应的部门信息
SELECT * FROM emp INNER JOIN dept ON emp.dept_id = dept.id;
SELECT * FROM emp JOIN dept ON emp.dept_id = dept.id; -- inner可以省略
-- 左外连接
SELECT * FROM emp LEFT OUTER JOIN dept ON emp.dept_id = dept.id;
-- 右外连接
SELECT * FROM dept RIGHT OUTER JOIN emp ON emp.dept_id = dept.id;
-- 查询最高工资员工信息
-- 1.先查询最高工资是多少
SELECT MAX(salary) FROM emp;
-- 2.查询员工信息,工资等于9600的
SELECT * FROM emp WHERE salary = 9600;
-- ----------------------------------------
-- 利用子查询完成
SELECT * FROM emp WHERE salary = (SELECT MAX(salary) FROM emp);
-- 查询工资小于平均工资的员工信息
SELECT * FROM emp WHERE salary < (SELECT AVG(salary) FROM emp);
-- 查询财务部和市场部的所有员工信息
SELECT id FROM dept WHERE NAME = '财务部' OR NAME = '市场部';
SELECT * FROM emp WHERE dept_id = 2 OR dept_id = 3;
SELECT * FROM emp WHERE dept_id IN (2,3);
-- 利用子查询解决
SELECT * FROM emp WHERE dept_id IN (SELECT id FROM dept WHERE NAME = '财务部' OR NAME = '市场部');
* 子查询可以作为一张虚拟表参与查询
-- 查询入职时间在2011-11-11之后的员工信息和部门信息
SELECT
*
FROM
dept a,
(SELECT * FROM emp WHERE jion_date > '2011-11-11') b
WHERE
b.dept_id = a.id;
-- ---------------------------------------------------
-- 普通内查询
SELECT * FROM emp a,dept b WHERE a.dept_id = b.id AND a.jion_date > '2011-11-11';
CREATE TABLE zhuangzhang (
NAME VARCHAR(20),
money INT
);
INSERT INTO zhuangzhang(NAME,money) VALUES ('张三',1000),('李四',1000);
-- 开启事务
START TRANSACTION;
-- 张三给李四转账
UPDATE zhuangzhang SET money = money - 500 WHERE NAME = '张三';
异常来啦
UPDATE zhuangzhang SET money = money + 500 WHERE NAME = '李四';
-- 发现没有问题,提交事务
COMMIT
-- 发现出问题了,回滚事务
ROLLBACK
多个事务之间隔离的,相互独立的。但是如果多个事务操作同一批数据,则会引发一些问题,设置不同的隔离级别就可以解决这些问题。
* 数据库查询隔离级别:
select @@tx_isolation;
* 数据库设置隔离级别:
set global transaction isolation level 级别字符串;
create user ‘用户名’ @’主机名’ identified by ‘密码’;
drop user ‘用户名‘@’主机名’;
方式1:update user set password = password(‘新密码’) where user = ‘用户名’;
方式2:set password for ‘用户名’ @’主机名’ = password(‘新密码’);
show grants for ‘用户名‘@’主机名’;
grant 权限列表 on 数据库名.表名 to ‘用户名‘@’主机名’; 给哪位用户授权什么权限,在什么数据库的什么表上
给某位用户授予所有权限,在任意数据库任意表上
grant all on *.* to '用户名'@'localhost';
revoke 权限列表 on 数据库名.表名 from ‘用户名‘@’主机名’;
* //1. 导入驱动jar包
* //2. 注册驱动
Class.forName("com.mysql.cj.jdbc.Driver"); // mysql 5版本之后可以省略
* //3. 获取数据库连接对象
//Connection conn =DriverManager.getConnection("jdbc:mysql://localhost:3306/db3", "root", "lxj521..");
Connection conn = DriverManager.getConnection("jdbc:mysql:///db3", "root", "lxj521..");//省略本机名和IP写法
* //4. 定义sql语句
String sql = "update zhuangzhang set money = 1000";
* //5. 获取执行sql的对象 Statement
Statement statement = conn.createStatement();
* //6. 执行sql
int count = statement.executeUpdate(sql);
* //7. 处理结果
System.out.println(count);
* //8. 释放资源
statement.close();
conn.close();
* 功能:
1. 注册驱动:告诉程序该使用哪一个数据库驱动jar
static void registerDriver(Driver driver):注册与给定的驱动程序DriverManager
写代码使用:Class.forName("com.mysql.jdbc.Driver")
通过查看源码发现:在com.mysql.jdbc.Driver类中存在静态代码块.
* 注意:mysql 5之后的驱动jar包可以省略注册驱动的步骤。但建议还是写上。
2. 获取数据库连接
* 方法:static Connection getConnection(String url,String user,String password)
* 参数:
* url:指定连接的路径
* 语法:jdbc:mysql://ip地址(域名):端口号/数据库名称
* 例子:jdbc:mysql://localhost:3306/db3
* 细节:如果连接的是本机mysql服务器,并且mysql服务器默认端口是3306,则url可以简写为:jdbc:mysql:///数据库名称
* user:用户名
* password:密码
* 功能:
1. 获取执行sql的对象
* Statement createStatement()
* PreparedStatement preparedStatement(String sql)
2. 管理事务:
* 开启事务:setAutoCommit(boolean autoCommit):调用该方法设置参数为false,即开启事务
* 提交事务:commit()
* 回滚事务:rollback()
* 执行sql
1. boolean execute(String sql):可以执行任意的sql(了解)
2. int executeUpdate(String sql):执行DML(insert,update,delete)语句,DDL(create,alter,drop)语句
* 返回值:影响的行数,可以通过这个影响地行数判断DML是否执行成功,返回值>0的则执行成功,反之,则失败。
3. ResultSet executeQuery(String sql):执行DQL(select)语句。
* 返回值为结果集对象。
* next():游标向下移动一行
* getXxx(参数):获取数据
* Xxx:代表数据类型 如:int:getInt(), String:getString()
* 参数:
1.int :代表列的编号,从1开始。 如:getString(1)
2.String:代表列名称。 如:getDoble("balance")
public class Demo05 {
public static void main(String[] args) {
ResultSet resultSet = null;
Statement statement = null;
Connection conn = null;
try {
//1.注册驱动
Class.forName("com.mysql.cj.jdbc.Driver");
//2.获取数据库连接对象
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/db3", "root", "lxj521..");
//3.定义sql
String sql = "select * from zhuangzhang";
//4.获取sql执行对象
statement = conn.createStatement();
//5.执行sql
resultSet = statement.executeQuery(sql);
//6.处理结果
//6.1 游标向下移动一行:因为要查询第一行的数据
resultSet.next();
//6.2 获取数据
String name = resultSet.getString(1);
double money = resultSet.getDouble("money");
//7.处理结果
System.out.println(name + "===" + money);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
} finally {
////8. 释放资源
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (statement != null) {
try {
statement.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (resultSet != null) {
try {
resultSet.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
}
* boolean next():游标向下移动一行,判断当前是否是最后一行末尾(是否有数据),如果是,则返回false,如果不是则返回true
* 利用while循环遍历
while (rs.next()) {
String name = rs.getString(1);
double money = rs.getDouble("money");
System.out.println(name + "---" + money);
}
public class emp {
private int id;
private String name;
private String sex;
private double salary;
private Date jion_date;
private int dept_id;
public emp(int id, String name, String sex, double salary, Date jion_date, int dept_id) {
this.id = id;
this.name = name;
this.sex = sex;
this.salary = salary;
this.jion_date = jion_date;
this.dept_id = dept_id;
}
public emp() {
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public double getSalary() {
return salary;
}
public void setSalary(double salary) {
this.salary = salary;
}
public Date getJion_date(Date jion_date) {
return this.jion_date;
}
public void setJion_date(Date jion_date) {
this.jion_date = jion_date;
}
public int getDept_id() {
return dept_id;
}
public void setDept_id(int dept_id) {
this.dept_id = dept_id;
}
@Override
public String toString() {
return "emp{" +
"id=" + id +
", name='" + name + '\'' +
", sex=" + sex +
", salary=" + salary +
", jion_date=" + jion_date +
", dept_id=" + dept_id +
'}';
}
}
/*
* 提示:该行代码过长,系统自动注释不进行高亮。一键复制会移除系统注释
* <!--hexoPostRenderEscape:<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line"></span><br><span class="line"> * 再创建一个主类,调用emp方法</span><br><span class="line"></span><br><span class="line">```java</span><br><span class="line">public class Demo07 {</span><br><span class="line"> public static void main(String[] args) {</span><br><span class="line"> List<emp> list = new Demo07().findAll();</span><br><span class="line"> System.out.println(list);</span><br><span class="line"> System.out.println(list.size());</span><br><span class="line"></span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> public List<emp> findAll() {</span><br><span class="line"> ResultSet rs = null;</span><br><span class="line"> Statement statement = null;</span><br><span class="line"> Connection conn = null;</span><br><span class="line"></span><br><span class="line"> List<emp> list = null;</span><br><span class="line"> try {</span><br><span class="line"> //1.注册驱动</span><br><span class="line"> Class.forName("com.mysql.cj.jdbc.Driver");</span><br><span class="line"> //2.获取连接数据库对象</span><br><span class="line"> conn = DriverManager.getConnection("jdbc:mysql:///db2", "root", "lxj521..");</span><br><span class="line"> //3.定义sql</span><br><span class="line"> String sql = "select * from emp";</span><br><span class="line"> //4.获取处理sql对象</span><br><span class="line"> statement = conn.createStatement();</span><br><span class="line"> //5.处理sql</span><br><span class="line"> rs = statement.executeQuery(sql);</span><br><span class="line"> //6.处理结果</span><br><span class="line"> emp emp = null;</span><br><span class="line"> list = new ArrayList<emp>();</span><br><span class="line"> while (rs.next()) {</span><br><span class="line"> int id = rs.getInt("id");</span><br><span class="line"> String name = rs.getString("name");</span><br><span class="line"> String sex = rs.getString("sex");</span><br><span class="line"> double salary = rs.getDouble("salary");</span><br><span class="line"> Date jion_date = rs.getDate("jion_date");</span><br><span class="line"> int dept_id = rs.getInt("dept_id");</span><br><span class="line"></span><br><span class="line"> //创建emp对象,并赋值</span><br><span class="line"> emp = new emp();</span><br><span class="line"> emp.setId(id);</span><br><span class="line"> emp.setName(name);</span><br><span class="line"> emp.setSex(sex);</span><br><span class="line"> emp.setSalary(salary);</span><br><span class="line"> emp.getJion_date(jion_date);</span><br><span class="line"> emp.setDept_id(dept_id);</span><br><span class="line"></span><br><span class="line"> //装载集合</span><br><span class="line"> list.add(emp);</span><br><span class="line"> }</span><br><span class="line"> } catch (ClassNotFoundException e) {</span><br><span class="line"> e.printStackTrace();</span><br><span class="line"> } catch (SQLException e) {</span><br><span class="line"> e.printStackTrace();</span><br><span class="line"> } finally {</span><br><span class="line"> if (rs != null) {</span><br><span class="line"> try {</span><br><span class="line"> rs.close();</span><br><span class="line"> } catch (SQLException e) {</span><br><span class="line"> e.printStackTrace();</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> if (statement != null) {</span><br><span class="line"> try {</span><br><span class="line"> statement.close();</span><br><span class="line"> } catch (SQLException e) {</span><br><span class="line"> e.printStackTrace();</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> if (conn!=null) {</span><br><span class="line"> try {</span><br><span class="line"> conn.close();</span><br><span class="line"> } catch (SQLException e) {</span><br><span class="line"> e.printStackTrace();</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> return list;</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure>:hexoPostRenderEscape-->
*/
在拼接sql时,有一些sql的特殊关键字参与字符串的拼接,会造成安全性问题;
* 1.输入用户随便,输入密码:a' or 'a' = 'a
2.sql:select * from user where username = "ahdahal" and password = a' or 'a' = 'a
1.导入驱动jar包;
2.注册驱动;
3.获取数据库连接对象 Connection
4.定义sql
* 注意:sql的参数使用?作为占位符。
如:select * from user where username = ? and password = ?;
5.获取执行sql语句的对象 PreparedStatement
* Connection.prepareSttement(String sql)
6.给?赋值:
* 方法:setXxx(参数1,参数2)
* 参数1:?的位置编号 从1 开始
* 参数2:?的值
7.执行sql,接受返回结果,不需要传递sql语句
8.处理结果
9.释放资源
public class Demo02 {
public static void main(String[] args) {
//键盘录入
Scanner sc = new Scanner(System.in);
System.out.println("请输入用户名:");
String username = sc.nextLine();
System.out.println("请输入密码:");
String password = sc.nextLine();
//调用对象
boolean flag = new Demo02().login2(username, password);
//判断结果
if (flag) {
System.out.println("登录成功");
} else {
System.out.println("用户名或者密码错误");
}
}
//登录方法
public boolean login2(String username,String password) {
if ((username == null) || (password == null)) {
return false;
}
//连接数据库判断是否登录成功
Connection conn = null;
PreparedStatement pstem =null;
ResultSet rs = null;
try {
//1.获取连接数据库对象
conn = JDBCUtils.getConnection();
//2.定义sql
String sql = "select * from user where username = ? and password = ?";
//3.获取处理sql对象
pstem = conn.prepareStatement(sql);
//给?赋值
pstem.setString(1,username);
pstem.setString(2,password);
//4.执行查询sql,不需要传递sql
rs = pstem.executeQuery();
//5.判断
return rs.next();//如果有下一行,则返回true
} catch (SQLException e) {
e.printStackTrace();
} finally {
JDBCUtils.close(rs,pstem,conn);
}
return false;
}
}
* 需求:不想传递参数(麻烦),还得保证工具类的通用性。
* 解决:配置文件:
* 创建 jdbc.properties 文件
url =
user =
password =
driver =
* 示例:
url=jdbc:mysql:///db2
user=root
password=lxj521..
driver=com.mysql.cj.jdbc.Driver
* 首先创建名为JDBCUtils.java 文件
/*
* JDBC工具类
* */
import java.io.FileReader;
import java.io.IOException;
import java.net.URL;
import java.sql.*;
import java.util.Collection;
import java.util.Properties;
public class JDBCUtils {
private static String url;
private static String user;
private static String password;
private static String driver;
/*
* 文件的读取,只需要读取一次即可拿到这些值。只用静态代码块
* */
static {
//读取资源文件,获取值
try {
//1.创建Properties集合类
Properties pro = new Properties();
//获取src路径下的文件的方式:ClassLoader 类加载器
ClassLoader classLoader = JDBCUtils.class.getClassLoader();
URL resource = classLoader.getResource("jdbc.properties");
String path = resource.getPath();
//System.out.println(path);
//2.加载文件
// pro.load(new FileReader("src/jdbc.properties"));
pro.load(new FileReader(path));
//3.获取数据,赋值
url = pro.getProperty("url");
user = pro.getProperty("user");
password = pro.getProperty("password");
driver = pro.getProperty("driver");
//4.注册驱动
Class.forName(driver);
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
/*
* 获取连接
* @return 连接对象
* */
public static Connection getConnection() throws SQLException {
return DriverManager.getConnection(url,user,password);
}
/*
* 释放资源
* */
public static void close(Statement statement,Connection conn) {
if (statement != null) {
try {
statement.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
//释放资源,重载
public static void close(ResultSet rs,Statement statement,Connection conn) {
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (statement != null) {
try {
statement.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (conn!=null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
public class Demo {
public static void main(String[] args) {
List<emp> list = new Demo().findAll();
System.out.println(list);
System.out.println(list.size());
}
public List<emp> findAll() {
ResultSet rs = null;
Statement statement = null;
Connection conn = null;
List<emp> list = null;
try {
//1.注册驱动
// Class.forName("com.mysql.cj.jdbc.Driver");
//2.获取连接数据库对象
// conn = DriverManager.getConnection("jdbc:mysql:///db2", "root", "lxj521..");
conn = JDBCUtils.getConnection();
//3.定义sql
String sql = "select * from emp";
//4.获取处理sql对象
statement = conn.createStatement();
//5.处理sql
rs = statement.executeQuery(sql);
//6.处理结果
emp emp = null;
list = new ArrayList<emp>();
while (rs.next()) {
int id = rs.getInt("id");
String name = rs.getString("name");
String sex = rs.getString("sex");
double salary = rs.getDouble("salary");
Date jion_date = rs.getDate("jion_date");
int dept_id = rs.getInt("dept_id");
//创建emp对象,并赋值
emp = new emp();
emp.setId(id);
emp.setName(name);
emp.setSex(sex);
emp.setSalary(salary);
emp.getJion_date(jion_date);
emp.setDept_id(dept_id);
//装载集合
list.add(emp);
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
//释放资源
JDBCUtils.close(rs, statement, conn);
}
return list;
}
}
一个包含多个步骤的业务操作。如果这个业务操作被事务管理,则这多个步骤要么同时成功,要么同时失败。
* 开启事务:setAutoCommit(boolean autoCommit):调用该方法设置参数为false,即开启事务;
* 在执行sql之前开启事务
* 提交事务:commit()
* 当所有sql都执行完提交事务
* 回滚事务:rollback()
* 在catch中回滚事务
public class Demo3 {
public static void main(String[] args) {
PreparedStatement pstm1 = null;
PreparedStatement pstm2 = null;
Connection conn = null;
try {
//1.注册驱动
conn = JDBCUtils.getConnection();
//开启事务
conn.setAutoCommit(false);
//2.定义sql
String sql1 = "update zhuangzhang set money = money - ? where name = ?";
String sql2 = "update zhuangzhang set money = money + ? where name = ?";
//3.获取处理sql对象
pstm1 = conn.prepareStatement(sql1);
pstm2 = conn.prepareStatement(sql2);
//4.给?赋值
pstm1.setDouble(1, 500);
pstm1.setString(2, "张三");
pstm2.setDouble(1, 500);
pstm2.setString(2, "李四");
//5.处理sql,不需要获取sql
pstm1.executeUpdate();
//手动设置异常
int i = 3 / 0;
pstm2.executeUpdate();
} catch (SQLException e) {
//回滚事务
try {
if (conn != null) {
conn.rollback();
}
} catch (Exception ex) {
ex.printStackTrace();
}
e.printStackTrace();
} finally {
//释放资源
JDBCUtils.close(pstm1, conn);
JDBCUtils.close(pstm2, null);
}
}
}
其实就是一个容器(集合),存放数据库连接的容器。
当系统初始化好后,容器被创建,容器中会申请宁一些连接对象,当用户来访问数据库时,从容器中中获取连接对象,榕湖访问完之后,会将连接对象归还给容器。
方法:
* 获取连接:getConnection()
* 归还连接:Connection.close().如果连接对象Connection是从连接池获取的,那么调用Connection.close()方法,则不会再关闭连接了,而是归还连接。
* 步骤:
1.导入jar包(两个)c3p0-0.9.5.5-sources.jar和mchange-commons-java-0.2.19-sources.jar;
* 不要忘记导入数据库驱动jar包:mysql-connector-java-8.0.19.jar
2.定义配置文件:
* 名称:c3p0.properties 或者 c3p0-config.xml
* 路径:直接将文件放在src目录下即可。
3.创建核心对象:
数据库连接池对象 ComboPooledDataSource
4.获取连接:getConnection
* 步骤:
//1.导入jar包 druid-1.1.18.jar
//2.定义配置文件
* 是properties形式的
* 可以叫任意名称,可以放在任意目录下
//3.加载配置文件 Properties
Properties pro = new Properties(); InputStreamis=DruidDemo.class.getClassLoader().getResourceAsStream("druid.properties");
pro.load(is);
//4.获取连接池对象:通过工厂来获取 DruidDataSourceFactory
DataSource ds = DruidDataSourceFactory.createDataSource(pro);
//5.获取连接 getConnection
Connection conn = ds.getConnection();
System.out.println(conn);
driverClassName=com.mysql.cj.jdbc.Driver
url=jdbc:mysql:///db3
username=root
password=lxj521..
# 初始化连接数量
initialSize=5
# 最大连接数
maxActive=10
# 最大等待时间
maxWait=3000
1.定义一个类:JDBCUtils
2.提供静态代码块加载配置文件,初始化连接池对象
3.提供方法
1.获取连接方法:通过数据库连接池获取连接;
2.释放资源;
3.获取连接池的方法。
public class JDBCUtils {
//1.定义成员变量 DataSours
private static DataSource ds;
static {
try {
//1.记载配置文件
Properties prop = new Properties();
prop.load(JDBCUtils.class.getClassLoader().getResourceAsStream("druid.properties"));
//2.获取DataSource
ds = DruidDataSourceFactory.createDataSource(prop);
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
//获取连接
public static Connection getConnection() throws SQLException {
return ds.getConnection();
}
//释放资源
public static void close(Statement statement,Connection conn) {
// if (statement != null) {
// try {
// statement.close();
// } catch (SQLException e) {
// e.printStackTrace();
// }
// }
// if (conn != null) {
// try {
// conn.close(); //归还连接
// } catch (SQLException e) {
// e.printStackTrace();
// }
// }
close(null,statement,conn);
}
public static void close(ResultSet resultSet,Statement statement, Connection conn) {
if (resultSet != null) {
try {
resultSet.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (statement != null) {
try {
statement.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (conn != null) {
try {
conn.close(); //归还连接
} catch (SQLException e) {
e.printStackTrace();
}
}
}
//获取连接池方法
public static DataSource getDataSource() {
return ds;
}
}
public class Demo02 {
public static void main(String[] args) {
Connection conn = null;
PreparedStatement ps = null;
try {
//1.获取连接:
conn = JDBCUtils.getConnection();
//2.定义sql:
String sql = "insert into zhuangzhang value (?,?)";
//3.获取处理sql对象
ps = conn.prepareStatement(sql);
//4.给?赋值
ps.setString(1, "王五");
ps.setDouble(2, 2000);
//5.执行sql
int count = ps.executeUpdate();
System.out.println(count);
} catch (SQLException e) {
e.printStackTrace();
} finally {
//6.释放资源
JDBCUtils.close(ps, conn);
}
}
}
spring JDBC
1.导入jar包 2.创建JDBCTemplate对象,依赖于数据源DataSource * JdbcTemplate template = new JdbcTemplate(ds); 3.调用JdbcTemplate的方法来完成CRUD的操作: * update():执行DML语句。增删改 * queryForMap():查询结果将结果集封装为map集合 * queryForList():查询结果将结果集封装为list集合 * query():查询结果,将结果封装为JavaBean对象 * queryForObject:查询结果,将结果封装为对象
https://repo.spring.io/release/org/springframework/
文章作者: silentcow
文章链接: http://silentcow.cn/2020/08/06/MySQL%E4%B8%8EJDBC%E7%B2%BE%E8%AE%B2%E7%AC%94%E8%AE%B0/