目录
一. 关联关系和关联查询
1.1 关联关系
1. 指创建表时,表和表之间存在的业务关系。数据库中有三种关联关系:
- 一对一:有AB两张表,A表中的一条数据对应B表中的一条数据, 同时B表中的一条数据也对应A表中的一条数据。
- 一对多:有AB两张表, A表中的一条数据对应B表中的多条数据, 同时B表中的一条数据对应A表中的一条数据。
- 多对多:有AB两张表, A表中的一条数据对应B表中的多条数据, 同时B表中的一条数据也对应A表中的多条数据。
2. 如果两张表之间存在关联关系,如何建立关系?
一对一:可以在两张关系表中任何一个表里面添加建立关系的字段,指向另外一张表的主键。
一对多:在一对多的两张表里面的表示"多"的表中添加建立关系的字段指向另外一张表的主键。
多对多:需要创建一个单独的关系表,关系表中两个字段分别指向另外两张表的主键 。
1.2 关联查询
同时查询多张表数据的查询方式称为关联查询。
关联查询包括: 等值链接, 内连接和外连接。
1.2.1 关联查询之等值连接
格式:select * from A,B where 关联关系 and 其它条件
//查询每个员工的姓名和对应的部门名
select e.name,d.namefrom emp e,dept d where e.dept_id=d.id;
//查询工资高于2000的员工姓名,工资和部门信息
select e.name,e.sal,d.* from emp e,dept d where e.dept_id=d.id and sal>2000;
1.2.2 关联查询之内连接
内连接和等值链接作用一样,查询到的都是两个表的交集数据,查询不到交集以外的数据。
格式:select * from A join B on 关联关系 where 条件
//查询每个员工的姓名和对应的部门名
select e.name,d.namefrom emp e join dept d on e.dept_id=d.id;
//查询工资高于2000的员工姓名,工资和部门信息
select e.name,sal,d.*from emp e join dept d on e.dept_id=d.idwhere sal>2000;
1.2.3 关联查询之外连接
查询一张表的全部和另外一张表的交集数据。
格式:select * from A left/right join B on 关联关系 where 条件;
//查询所有员工名和对应的部门名
select e.name,d.namefrom emp e left join dept d on e.dept_id=d.id;
//查询所有部门名称,地点和对应的员工姓名和工资,只查询有领导的员工
select d.name,loc,e.name,salfrom emp e right join dept d on dept_id=d.id where e.manager is not null;
总结:
如果查询的是多张表中的数据则使用关联查询:(等值链接,内连接和外连接)
如果查询的是多张表的交集数据,则使用等值链接或内连接(推荐)
如果查询的是一张表的全部和其它表的交集数据则使用外连接
二. JDBC
JDBC:(JavaDataBaseConnectivity)Java数据库链接,通过Java代码执行所学的SQL语句。 JDBC是Sun公司提供的一套专门用于Java语言和数据库进行连接的API(Application Programma Interface应用程序编程接口)。
Sun公司为了避免Java程序员每一种数据库软件都学习一套新的方法, 通过JDBC接口将方法名定义好,各个数据库厂商根据此接口中的方法名写各自的实现类(jar包(驱动)), 这样Java程序员只需要掌握JDBC接口中方法的调用即可访问任何数据库, 即使在工作中换了数据库软件,代码也不需要发生改变 。
2.1 JDBC连接
1. 创建Maven工程,在工程的pom.xml文件中添加MySQL驱动的依赖、修改jdk和字符集。
<properties>
<!-- 设置 JDK 版本为 1.8 -->
<maven.compiler.target>1.8</maven.compiler.target>
<maven.compiler.source>1.8</maven.compiler.source>
<!-- 设置编码为 UTF-8 -->
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<maven.compiler.encoding>UTF-8</maven.compiler.encoding>
</properties>
<!--添加MySQL相关的依赖,Maven会通过此依赖找到对应的jar包文件下载到工程中-->
<dependencies>
<!-- 连接MySQL数据库的依赖 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.15</version>
</dependency>
</dependencies>
2. 修改完之后记得刷新Maven
3. 创建XXX.java类文件, 在main方法中添加以下代码
//1.建立链接,有异常抛出
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/dbName?characterEncoding=utf8&serverTimezone=Asia/Shanghai&useSSL=false","root","root");
System.out.println("链接对象:"+conn);
//2.创建执行SQL语句的对象
Statement s = conn.createStatement();
//3.执行SQL语句
execute=执行s.execute("create table jdbct1(id int)");
//4.关闭资源 断开链接
conn.close();
System.out.println("执行完成!");
2.2 Statement执行SQL语句的对象
- execute("sql"); 可以执行任意sql语句,但是推荐执行DDL(数据定义语言,包括数据库相关和表相关)。
- int row = executeUpdate("sql"); 执行增删改, 此方法的返回值为生效的行数。
- ResultSet rs = executeQuery("sql"); 执行查询相关的SQL语句, ResultSet对象里面装着查询回来的结果。
2.3 DBCP数据库连接池
DataBaseConnectionPool: 数据库连接池
作用: 将链接重用,避免频繁的开关链接所带来的资源浪费
2.3.1 如何使用数据库连接池
1. 在pom.xml文件中添加连接池相关的依赖
<!-- 数据库连接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.21</version>
</dependency>
2. 添加代码
//创建表示连接池的对象
DruidDataSource ds = new DruidDataSource();
//设置链接数据库的信息
ds.setUrl("jdbc:mysql://localhost:3306/dbName?characterEncoding=utf8&serverTimezone=Asia/Shanghai&useSSL=false");
ds.setUsername("root");
ds.setPassword("root"); //写自己的密码
//设置初始连接数量
ds.setInitialSize(3);
//设置最大连接数量
ds.setMaxActive(5);
//从连接池中获取链接 异常抛出
Connection conn = ds.getConnection();
System.out.println("连接对象:"+conn);
三. 关于SQL注入
- SQL注入是往本应该传值的地方,传递进去了SQL语句导致原有SQL语句的逻辑发生改变,这个过程称为SQL注入。
- where username='xxx' and password='' or '1'='1'
- SQL注入漏洞是网站的低级漏洞,但是危害比较大, 黑客可以利用此漏洞对网站进行攻击。
PreparedStatement
- 通过PreparedStatement执行SQL语句可以避免出现SQL注入漏洞
- 内部原理: 使用PreparedStatement 可以起到预编译的作用, 可以将编译SQL语句的时间点提前(从之前执行SQL语句时编译提前到创建时), 编译时间点提前可以将SQL语句中业务逻辑部分编译好(将业务部分锁死),之后将用户输入的内容替换到SQL语句时,用户输入的内容只能以值的形式添加到SQL语句中,不会影响原有SQL语句的判断逻辑,所以避免了SQL注入的漏洞
- 执行setString()方法替换?时 会自动给字符串添加引号,并且用户输入的字符串中出现了引号关键字时会进行转义操作 password=''' or ''1''=''1'
本文完!
写在结尾:
2022 年 10 月 25 日 一个java菜鸟,发布于北京海淀。
好记性不如烂笔头,持续学习,坚持输出~ 可以点赞、评论、收藏啦。