定义:帮助MYSQL高效获取数据的数据结构
----------主键索引----------primary key [有唯一标识]
----------唯一索引----------unique key [避免重复的列出现,值可重复]
----------常规索引----------index/key [默认的,用index、key来设置]
----------全文索引----------fulltext [特定数据库引擎下才有,快速定位数据]
在创建表的时候,索引都是放在建表语句最下面
SHOW INDEX FROM TableName
已有表,增加索引:
alter table school.tablename
ADD fulltext index indexname
(studentname
)
索引原则
索引不是越多越好
不要对经常变动的数据加数据
小数据量不需要加索引
索引一般加在常用查询的字段
索引的数据结构
https://blog.codinglabs.org/articles/theory-of-mysql-index.html
mysql.user表
修改密码:
当前:set PASSWORD = PASSWORD(‘123456’);
选择: set FOR wangzheng = PASSWORD(‘123456’);
数据库备份
备份方式:
一)、拷贝物理文件:data文件夹导出
二)、可视化工具中,手动导出
三)、mysqldump命令行导出:
mysqldump -hlocalhost -uroot -p123456 school student >D:/a.sql
navicat怎么把建表语句、数据插入语句全部导出
--------------------------- 转储SQL文件+结构与数据 -------------------------
三大范式:[信息重复、更新异常、插入异常、删除异常]
每一列都不可分
满足不可分的前提下,每张表只描述一个事情
每一列与主键直接相关,不能间接相关
JAVA操作数据库的规范
java.sql
javax.sql
导入数据库驱动
第一个JDBC
导入驱动
增加lib
add as a library
package com.wang.lesson01;
import javax.sql.StatementEvent;
import java.sql.*;
public class JDBCFirstDemo {
public static void main(String[] args) throws ClassNotFoundException, SQLException {
//加载驱动,固定语法
Class.forName("com.mysql.jdbc.Driver");
//用户信息和URL
String url = "jdbc:mysql://localhost:3306/jdbcstudy?useUnicode=true&characterEncoding=utf8&useSSL=false";
//这里要注意:userSLL如果用的true,系统会报错
String username = "root";
String password = "123456";
//连接成功,数据库对象
Connection connection = DriverManager.getConnection(url,username,password);
//创建执行SQL的对象
Statement statement = connection.createStatement();
//执行SQL的对象去执行SQL,可能存在结果
String sql = "select * from users ;";
ResultSet resultSet = statement.executeQuery(sql);//封装了全部的
while(resultSet.next()){
System.out.println("id="+resultSet.getObject("id"));
System.out.println("NAME="+resultSet.getObject("NAME"));
System.out.println("PASSWORD="+resultSet.getObject("PASSWORD"));
System.out.println("email="+resultSet.getObject("email"));
System.out.println("birth="+resultSet.getObject("birthday"));
System.out.println("=======================================");
}
//释放连接
resultSet.close();
statement.close();
connection.close();
}
}
connection代表了数据库对象
数据库自动自动提交
事务提交/回滚。这些功能都可以通过connection.commit/rollback等直接实现
statement就是执行sql对象的类
PrapareStatement也是执行sql对象的类
Statement statement = connection.createStatement();
statement.executeQuery("");
statement.execute("");
statement.executeUpdate("");
ResultSet就是封装了查询结果
resultSet.getObject(""); //如果不知道查询结果是何种类型的情况下使用
resultSet.getString(""); //知道返回结果的情况下使用
resultSet.getInt("");
resultSet.getDate("");
遍历,next()
工具类代码:
public class JdbcUtils {
private static String driver = null;
private static String url = null;
private static String username = null;
private static String password = null;
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 (Exception e) {
e.printStackTrace();
}
}
//获取连接
public static Connection getConnect() throws SQLException {
return DriverManager.getConnection(url,username,password);
}
//释放连接资源
public static void release(Connection connection, Statement statement, ResultSet resultSet){
if(resultSet!=null){
try {
resultSet.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(connection!=null){
try {
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(statement!=null){
try {
statement.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
db.properties
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/jdbcstudy?useUnicode=true&characterEncoding=utf8&useSSL=false
username=root
password=******
测试类
public class TestUtils {
public static void main(String[] args) {
Connection connection = null ;
Statement statement = null ;
ResultSet resultSet = null ;
try {
connection = JdbcUtils.getConnect();
statement = connection.createStatement();
String sql = "insert into users (`id`,`NAME`,`PASSWORD`,email,birthday) values (5,'梁志斌','20030707','[email protected]','2020-08-02');";
int i = statement.executeUpdate(sql);
if (i>0){
System.out.println("插入成功");
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
//关闭连接
JdbcUtils.release(connection,statement,resultSet);
}
}
}
SQL注入的问题:
以用户登录为例:在username和password进行适当的SQL语句分析,试图改变原本SQL逻辑,以’or 1=1’等方式强制使SQL执行并返回结果得以实现后续登录效果等
PreparedStatement对象
可以防止SQL注入,并且效率更高
public class TestDemo {
public static void main(String[] args) {
Connection connection = null;
PreparedStatement preparedStatement = null ;
ResultSet resultSet = null ;
try {
connection = JdbcUtils.getConnect();
//使用问号占位符
String sql = "insert into users (`id`,`NAME`,`PASSWORD`,email,birthday) values (?,?,?,?,?);";
preparedStatement = connection.prepareStatement(sql);//预编译sql,不执行
//手动给占位符赋值
preparedStatement.setInt(1,6);
preparedStatement.setString(2,"卢崛");
preparedStatement.setString(3,"123321");
preparedStatement.setString(4,"[email protected]");
System.out.println((new Date().getTime())/2+"--------------------------");
System.out.println(new Date().UTC(2019,12,5,12,1,3));
preparedStatement.setDate(5,new java.sql.Date(new Date().getTime()));
int i = 0;
i = preparedStatement.executeUpdate();
if (i>0){
System.out.println("preparedstatement应用成功,数据已插入");
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
JdbcUtils.release(connection,preparedStatement,resultSet);
}
}
}
修改mysql的时区,记得flush privileges;否则不会生效
进入后,记得在Schemas中修改一下所查看的表,这样才能看到具体的业务表
后续加紧使用联系
原子、一致、隔离、持久
脏读、不可重复读、虚读(幻读)
public class TestTransFormation {
public static void main(String[] args) {
Connection connection = null ;
PreparedStatement preparedStatement = null ;
ResultSet resultSet = null ;
try {
connection = JdbcUtils.getConnect();
//关闭MYSQL自动提交,意味着事务的开始第一步
connection.setAutoCommit(false);
//这里我没有建表,所以SQL暂时不执行了
String sql1 = "" ;
preparedStatement = connection.prepareStatement(sql1);
String sql2 = "" ;
preparedStatement = connection.prepareStatement(sql2);
connection.commit();
//这里注意,当使用了commit命令提交事务之后,数据库会自己恢复到自动提交的状态,不用刻意去开启自动提交了,同理回滚也是
} catch (SQLException e) {
try {
//如果失败就回滚事务,其实这里不写也可以,事务中出现异常会自动回滚
connection.rollback();
} catch (SQLException ex) {
ex.printStackTrace();
}
e.printStackTrace();
} finally {
//关闭JDBC各连接,防止占用内存
JdbcUtils.release(connection,preparedStatement,resultSet);
}
}
}
创建连接–使用–释放十分浪费内存资源,因此提前准备好一些连接,需要使用时直接取用
实现类:DataSource
工具类TestUtiles:
public class JdbcUtils_DBCP {
private static DataSource dataSource= null ;
static {
try{
InputStream in = JdbcUtils_DBCP.class.getClassLoader().getResourceAsStream("dbcpconfig.properties");
Properties properties = new Properties();
properties.load(in);
//创建数据源
dataSource = BasicDataSourceFactory.createDataSource(properties);
} catch (Exception e) {
e.printStackTrace();
}
}
//获取连接
public static Connection getConnect() throws SQLException {
return dataSource.getConnection(); //从数据源中获取连接
}
//释放连接资源
public static void release(Connection connection, Statement statement, ResultSet resultSet){
if(resultSet!=null){
try {
resultSet.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(connection!=null){
try {
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(statement!=null){
try {
statement.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
实现类:
public class TestUtils {
public static void main(String[] args) {
Connection connection = null ;
Statement statement = null ;
ResultSet resultSet = null ;
try {
connection = JdbcUtils_DBCP.getConnect();
statement = connection.createStatement();
String sql = "insert into users (`id`,`NAME`,`PASSWORD`,email,birthday) values (5,'梁志斌','20030707','[email protected]','2020-08-02');";
int i = statement.executeUpdate(sql);
if (i>0){
System.out.println("插入成功");
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
//关闭连接
JdbcUtils_DBCP.release(connection,statement,resultSet);
}
}
}
=====区别只在于数据库连接方式的不同=