隔离所导致的问题:
脏读:一个事务读取了另一个事务未提交的数据
不可重复读:多次读取同一条数据出现结果不同
虚读:指一个事务读取到别的事务插入的数据,导致前后读取结果不一致
-- 创建一个数据库
CREATE DATABASE if NOT EXISTS shop
use shop
-- 创建一个表
CREATE TABLE IF NOT EXISTS bank(
`id` INT(20) NOT NULL auto_increment,
`name` VARCHAR(30) NOT NULL,
`money` DECIMAL(9,2) NOT NULL,
PRIMARY KEY(`id`)
)ENGINE=INNODB DEFAULT CHARSET = utf8
-- 注入数据
INSERT bank VALUES(1,'A',5000),(2,'B',10000)
-- 关闭自动提交
SET autocommit = 0
-- 开启事务
START TRANSACTION
-- 转账
UPDATE bank SET money = money-500 WHERE id = 1
UPDATE bank SET money = money+500 WHERE id = 2
-- 提交事务
COMMIT
-- 失败则回滚
ROLLBACK
-- 恢复默认值
SET autocommit = 1
在表中,主键索引只能有一个,唯一索引可以有多个
-- 显示所有索引信息
SHOW INDEX FROM student
-- 增加一个全文索引
ALTER TABLE schooldemo.student ADD FULLTEXT studentName(`studentName`)
糟糕的数据库设计:
良好的数据库设计:
———— 为什么需要数据规范化?
———— 信息重复 更新异常 插入异常 删除异常
第一范式(1NF)
第二范式(2NF)
第三范式(3NF)
规范性 和 性能的问题
第一个JDBC代码——步骤:
- 加载驱动
- 用户信息和URL
- 连接数据库
- 获得执行sql语句的statement
- 执行sql语句,获得结果集 遍历
- 释放连接
import java.sql.*;
public class JDBCdemo01 {
public static void main(String[] args) throws ClassNotFoundException, SQLException {
// 1. 加载驱动(固定写法)
Class.forName("com.mysql.jdbc.Driver");
// 2. 用户信息和URL
/* useUnicode——支持中文编码 characterEncoding——设定中文字符集 useSSL——使用安全连接*/
//(固定写法)
String url = "jdbc:mysql://localhost:3306/jdbcstudy?useUnicode=true&characterEncoding=utf8&useSSL=true";
String username = "root";
String password = "zy123456";
// 3. 连接数据库
Connection connection = DriverManager.getConnection(url, username, password);
// 4. 获得执行sql的对象statement
Statement statement = connection.createStatement();
// 5. 执行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("birthday = "+resultSet.getObject("birthday"));
System.out.println("=======================================");
}
// 6. 释放连接
resultSet.close();
statement.close();
connection.close();
}
}
- 创建配置文件——db.properties
driver =com.mysql.jdbc.Driver
url = jdbc:mysql://localhost:3306/jdbcstudy?useUnicode=true&characterEncoding=utf8&useSSL=true
username = root
password = ******
- 创建工具类——JDBCutils
import java.io.InputStream;
import java.sql.*;
import java.util.Properties;
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");
// 1. 加载驱动
Class.forName(driver);
} catch (Exception e) {
e.printStackTrace();
}
}
// 3. 获得connection连接
public static Connection getConnection() throws SQLException {
return DriverManager.getConnection(url,username,password);
}
// 6. 释放资源
public static void release(Connection con, Statement st, ResultSet re){
if(con != null){
try {
con.close();
}
catch (SQLException e) {
e.printStackTrace();
}
} if(st != null){
try {
st.close();
}
catch (SQLException e) {
e.printStackTrace();
}
} if(re != null){
try {
re.close();
}
catch (SQLException e) {
e.printStackTrace();
}
}
}
}
- 编写增删改查代码
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
public class insertDemo {
public static void main(String[] args) throws SQLException {
JDBCutils jdbCutils = new JDBCutils();
Connection con = JDBCutils.getConnection();
Statement st = con.createStatement();
String sql = " INSERT INTO users VALUES(4,'小花',123456,'[email protected]',null)";
int i = st.executeUpdate(sql);
if (i!=0){
System.out.println("插入成功!");
}
jdbCutils.release(con,st,null);
}
}
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
public class deleteDemo {
public static void main(String[] args) throws SQLException {
JDBCutils jdbCutils = new JDBCutils();
Connection con = jdbCutils.getConnection();
Statement st = con.createStatement();
String sql = "DELETE FROM users WHERE id = 4";
int i = st.executeUpdate(sql);
if (i!=0){
System.out.println("删除成功!");
}
jdbCutils.release(con,st,null);
}
}
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
public class updataDemo {
public static void main(String[] args) throws SQLException {
JDBCutils jdbCutils = new JDBCutils();
Connection con = jdbCutils.getConnection();
Statement st = con.createStatement();
String sql = "UPDATE users SET password = 666666 WHERE id = 4";
int i = st.executeUpdate(sql);
if (i!=0){
System.out.println("修改成功!");
}
jdbCutils.release(con,st,null);
}
}
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class selectDemo {
public static void main(String[] args) throws SQLException {
JDBCutils jdbCutils = new JDBCutils();
Connection con = jdbCutils.getConnection();
Statement st = con.createStatement();
String sql = "SELECT NAME FROM users";
ResultSet rs = st.executeQuery(sql);
while (rs.next()){
System.out.println(rs.getString("NAME"));
}
jdbCutils.release(con,st,rs);
}
}
为了防止sql注入的问题进行盗取信息,改用PreparedStatement 防止注入
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class sqlzhuri {
public static void main(String[] args) {
// login("kuangshen","123456"); 正常登录
login(" 'or '1=1"," 'or'1=1"); // sql注入问题
}
// 登录业务
public static void login(String username,String password){
Connection conn =null;
Statement st = null;
ResultSet rs = null;
try {
conn = JDBCutils.getConnection();
st = conn.createStatement();
// SELECT * FROM users WHERE `Name` = 'kuangshen' AND `password` = '123456';
// SELECT * FROM users WHERE `Name` = '' or '1=1' AND `password` = '' or '1=1';
String sql = "select * from users where `NAME`='"+username+"' AND `password` ='"+password+"'";
rs = st.executeQuery(sql); //查询完毕会返回一个结果集
while (rs.next()){
System.out.println(rs.getString("NAME"));
System.out.println(rs.getString("password"));
System.out.println("============================");
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
JDBCutils.release(conn,st,rs);
}
}
}
使用PreparedStatement——防止sql注入
package Demo03;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
public class insertDemo {
public static void main(String[] args) throws SQLException {
JDBCutils jdbCutils = new JDBCutils();
Connection con = jdbCutils.getConnection();
String sql = "insert into users(id,NAME,PASSWORD,email) values(?,?,?,?)";
PreparedStatement pst = con.prepareStatement(sql);
pst.setInt(1,5);
pst.setString(2,"小明");
pst.setInt(3,123456);
pst.setString(4,"[email protected]");
int i = pst.executeUpdate();
if (i!=0){
System.out.println("插入成功!");
}
jdbCutils.release(con,pst,null);
}
}
package Demo03;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
public class deleteDemo {
public static void main(String[] args) throws SQLException {
JDBCutils jdbCutils = new JDBCutils();
Connection con = jdbCutils.getConnection();
String sql = "DELETE FROM users WHERE id = ?";
PreparedStatement pst = con.prepareStatement(sql);
pst.setInt(1,5);
int i = pst.executeUpdate();
if (i!=0){
System.out.println("删除成功!");
}
jdbCutils.release(con,pst,null);
}
}
package Demo03;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
public class updataDemo {
public static void main(String[] args) throws SQLException {
JDBCutils jdbCutils = new JDBCutils();
Connection con = jdbCutils.getConnection();
String sql = "UPDATE users SET password = ? WHERE id = ?";
PreparedStatement pst = con.prepareStatement(sql);
pst.setInt(1,123456);
pst.setInt(2,4);
int i = pst.executeUpdate();
if (i!=0){
System.out.println("更新成功!");
}
jdbCutils.release(con,pst,null);
}
}
package Demo03;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class selectDemo {
public static void main(String[] args) throws SQLException {
JDBCutils jdbCutils = new JDBCutils();
Connection con = jdbCutils.getConnection();
String sql = "SELECT NAME FROM users";
PreparedStatement pst = con.prepareStatement(sql);
ResultSet rs = pst.executeQuery();
while (rs.next()){
System.out.println(rs.getString("NAME"));
}
jdbCutils.release(con,pst,rs);
}
}
package Demo03;
import java.sql.*;
public class SQLzhuru {
public static void main(String[] args) {
// login("kuangshen","123456"); 正常登录
login("'' or 1=1","123456"); // sql注入问题
}
// 登录业务
public static void login(String username,String password){
Connection conn =null;
PreparedStatement pst = null;
ResultSet rs = null;
try {
conn = JDBCutils.getConnection();
String sql = "select * from users where `NAME`=? and `PASSWORD`=?";
pst = conn.prepareStatement(sql);
pst.setString(1,username);
pst.setString(2,password);
// SELECT * FROM users WHERE `Name` = 'kuangshen' AND `password` = '123456';
// SELECT * FROM users WHERE `Name` = '' or '1=1' AND `password` = '' or '1=1';
rs = pst.executeQuery(); //查询完毕会返回一个结果集
while (rs.next()){
System.out.println(rs.getString("NAME"));
System.out.println(rs.getString("password"));
System.out.println("============================");
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
JDBCutils.release(conn,pst,rs);
}
}
}