、数据库设计
1.1、范式
规则:优化数据的设计和存储。
1.2、分类
第一范式、第二范式、第三范式、BCNF、第四范式、第五范式
1.3、
第一范式
确保每个字段不可再分,确保每列原子性。
第二范式
一个表只能描述一件事情。
第三范式
消除传递依赖,所有的非键字段中,不能有传递依赖。
反三范式:性能比范式重要。
2、数据库还原和备份
2.1、什么是数据库备份
导出数据或复制表文件来制作数据库的副本。
2.2、备份
格式:
mysqldump -u用户名 -p密码 数据库名 > sql文件位置
格式:
mysqldump -u用户名 -p密码 数据库名
1、JDBC
java database connection 规范,API,接口。
jdbc与数据库驱动的关系,就是接口与实现的关系。
2、快速入门JDBC
2.1、准备好数据库与数据库表
create table user(
id int primary key auto_increment,
username varchar(20),
password varchar(20),
nickname varchar(20)
);
INSERT INTO `USER` VALUES(null,'zs','123456','老张');
INSERT INTO `USER` VALUES(null,'ls','123456','老李');
INSERT INTO `USER` VALUES(null,'wangwu','123','东方不败');
2.2、创建一个JAVA工程
maven 创建我们的java项目,包(jar包)统一管理。
pom.xml
修改pom.xml里面的配置文件,必须重新更新(reload project)。
jdbc_demo_01
2.3、准备好驱动jar包
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.28</version>
</dependency>
2.4、编写代码
(1)加载驱动
DriverManager.registerDriver(new Driver());
(2)创建数据库连接
url格式:jdbc:mysql://ip:port/dbname
String url="jdbc:mysql://localhost:3306/db02";
String username="root";
String password="Root123456";
Connection connection=DriverManager.getConnection(url,username,password);
(3)操作数据库表
需求:查询user表中所有的记录
A、准备好查询的SQL
String sql="select * from user";
B、创建执行SQL的对象
Statement statement=connection.createStatement();
C、执行SQL,得到结果集
ResultSet resultSet=statement.executeQuery(sql);
D、展示查询出来的结果
while(resultSet.next()){
System.out.print(resultSet.getObject(1)+" ");
System.out.print(resultSet.getObject(2)+" ");
System.out.print(resultSet.getObject(3)+" ");
System.out.print(resultSet.getObject(4)+" ");
System.out.println();
}
(4)释放资源
resultSet.close();
statement.close();
connection.close();
第一个案例:
package com.ww.jdbc.test;
import com.mysql.cj.jdbc.Driver;
import java.sql.*;
public class JdbcTest {
public static void main(String[] args) throws SQLException {
//1、加载驱动
DriverManager.registerDriver(new Driver());
//2、连接数据库
//声明url,username,password
String url="jdbc:mysql://localhost:3306/db02";
String username="root";
String password="Root123456";
Connection connection=DriverManager.getConnection(url,username,password);
//3、操作数据库表
String sql="select * from user";
Statement statement=connection.createStatement();
ResultSet resultSet=statement.executeQuery(sql);
//循环打印出所有记录(结果集)
while(resultSet.next()){
System.out.print(resultSet.getObject(1)+" ");
System.out.print(resultSet.getObject(2)+" ");
System.out.print(resultSet.getObject(3)+" ");
System.out.print(resultSet.getObject(4)+" ");
System.out.println();
}
//4、释放资源(先创建,后关闭)
resultSet.close();
statement.close();
connection.close();
}
}
1、JDBC API详解
1.1、DriverManager
加载驱动
DriverManager.registerDriver(new Driver())
mysql8.jar com.mysql.cj.jdbc.Driver
mysql5.jar com.mysql.jdbc.Driver
Class.forName("com.mysql.cj.jdbc.Driver"); //反射机制
创建连接
DriverManager.getConnection(url,username,password)
url地址连接mysql格式:
jdbc:mysql://ip地址:端口号/数据库名
jdbc:mysql://localhost:3306/db02
jdbc:mysql://…/db02
1.2、Connection
是数据库连接对象。
Statement<=createStatement() 创建执行SQL语句对象
拿到SQL语句就只能直接执行。
例:
Connection conn=DriverManager.getConnection(url,username,password);
Statement state=conn.createStatement();
PreparedStatement<=prepareStatement() 创建预编译执行SQL语句对象
拿到SQL语句可以先编译,在执行。
例:
Connection conn=DriverManager.getConnection(url,username,password);
PreparedStatement state=conn.prepareStatement();
1.3、Statement
直接执行写好的SQL语句。
executeQuery(sql) 只能执行DQL语句,select查询语句
例:
String sql=“select * from user”;
Connection conn=DriverManager.getConnection(url,username,password);
Statement state=conn.createStatement();
ResultSet rs=state.executeQuery(sql);
executeUpdate(sql) 只能执行DML语句,insert update delete语句
例:
String sql=“delete from user where id=1”;
Connection conn=DriverManager.getConnection(url,username,password);
Statement state=conn.createStatement();
state.executeUpdate(sql);
execute() 执行任意语句,返回true/false
例1:
String sql=“select * from user”;
Connection conn=DriverManager.getConnection(url,username,password);
Statement state=conn.createStatement();
Boolean isval=state.execute(sql);
注意:
isval为true,表示查询到了用户记录
isval为false,表示没有查询到用户记录
例2:
String sql=“delete from user where id=1”;
Connection conn=DriverManager.getConnection(url,username,password);
Statement state=conn.createStatement();
Boolean isval=state.execute(sql);
注意:
isval为false,增加语句、修改语句、删除语句没有结果集
1.4、ResultSet
对象,结果集
next() 方法:游标往下移一行,判断是否存在记录,存在就用get方法来取值
get方法:
getInt(int i) i表示的是位置 getInt(String name) name表示的是字段名
getString()
getDouble()
getBoolean()
getDate()
……
例:
String sql=“select * from user”;
Connection conn=DriverManager.getConnection(url,username,password);
Statement state=conn.createStatement();
ResultSet rs=state.executeQuery(sql);
while(rs.next()){
System.out.println(rs.getInt(1));
System.out.println(rs.getInt(“id”));
}
案例:
package com.ww.jdbc.test;
import java.sql.*;
public class JdbcTest {
public static void main(String[] args) throws SQLException, ClassNotFoundException {
//1、加载驱动
// DriverManager.registerDriver(new Driver());
Class.forName("com.mysql.cj.jdbc.Driver"); //反射机制
//2、连接数据库
//声明url,username,password
String url="jdbc:mysql://localhost:3306/db02";
String username="root";
String password="Root123456";
Connection connection=DriverManager.getConnection(url,username,password);
//3、操作数据库表
String sql="select * from user";
Statement statement=connection.createStatement();
ResultSet resultSet=statement.executeQuery(sql);
//循环打印出所有记录(结果集)
while(resultSet.next()){
System.out.print(resultSet.getObject("id")+" ");
System.out.print(resultSet.getObject("username")+" ");
System.out.print(resultSet.getObject("nickname")+" ");
System.out.print(resultSet.getObject("password")+" ");
System.out.println();
}
//4、释放资源(先创建,后关闭)
resultSet.close();
statement.close();
connection.close();
}
}
1.JDBC查询
查询 增加、删除、修改
加载驱动 加载驱动 Class.forName() Class.forName()
创建连接 创建连接 Connection Connection
创建SQL执行对象 创建SQL执行对象 Statement Statement
执行SQL ,有结果集 执行SQL没有结果集 ResultSet 无
通过实体类存入集合 释放资源 List 实体类 close()
释放资源 close()
2、抽取工具类
加载驱动 、创建连接;
释放资源;
(1)创建配置文件
resources ----> jdbc.properties
driver= com.mysql.cj.jdbc.Driver
url = jdbc:mysql://localhost:3306/ooo
username = root
password = 123456
(2)编写工具类
static {
//1-2-1将配置文件,转换成输入流
InputStream resourceAsStream = jdbc_Utils.class.getClassLoader().getResourceAsStream("jdbc.properties");
//1-2-2 、通过属性对象(Properties),关联输入流
Properties properties = new Properties();
try {
properties.load(resourceAsStream);
driver = properties.getProperty("driver");
url = properties.getProperty("url");
username = properties.getProperty("username");
password = properties.getProperty("password");
Class.forName(driver);
} catch (IOException e) {
throw new RuntimeException(e);
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}finally {
try {
resourceAsStream.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
(2-1)编写获取连接方法 ,读取配置文件加载驱动
public static Connection getConnection(){
Connection connection = null;
try {
DriverManager.getConnection(url, username, password);
} catch (SQLException e) {
throw new RuntimeException(e);
}
return connection;
}
(2-2) 编写释放资源方法
public static void closeAll(ResultSet resultSet, Statement statement,Connection connection) throws SQLException {
if (resultSet != null){
resultSet.close();
}
if (statement!= null){
statement.close();
}
if (connection != null){
connection.close();
}
}
3.工具类的使用
工具类为我们解救了2个问题 :(1)获取连接 (2)释放资源
@Test
// public void jdbcutilselect() throws SQLException {
// String select_sql = "select * from user";
// Connection connection = jdbc_Utils.getConnection();
// Statement statement = connection.createStatement();
// ResultSet resultSet = statement.executeQuery(select_sql);
// List<user> users = new ArrayList<>();
//
// while (resultSet.next()) {
// user user = new user();
// user.setId(resultSet.getInt("id"));
// user.setUsername(resultSet.getString("username"));
// user.setPassword(resultSet.getString("password"));
// user.setNickname(resultSet.getString("nickname"));
// users.add(user);
// }
// for (user i : users) {
// System.out.println(i.toString());
// }
//
// jdbc_Utils.closeAll(resultSet,statement,connection);
//
// }
// @Test
// public void jdbcutilselect01() throws SQLException {
// String select_sql = "select * from user where id = 1";
// Connection connection = jdbc_Utils.getConnection();
// Statement statement = connection.createStatement();
// ResultSet resultSet = statement.executeQuery(select_sql);
// List<user> users = new ArrayList<>();
//
// while (resultSet.next()) {
// user user = new user();
// user.setId(resultSet.getInt("id"));
// user.setUsername(resultSet.getString("username"));
// user.setPassword(resultSet.getString("password"));
// user.setNickname(resultSet.getString("nickname"));
// users.add(user);
// }
// for (user i : users) {
// System.out.println(i.toString());
// }
//
// jdbc_Utils.closeAll(resultSet, statement, connection);
//
// }
@Test
public void jdbcdelete() throws SQLException {
String delete_sql = "delete from user where id = 3";
Connection connection = jdbc_Utils.getConnection();
Statement statement = connection.createStatement();
statement.executeUpdate(delete_sql);
jdbc_Utils.closeAll(null, statement, connection);
}
1、PreparedStatement
预编译执行SQL对象
? 替换符
案例:
@Test
public void demo01() throws SQLException {
int id=3;
String sql="select * from user where id=?";
//1、获取连接
Connection connection=JdbcUtils.getConnection();
//2、获取预编译执行SQL对象
PreparedStatement ps=connection.prepareStatement(sql);
ps.setInt(1,id);
//3、执行SQL
ResultSet rs=ps.executeQuery();
//4、结果集存入到实体类,实体类存入到集合
List<User> list=new ArrayList<User>();
while(rs.next()){
User user=new User();
user.setId(rs.getInt("id"));
user.setUsername(rs.getString("username"));
user.setPassword(rs.getString("password"));
user.setNickname(rs.getString("nickname"));
list.add(user);
}
//展示集合中存放的结果集。
for(User u:list){
System.out.println(u.toString());
}
}
登录案例:
(1)分析
用一个登录页面;
去查询数据库判断有没有输入的用户和密码;
有就输出登录成功,没有就输出登录失败
(2)前期准备
输出流、输入流
数据库、数据库表、Jdbc工具类、JdbcAPI
(3)代码步骤
(3-1)idea新建maven项目
(3-2)导入依赖,mysql,junit
(3-3)创建实体类User
(3-4)创建配置文件jdbc.properties
(3-5)创建工具类JdbcUtils.java
(3-6)创建一个登录类
(3-6-1)创建输出页面的方法
(3-6-2)输入用户密码和密码
(3-6-3)去数据库查询用户名和密码是否存在
(3-6-4)存在,就输出登录成功!,不存在就输出登录失败
package com.ww.jdbc.junit;
import com.ww.jdbc_demo_01.util.JdbcUtils;
import org.junit.Test;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Scanner;
public class JdbcLogin {
public static void main(String args[]) throws SQLException {
Scanner scanner=new Scanner(System.in);
System.out.println("请输入用户名:");
String username=scanner.next();
System.out.println("请输入密码:");
String password=scanner.next();
//去数据库里面查看用户名是否存在
String sql ="select * from user where username=? and password=?";
//去数据库查询用户名和密码
//1、获取连接
Connection connection=JdbcUtils.getConnection();
//2、创建预编译对象
PreparedStatement preparedStatement=connection.prepareStatement(sql);
//3、替换替换符内容
preparedStatement.setString(1,username);
preparedStatement.setString(2,password);
//4、执行SQL得到结果集
ResultSet resultSet=preparedStatement.executeQuery();
//5、得到是否登录成功,成功就是为true,失败为False
boolean isval = false;
if(resultSet.next()){
isval = true;
}
//6、释放资源
JdbcUtils.closeAll(resultSet,preparedStatement,connection);
if(isval){
System.out.println("登录成功!");
}else{
System.out.println("登录失败!");
}
}
}
2、SQL注入
1、读取配置文件
}
Properties类
InputStream inputStream=JdbcUtils.class.getClassLoader().getResourceAsStream("jdbc.properties");
ResourceBundle类
package com.ww.jdbc_demo_01.util;
import java.sql.*;
import java.util.ResourceBundle;
public class JdbcUtils {
//1、读取配置文件里面的属性值
//1-1、声明读取的属性值要赋值的变量
private static String driver;
private static String url;
private static String username;
private static String password;
//1-2、静态代码块,读取配置文件;加载驱动;
static{
//1、读取resources/jdbc.properties配置文件
ResourceBundle bundle = ResourceBundle.getBundle("jdbc");
driver=bundle.getString("driver");
url=bundle.getString("url");
username= bundle.getString("username");
password=bundle.getString("password");
try {
Class.forName(driver);
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
}
//2、获取连接
public static Connection getConnection(){
Connection connection= null;
try {
connection = DriverManager.getConnection(url,username,password);
} catch (SQLException e) {
throw new RuntimeException(e);
}
return connection;
//3、释放资源
public static void closeAll(ResultSet resultSet, Statement statement, Connection connection){
try {
if(resultSet!=null){
resultSet.close();
}
if(statement!=null){
statement.close();
}
if(connection!=null){
connection.close();
}
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}
2、连接池
2.1、连接池概述
2.1.1、为什么要去使用连接池
存放多个连接的容器。
我会频繁的使用连接,一个连接从创建到销毁都会消耗我们的资源。
同时创建多个连接,存入集合,使用获取集合中没有被使用的连接,使用完后就将连接归还给集合。
2.1.2、连接池原理
如果连接池中基础连接被获取完了,要么等待3S,看是否有连接归还;如果没有就只能新建连接。
自定义连接池,使用的是LinkedList集合来存放我们的连接。
3、自定义连接池
创建类,连接池类(MyDataSource.java)
定义一个集合对象(LinkedList.java)
初始化连接,5个、10个
获取连接
归还连接
package com.ww.jdbc_demo_01.util;
import java.sql.Connection;
import java.util.LinkedList;
//1、新建连接池类
public class MyDataSource {
//2、创建连接池
private LinkedList<Connection> connectionPool=new LinkedList<Connection>();
//3、初实始化5个连接
public MyDataSource(){
for(int i=1;i<=5;i++){
//创建5个连接
Connection connection=JdbcUtils.getConnection();
connectionPool.add(connection);
}
}
//4、获取连接,还有初始化好的连接就获取,没有子就创建新的连接
public Connection getConnection(){
Connection connection=null;
if(connectionPool.size()>0){
connection =connectionPool.removeFirst();
}else{
connection=JdbcUtils.getConnection();
}
return connection;
}
//5、归还连接,就是将使用完的连接,在次存入到我们的连接池对象
public void addBack(Connection connection){
connectionPool.addLast(connection);
}
}
连接池使用
@Test
public void selectAllUser() throws SQLException {
//1、查询所有SQL语句
String sql="select * from user";
//2、获取连接
MyDataSource myDataSource=new MyDataSource();//new 时已经初始化有5个连接
Connection connection=myDataSource.getConnection();//获取连接
//3、创建PreparedStatement对象
PreparedStatement preparedStatement=connection.prepareStatement(sql);
//4、替换替换符(无参数)
//5、执行SQL,拿到结果集
ResultSet resultSet=preparedStatement.executeQuery();
//6、取出结果集,存入到实体类;实体类存入到集合
List<User> list=new ArrayList<User>();
while(resultSet.next()){
User user=new User();
user.setId(resultSet.getInt("id"));
user.setUsername(resultSet.getString("username"));
user.setPassword(resultSet.getString("password"));
user.setNickname(resultSet.getString("nickname"));
list.add(user);
}
//7、释放资源,归还连接给连接池
JdbcUtils.closeAll(resultSet,preparedStatement,null);
myDataSource.addBack(connection);
//8、集合处理,(1)返回return (2)打印输出了
for(User user:list){
System.out.println(user.toString());
}
}