权限管理和备份
- 用户管理
-- 创建用户
create user zhangsan identified by '123';
-- 修改当前用户密码
set password = password('123456');
-- 修改指定用户密码
set password for zhangsan = password('123');
-- 重命名用户
rename user zhangsan to lisi;
-- 用户授权 all privileges
grant all privileges on *.* to zhangsan; -- 无grant option权限
-- 查询权限
show grants for zhangsan;
show grants for root@localhost;
-- 撤销权限
revoke all privileges on *.* from zhangsan ;
-- 删除用户
drop user zhangsan;
备份
- 保证重要数据不丢失
- 数据转移
1.直接拷贝物理文件 data
2. 命令行导出 mysqldump
-- mysqldump -h 主机名 -u 用户名 -p 密码 数据库 表名 > 物理磁盘位置/文件名.sql
mysqldump -hlocalhost -uroot -p123456 school test test2 > D:/a.sql
-- 还原
-- 登入数据库后
source D:/a.sql;
规范数据库设计
-
糟糕的数据库设计:
- 数据冗余 浪费空间
- 数据库插入和删除都会麻烦 [屏蔽使用物理外键]
- 程序的性能差
-
良好的数据库设计:
- 节省内存空间
- 保证数据库的完整性
- 方便开发系统
-
标识实体(把需求落地到每个字段)
-
标识实体之间的关系
三大范式
- 第一范式(1NF) : 原子性 保证每一列不可再分
- 第二范式(2NF): 每张表只描述一件事
- 第三范式(3NF): 确保数据表中的每一列数据都和主键直接相关 而不能间接相关
- 规范性 和性能 : 关联查询的表不得超过三张表
- 考虑商业化的需求和目标(成本 用户体验) 数据库的性能更加重要
- 在规范性能问题的时候 适当考虑一下 规范性
- 故意给某些表增加一些冗余字段 (从多表查询变单边查询)
- 故意增加一些计算列(从大数据量降低为小数据量的查询: 索引)
JDBC
- 数据库驱动
Sun公司为了简化 开发人员的(对数据库的统一)操作 提供了一个(java操作数据库的)规范 俗称 JDBC 这些规范的实现由具体的厂商去做
对于开发人员 只需掌握JDBC 接口的操作即可
应用程序 - > JDBC -> MYSQL驱动 -> 数据库
- 第一个JDBC程序
-- 创建测试数据库
CREATE DATABASE jdbcStudy CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
DROP DATABASE jdbcStduy;
use jdbcstudy;
CREATE TABLE users(
id INT PRIMARY KEY,
`name` VARCHAR(40),
`password` VARCHAR(40),
email VARCHAR(60),
birthday date);
insert into users (`Id`,`name`,`password`,email,birthday)values
(1,'shansan','123456','zs@123.com','1980-12-04'),
(2,'zhangsan','abcde','zh@123.com','1989-11-24'),
(3,'lisi','123','li@123.com','1990-6-15');
- 导入数据库驱动
下载地址:https://downloads.mysql.com/archives/c-j/
在idea新建一个lib目录
将jar包拷贝进lib目录
右键lib目录 -> add as Library
- 编写测试代码
package com.wu.lesson01;
import java.sql.*;
public class jdbcDemon01 {
public static void main(String[] args) throws ClassNotFoundException, SQLException {
//加载驱动
Class.forName("com.mysql.jdbc.Driver");
//用户信息和url 注意我设置的mysql端口为3307 默认为3306
String url = "jdbc:mysql://localhost:3307/jdbcstudy?userUnicode=true&characterEncoding=utf8&useSSL=true";
String username = "root";
String password = "123456";
//连接成功 数据库对象 connection 代表数据库
Connection connection = DriverManager.getConnection(url, username, password);
//执行SQL对象 statement执行sql 对象
Statement statement = connection.createStatement();
// statement执行 sql
String sql = "select * from users";
ResultSet result = statement.executeQuery(sql); //返回结果集 结果封装了查询的全部结果
while(result.next()){
System.out.println("id: " + result.getObject("id"));
System.out.println("name: " + result.getObject("name"));
System.out.println("password: " + result.getObject("password"));
System.out.println("emai: l" + result.getObject("email"));
System.out.println("birthday: " + result.getObject("birthday"));
System.out.println("====================");
}
//释放连接
result.close();
statement.close();
connection.close();
}
}
//代码说明
//jdbc中的statement对象用于向数据库发送SQL语句 想完成对数据库的增删改查 只需通过这个对象向数据库发送增删改查语句即可 本质上就是数据库 可以创建事务
//statement对象executeUpdate方法 用于向数据库发送增 删 改的sql语句, executeUpdate执行完后 将会返回一个整数(即增删改语句导致了数据库几行数据发生了变化)
//CRUD操作- create
int num = statement.executeUpdate("insert itno user() values()");
if(num>0){
System.out.printIn("成功插入" + num + "条")
}
//CRUD操作- delete
int num = statement.executeUpdate("delete from user where id=1");
if( num >0 ){
System.out.printIm("成功删除" + num + "条");
}
//CURD操作- update
int num = statememt.exexuteUpdate("update user set name='zhaoliu' where id=3");
if(num >0){
System.out.printIn("成功更新" + num + "条");
}
//封装
// db.properties
driver = com.mysql.jdbc.Driver
url = jdbc:mysql://localhost:3307/jdbcstudy?userUnicode=true&characterEncoding=utf8&&useSSL=true
username = root
password =123456
//创建工具类
package com.wu.lesson02.utils;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.sql.*;
import java.util.Properties;
public class JdbcUtils {
public static String driver;
public static String url;
public static String username;
public static String password;
static {
try{
InputStream in = JdbcUtils.class.getClassLoader().getResourceAsStream("db.properties");
Properties properties = new Properties();
properties.load(in);
driver = properties.getProperty("driver");
url = properties.getProperty("url");
username = properties.getProperty("username");
password = properties.getProperty("password");
//加载驱动
Class.forName(driver);
}catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
//获取连接
public static Connection getConnection() throws SQLException {
return DriverManager.getConnection(url, username, password);
}
//释放资源
public static void release(Connection conn, Statement stat, ResultSet rst){
if( rst !=null){
try {
rst.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if(stat != null){
try {
stat.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if(conn != null){
try {
conn.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
}
//测试
package com.wu.lesson02.utils;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class TestInsert {
public static void main(String[] args) {
Connection connection =null;
Statement stat = null;
ResultSet rst=null;
try {
connection = JdbcUtils.getConnection();
stat = connection.createStatement();
// String sql ="insert into users values(4,'sunqi','abcde','sun@163.com','1992-09-12')";
// int i= stat.executeUpdate(sql);
// if(i >0){
// System.out.println("成功插入" + i + "条记录");
// }
String sql ="select * from users";
rst = stat.executeQuery(sql);
while (rst.next()){
System.out.println("id:" + rst.getInt("id"));
System.out.println("name:" + rst.getString("name"));
System.out.println("password:" + rst.getString("password"));
System.out.println("email:" + rst.getString("email"));
System.out.println("birthday:" + rst.getDate("birthday"));
System.out.println("==========");
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}finally {
JdbcUtils.release(connection,stat,rst);
}
}
}
SQL 注入
package com.wu.lesson02.utils;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class SqlInjection {
public static void main(String[] args) throws SQLException {
login("zhangsan","123");
}
public static void login(String username,String password) throws SQLException {
Connection connection = JdbcUtilesDemo01.getConnection();
Statement statement = connection.createStatement();
//注入关键 添加额外 or 语句
String sql = "select * from users where `name` = '" + username + "' or '1=1'";
ResultSet resultSet = statement.executeQuery(sql);
while (resultSet.next()){
System.out.println("id: " + resultSet.getInt("id"));
System.out.println("name: " + resultSet.getString("name"));
System.out.println("password:" + resultSet.getString("password"));
}
JdbcUtilesDemo01.release(connection,statement,resultSet);
}
}
预编译方法
package com.wu.lesson02.utils;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
public class PreText {
public static void main(String[] args) {
Connection connection =null;
PreparedStatement preparedStatement = null;
try {
connection = JdbcUtilesDemo01.getConnection();
//使用? 占位 本质上将参数变为字符串 忽略转义字符
String sql= " update users set `name`=? where id=?";
preparedStatement = connection.prepareStatement(sql);
preparedStatement.setString(1,"田七");
preparedStatement.setInt(2,3);
//执行
int i = preparedStatement.executeUpdate();
if(i > 0){
System.out.println("成功更新" + i + "条记录");
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}finally {
JdbcUtilesDemo01.release(connection,preparedStatement,null);
}
}
}