赞
踩
mysql-5.1.37和mysql-8.0.15数据库驱动包下载,如何导入IDEA往下看
今日源码
链接:https://pan.baidu.com/s/12ibAtAjbaRGFPuAcaA52Dg
提取码:n6ux
内连接: | 隐式、显式 |
---|---|
隐式: | 没有 join,使用 where |
显式: | inner join…on |
外连接: | 左连接和右连接 |
左连接: | left outer join … on |
右连接: | right outer join … on |
三种情况:
备份:mysqldump -u 用户名 -p 密码 数据库 > 文件名
还原:
登录使用数据库
use 数据库
source 文件名
事务四个特性 ACID:原子性、一致性、隔离性、持久性
在 mysql 中有三条语句:
使用第三方客户端来访问MySQL:SQLyog、Navicat、SQLWave、MyDB Studio、EMS SQL Manager for MySQL
使用 MySQL 自带的命令行方式
通过 Java 来访问 MySQL 数据库,今天要学习的内容
JDBC 规范定义接口,具体的实现由各大数据库厂商来实现。
JDBC 是 Java 访问数据库的标准规范,真正怎么操作数据库还需要具体的实现类,也就是数据库驱动。每个数据库厂商根据自家数据库的通信格式编写好自己数据库的驱动。所以我们只需要会调用 JDBC 接口中的方法即可,数据库驱动由数据库厂商提供。
会使用到的包 | 说明 |
---|---|
java.sql | 所有与 JDBC 访问数据库相关的接口和类 |
javax.sql | 数据库扩展包,提供数据库额外的功能。如:连接池 |
数据库的驱动 | 由各大数据库厂商提供,需要额外去下载,是对 JDBC 接口实现的类 |
接口或类 | 作用 |
---|---|
DriverManager 类 | 1) 管理和注册数据库驱动2) 得到数据库连接对象 |
Connection 接口 | 一个连接对象,可用于创建 Statement 和 PreparedStatement 对象 |
Statement 接口 | 一个 SQL 语句对象,用于将 SQL 语句发送给数据库服务器。 |
PreparedStatemen | 接口 一个 SQL 语句对象,是 Statement 的子接口 |
ResultSet 接口 | 用于封装数据库查询的结果集,返回给客户端 Java 程序 |
加载和注册驱动的方法 | 描述 |
---|---|
Class.forName(数据库驱动实现类) | 加载和注册数据库驱动,数据库驱动由 mysql 厂商"com.mysql.jdbc.Driver" |
public class Demo1 {
public static void main(String[] args) throws ClassNotFoundException {
//抛出类找不到的异常,注册数据库驱动
Class.forName("com.mysql.jdbc.Driver");
}
}
// Driver 接口,所有数据库厂商必须实现的接口,表示这是一个驱动类。
public class Driver implements java.sql.Driver {
public Driver() throws SQLException {
}
static {
try {
DriverManager.registerDriver(new Driver()); //注册数据库驱动
} catch (SQLException var1) {
throw new RuntimeException("Can't register driver!");
}
}
}
DriverManager 类中的静态方法 | 描述 |
---|---|
Connection getConnection (String url, String user, String password) | 通过连接字符串,用户名,密码来得到数据库的连接对象 |
Connection getConnection (String url, Properties info) | 通过连接字符串,属性对象来得到连接对象 |
JDBC 连接数据库的四个参数 | 说明 |
---|---|
用户名 | 登录的用户名 |
密码 | 登录的密码 |
连接字符串 URL | 不同的数据库 URL 是不同的,mysql 的写法jdbc:mysql://localhost:3306/数据库[?参数名=参数值] |
驱动类的字符串名 | com.mysql.jdbc.Driver |
**协议名:子协议://服务器名或 IP 地址:端口号/数
前提:必须是本地服务器,端口号是 3306
jdbc:mysql:///数据库名
如果数据库出现乱码,可以指定参数:?characterEncoding=utf8,表示让数据库以 UTF-8 编码来处理数据。
jdbc:mysql://localhost:3306/数据库?characterEncoding=utf8
package com.itheima; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; /** * 得到连接对象 */ public class Demo2 { public static void main(String[] args) throws SQLException { String url = "jdbc:mysql://localhost:3306/day24"; //1) 使用用户名、密码、URL 得到连接对象 Connection connection = DriverManager.getConnection(url, "root", "root"); //com.mysql.jdbc.JDBC4Connection@68de145 System.out.println(connection); } }
package com.itheima; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import java.util.Properties; public class Demo3 { public static void main(String[] args) throws SQLException { //url 连接字符串 String url = "jdbc:mysql://localhost:3306/day24"; //属性对象 Properties info = new Properties(); //把用户名和密码放在 info 对象中 info.setProperty("user","root"); info.setProperty("password","root"); Connection connection = DriverManager.getConnection(url, info); //com.mysql.jdbc.JDBC4Connection@68de145 System.out.println(connection); } }
Connection 接口,具体的实现类由数据库的厂商实现,代表一个连接对象。
Connection 接口中的方法 | 描述 |
---|---|
Statement createStatement() | 创建一条 SQL 语句对象 |
代表一条语句对象,用于发送 SQL 语句给服务器,用于执行静态 SQL 语句并返回它所生成结果的对象。
Statement 接口中的方法 | 描述 |
---|---|
int executeUpdate(String sql) | 用于发送 DML 语句,增删改的操作,insert、update、delete。 参数:SQL 语句 。返回值:返回对数据库影响的行数。 |
ResultSet executeQuery(String sql) | 用于发送 DQL 语句,执行查询的操作。select。 参数:SQL 语句 。返回值:查询的结果集。 |
package com.itheima; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import java.sql.Statement; /** * 创建一张学生表 */ public class Demo4DDL { public static void main(String[] args) { //1. 创建连接 Connection conn = null; Statement statement = null; try { conn = DriverManager.getConnection("jdbc:mysql:///day24", "root", "root"); //2. 通过连接对象得到语句对象 statement = conn.createStatement(); //3. 通过语句对象发送 SQL 语句给服务器 //4. 执行 SQL statement.executeUpdate("create table student (id int PRIMARY key auto_increment, " + "name varchar(20) not null, gender boolean, birthday date)"); //5. 返回影响行数(DDL 没有返回值) System.out.println("创建表成功"); } catch (SQLException e) { e.printStackTrace(); } //6. 释放资源 finally { //关闭之前要先判断 if (statement != null) { try { statement.close(); } catch (SQLException e) { e.printStackTrace(); } } if (conn != null) { try { conn.close(); } catch (SQLException e) { e.printStackTrace(); } } } } }
package com.itheima; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import java.sql.Statement; /** * 向学生表中添加 4 条记录,主键是自动增长 */ public class Demo5DML { public static void main(String[] args) throws SQLException { // 1) 创建连接对象 Connection connection = DriverManager.getConnection("jdbc:mysql:///day24", "root", "root"); // 2) 创建 Statement 语句对象 Statement statement = connection.createStatement(); // 3) 执行 SQL 语句:executeUpdate(sql) int count = 0; // 4) 返回影响的行数 count += statement.executeUpdate("insert into student values(null, '孙悟空', 1, '1993-03- 24')"); count += statement.executeUpdate("insert into student values(null, '白骨精', 0, '1995-03- 24')"); count += statement.executeUpdate("insert into student values(null, '猪八戒', 1, '1903-03- 24')"); count += statement.executeUpdate("insert into student values(null, '嫦娥', 0, '1993-03- 11')"); System.out.println("插入了" + count + "条记录"); // 5) 释放资源 statement.close(); connection.close(); } }
ResultSet 接口中的方法 | 描述 |
---|---|
boolean next() | 1) 游标向下移动 1 行 2) 返回 boolean 类型,如果还有下一条记录,返回 true,否则返回 false |
数据类型 getXxx() | 1) 通过字段名,参数是 String 类型。返回不同的类型 2) 通过列号,参数是整数,从 1 开始。返回不同的类型 |
SQL 类型 | Jdbc 对应方法 | 返回类型 |
---|---|---|
BIT(1) bit(n) | getBoolean() | boolean |
TINYINT | getByte() | byte |
SMALLINT | getShort() | short |
INT | getInt() | nt |
BIGINT | getLong() | long |
CHAR,VARCHAR | getString() | String |
Text(Clob) Blob | getClob getBlob() | Clob Blob |
DATE | getDate() | java.sql.Date 只代表日期 |
TIME | getTime() | java.sql.Time 只表示时间 |
TIMESTAMP | getTimestamp() | java.sql.Timestamp 同时有日期和时间 |
package com.itheima; import java.sql.*; /** * 查询所有的学生信息 */ public class Demo6DQL { public static void main(String[] args) throws SQLException { //1) 得到连接对象 Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/day24","root","root"); //2) 得到语句对象 Statement statement = connection.createStatement(); //3) 执行 SQL 语句得到结果集 ResultSet 对象 ResultSet rs = statement.executeQuery("select * from student"); //4) 循环遍历取出每一条记录 while(rs.next()) { int id = rs.getInt("id"); String name = rs.getString("name"); boolean gender = rs.getBoolean("gender"); Date birthday = rs.getDate("birthday"); //5) 输出的控制台上 System.out.println("编号:" + id + ", 姓名:" + name + ", 性别:" + gender + ", 生日:" + birthday); } //6) 释放资源 rs.close(); statement.close(); connection.close(); } }
上面写的代码中出现了很多重复的代码,可以把这些公共代码抽取出来。
7.2 创建类 JdbcUtil 包含 3 个方法:
package com.itheima.utils; import java.sql.*; /** * 访问数据库的工具类 */ public class JdbcUtils { //可以把几个字符串定义成常量:用户名,密码,URL,驱动类 private static final String USER = "root"; private static final String PWD = "root"; private static final String URL = "jdbc:mysql://localhost:3306/day24"; private static final String DRIVER= "com.mysql.jdbc.Driver"; /** * 注册驱动 */ static { try { Class.forName(DRIVER); } catch (ClassNotFoundException e) { e.printStackTrace(); } } /** * 得到数据库的连接 */ public static Connection getConnection() throws SQLException { return DriverManager.getConnection(URL,USER,PWD); } /** * 关闭所有打开的资源 */ public static void close(Connection conn, Statement stmt) { if (stmt!=null) { try { stmt.close(); } catch (SQLException e) { e.printStackTrace(); } } if (conn!=null) { try { conn.close(); } catch (SQLException e) { e.printStackTrace(); } } } /** * 关闭所有打开的资源 */ public static void close(Connection conn, Statement stmt, ResultSet rs) { if (rs!=null) { try { rs.close(); } catch (SQLException e) { e.printStackTrace(); } } close(conn, stmt); } }
create table user (
id int primary key auto_increment,
name varchar(20),
password varchar(20)
)
insert into user values (null,'jack','123'),(null,'rose','456');
-- 登录, SQL 中大小写不敏感
select * from user where name='JACK' and password='123';
-- 登录失败
select * from user where name='JACK' and password='333';
package com.itheima; import com.itheima.utils.JdbcUtils; import javax.xml.transform.Result; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.Scanner; public class Demo7Login { //从控制台上输入的用户名和密码 public static void main(String[] args) { Scanner sc = new Scanner(System.in); System.out.println("请输入用户名:"); String name = sc.nextLine(); System.out.println("请输入密码:"); String password = sc.nextLine(); login(name, password); } /** * 登录的方法 */ public static void login(String name, String password) { //a) 通过工具类得到连接 Connection connection = null; Statement statement = null; ResultSet rs = null; try { connection = JdbcUtils.getConnection(); //b) 创建语句对象,使用拼接字符串的方式生成 SQL 语句 statement = connection.createStatement(); //c) 查询数据库,如果有记录则表示登录成功,否则登录失败 String sql = "select * from user where name='" + name + "' and password='" + password + "'"; System.out.println(sql); rs = statement.executeQuery(sql); if (rs.next()) { System.out.println("登录成功,欢迎您:" + name); } else { System.out.println("登录失败"); } } catch (SQLException e) { e.printStackTrace(); } finally { //d) 释放资源 JdbcUtils.close(connection, statement, rs); } } }
请输入用户名:
newboy
请输入密码:
a' or '1'='1
select * from user where name='newboy' and password='a' or '1'='1'
登录成功,欢迎您:newboy
select * from user where name='newboy' and password='a' or '1'='1'
name='newboy' and password='a' 为假
'1'='1' 真
相当于
select * from user where true; 查询了所有记录
我们让用户输入的密码和 SQL 语句进行字符串拼接。用户输入的内容作为了 SQL 语句语法的一部分,改变了原有 SQL 真正的意义,以上问题称为 SQL 注入。要解决 SQL 注入就不能让用户输入的密码和我们的 SQL 语句进行简单的字符串拼接。
PreparedStatement 是 Statement 接口的子接口,继承于父接口中所有的方法。它是一个预编译的 SQL 语句
Connection 接口中的方法 | 描述 |
---|---|
PreparedStatement prepareStatement(String sql) | 指定预编译的 SQL 语句,SQL 语句中使用占位符 ? 创建一个语句对象 |
PreparedStatement 接口中的方法 | 描述 |
---|---|
int executeUpdate() | 执行 DML,增删改的操作,返回影响的行数。 |
ResultSet executeQuery() | 执行 DQL,查询的操作,返回结果集 |
PreparedStatement 中设置参数的方法 | 描述 |
---|---|
void setDouble(int parameterIndex, double x) | 将指定参数设置为给定 Java double 值。 |
void setFloat(int parameterIndex, float x) | 将指定参数设置为给定 Java REAL 值。 |
void setInt(int parameterIndex, int x) | 将指定参数设置为给定 Java int 值。 |
void setLong(int parameterIndex, long x) | 将指定参数设置为给定 Java long 值。 |
void setObject(int parameterIndex, Object x) | 使用给定对象设置指定参数的值。 |
void setString(int parameterIndex, String x) | 将指定参数设置为给定 Java String 值。 |
package com.itheima; import com.itheima.utils.JdbcUtils; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.Scanner; /** * 使用 PreparedStatement */ public class Demo8Login { //从控制台上输入的用户名和密码 public static void main(String[] args) throws SQLException { Scanner sc = new Scanner(System.in); System.out.println("请输入用户名:"); String name = sc.nextLine(); System.out.println("请输入密码:"); String password = sc.nextLine(); login(name, password); } /** * 登录的方法 * @param name * @param password */ private static void login(String name, String password) throws SQLException { Connection connection = JdbcUtils.getConnection(); //写成登录 SQL 语句,没有单引号 String sql = "select * from user where name=? and password=?"; //得到语句对象 PreparedStatement ps = connection.prepareStatement(sql); //设置参数 ps.setString(1, name); ps.setString(2,password); ResultSet resultSet = ps.executeQuery(); if (resultSet.next()) { System.out.println("登录成功:" + name); } else { System.out.println("登录失败"); } //释放资源,子接口直接给父接口 JdbcUtils.close(connection,ps,resultSet); } }
package com.itheima; import com.itheima.entity.Student; import com.itheima.utils.JdbcUtils; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; public class Demo9Student { public static void main(String[] args) throws SQLException { //创建学生对象 Student student = new Student(); Connection connection = JdbcUtils.getConnection(); PreparedStatement ps = connection.prepareStatement("select * from student where id=?"); //设置参数 ps.setInt(1,2); ResultSet resultSet = ps.executeQuery(); if (resultSet.next()) { //封装成一个学生对象 student.setId(resultSet.getInt("id")); student.setName(resultSet.getString("name")); student.setGender(resultSet.getBoolean("gender")); student.setBirthday(resultSet.getDate("birthday")); } //释放资源 JdbcUtils.close(connection,ps,resultSet); //可以数据 System.out.println(student); } }
package com.itheima; import com.itheima.entity.Student; import com.itheima.utils.JdbcUtils; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; public class Demo10List { public static void main(String[] args) throws SQLException { //创建一个集合 List<Student> students = new ArrayList<>(); Connection connection = JdbcUtils.getConnection(); PreparedStatement ps = connection.prepareStatement("select * from student"); //没有参数替换 ResultSet resultSet = ps.executeQuery(); while(resultSet.next()) { //每次循环是一个学生对象 Student student = new Student(); //封装成一个学生对象 student.setId(resultSet.getInt("id")); student.setName(resultSet.getString("name")); student.setGender(resultSet.getBoolean("gender")); student.setBirthday(resultSet.getDate("birthday")); //把数据放到集合中 students.add(student); } //关闭连接 JdbcUtils.close(connection,ps,resultSet); //使用数据 for (Student stu: students) { System.out.println(stu); } } }
package com.itheima; import com.itheima.utils.JdbcUtils; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; public class Demo11DML { public static void main(String[] args) throws SQLException { //insert(); //update(); delete(); } //插入记录 private static void insert() throws SQLException { Connection connection = JdbcUtils.getConnection(); PreparedStatement ps = connection.prepareStatement("insert into student values(null,?,?,?)"); ps.setString(1,"小白龙"); ps.setBoolean(2, true); ps.setDate(3,java.sql.Date.valueOf("1999-11-11")); int row = ps.executeUpdate(); System.out.println("插入了" + row + "条记录"); JdbcUtils.close(connection,ps); } //更新记录: 换名字和生日 private static void update() throws SQLException { Connection connection = JdbcUtils.getConnection(); PreparedStatement ps = connection.prepareStatement("update student set name=?, birthday=? where id=?"); ps.setString(1,"黑熊怪"); ps.setDate(2,java.sql.Date.valueOf("1999-03-23")); ps.setInt(3,5); int row = ps.executeUpdate(); System.out.println("更新" + row + "条记录"); JdbcUtils.close(connection,ps); } //删除记录: 删除第 5 条记录 private static void delete() throws SQLException { Connection connection = JdbcUtils.getConnection(); PreparedStatement ps = connection.prepareStatement("delete from student where id=?"); ps.setInt(1,5); int row = ps.executeUpdate(); System.out.println("删除了" + row + "条记录"); JdbcUtils.close(connection,ps); } }
之前我们是使用 MySQL 的命令来操作事务。接下来我们使用 JDBC 来操作银行转账的事务。
CREATE TABLE account (
id INT PRIMARY KEY AUTO_INCREMENT,
NAME VARCHAR(10),
balance DOUBLE
);
-- 添加数据
INSERT INTO account (NAME, balance) VALUES ('Jack', 1000), ('Rose', 1000);
Connection 接口中与事务有关的方法 | 说明 |
---|---|
void setAutoCommit(boolean autoCommit) | 参数是 true 或 false 如果设置为 false,表示关闭自动提交,相当于开启事务 |
void commit() | 提交事务 |
void rollback() | 回滚事务 |
package com.itheima; import com.itheima.utils.JdbcUtils; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; public class Demo12Transaction { //没有异常,提交事务,出现异常回滚事务 public static void main(String[] args) { //1) 注册驱动 Connection connection = null; PreparedStatement ps = null; try { //2) 获取连接 connection = JdbcUtils.getConnection(); //3) 开启事务 connection.setAutoCommit(false); //4) 获取到 PreparedStatement //从 jack 扣钱 ps = connection.prepareStatement("update account set balance = balance - ? where name=?"); ps.setInt(1, 500); ps.setString(2,"Jack"); ps.executeUpdate(); //出现异常 System.out.println(100 / 0); //给 rose 加钱 ps = connection.prepareStatement("update account set balance = balance + ? where name=?"); ps.setInt(1, 500); ps.setString(2,"Rose"); ps.executeUpdate(); //提交事务 connection.commit(); System.out.println("转账成功"); } catch (Exception e) { e.printStackTrace(); try { //事务的回滚 connection.rollback(); } catch (SQLException e1) { e1.printStackTrace(); } System.out.println("转账失败"); } finally { //7) 关闭资源 JdbcUtils.close(connection,ps); } } }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。