一、引言
1.1 如何操作数据库
使用客户端工具访问数据库,需要手工建立连接,输入用户名和密码登录,编写 SQL 语句,点击执行,查看操作结果(结果集或受影响行数)。
客户端操作数据库步骤 |
---|
1.2 实际开发中,会采用客户端操作数据库吗?
在实际开发中,当用户的数据发生改变时,不可能通过客户端操作执行 SQL 语句,因为操作量过大,无法保证效率和正确性。
二、JDBC
2.1 什么是 JDBC?
JDBC(Java Database Connectivity) Java 连接数据库的规范(标准),可以使用 Java 语言连接数据库完成 CRUD 操作。
2.2 JDBC 核心思想
Java 中定义了访问数据库的接口,可以为多种关系型数据库提供统一的访问方式。由数据库厂商提供驱动实现类(Driver 数据库驱动)。
核心思想 |
---|
2.2.1 MySQL 数据库驱动
- mysql-connector-java-5.1.X 适用于 5.X 版本
- mysql-connector-java-8.0.X 适用于 8.X版本
2.3 环境搭建
- 在项目下新建 lib 文件夹,用于存放 jar 文件。
- 将 mysql 驱动mysql-connector-java-5.1.X复制到项目的 lib 文件夹中。
- 选中 lib 文件夹右键 Add as Libraay,点击 OK。
mysql厂商提供的jdbc规范的实现,要想完成JDBC操作,就需要将驱动包加入到当前项目中.
2.3.1 方式1:复制粘贴
在项目名下创建文件夹lib |
---|
命名为lib |
---|
将mysql驱动包复制粘贴到此处 |
---|
添加驱动包为当前项目的类库 |
---|
2.3.2 方式2:idea导入类库
打开项目结构(Project Structure) |
---|
选择libraries,添加jar包 |
---|
本地磁盘选择jar包 |
---|
成功 |
---|
三、JDBC编程
JDBC编程有标准步骤(八股文)
- 注册驱动
- 将sql语句的运行环境加载到JVM
- 连接数据库
- 获得执行SQL的对象
- 执行SQL语句,获得结果
- 关流
3.1 注册驱动
使用 Class.forName(“com.mysql.jdbc.Driver”);手动加载字节码文件到 JVM 中。
Class.forName("com.mysql.jdbc.Driver");//加载驱动
3.2 连接数据库
- 通过 DriverManager.getConnection(url,user,password) 获取数据库连接对象
- URL:jdbc:mysql://localhost:3306/database
- username:root
- password:1234
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/database?useUnicode=true&characterEncoding=utf8", "root","1234");
3.3 获取发送 SQL 的对象
通过 Connection 对象获得 Statement 对象,用于对数据库进行通用访问。
Statement statement = conn.createStatement();
3.4 执行SQL 语句
执行 SQL 语句并接收执行结果。
String sql ="INSERT INTO t_jobs(JOB_ID,JOB_TITLE,MIN_SALARY,MAX_SALARY) VALUES('JAVA_Le','JAVA_Lecturer',4000,10000);";
int result = statement.executeUpdate(sql);//执行SQL语句并接收结果
3.5 处理结果
接受处理操作结果。
if(result == 1){
System.out.println("Success");
}
3.6 释放资源
遵循先开后关原则,释放所使用到的资源对象。
statement.close();
conn.close();
3.7 案例
准备数据库表,进行CRUD.
create table tb_user(
id int(11) primary key auto_increment comment '用户编号',
username varchar(10) comment '用户名',
password varchar(10) comment '密码',
phone varchar(11) comment '手机号',
createTime date comment '注册时间',
money double(10,2) comment '账户余额',
sex int(1) comment '性别 1男2女'
);
需求: 使用JDBC完成对tb_user表插入数据
package com.qf.jdbc;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
/**
*
*/
public class Demo1_insert {
public static void main(String[] args) throws ClassNotFoundException, SQLException {
// 1 加载驱动
// ps: 利用反射技术,将驱动类加载到JVM
Class.forName("com.mysql.jdbc.Driver");
// 2 通过驱动管理对象获得连接对象
/**
* 参数1 url: 数据库连接的地址
* 协议://ip:端口/库名
* 参数2 username: 数据库用户名
* 参数3 password: 数据库密码
*/
String url = "jdbc:mysql://localhost:3306/java2217?useSSL=false&serverTimezone=UTC";
String username = "root";
String password = "123456";
Connection conn = DriverManager.getConnection(url,username,password);
// 3 通过连接对象,创建执行sql语句的对象
Statement statement = conn.createStatement();
// 4 通过执行语句对象,执行sql,获得结果
String sql = "insert into tb_user (id,username,password,phone,createTime,money,sex) values (2,'root','123456','1122200','2022-11-21',2000.0,2)";
// 执行查询,是executeQuery()
// 执行增删改,是executeUpdate(),返回受影响的行数
int num = statement.executeUpdate(sql);
if (num > 0) {
System.out.println("插入成功!!" );
}
// 5 关流
statement.close();
conn.close();
}
}
四、完成增删改
4.1 插入
参考入门案例
4.2 更新
任何的JDBC都是那5个步骤.
package com.qf.jdbc;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
/**
*/
public class Demo2_update {
public static void main(String[] args) throws Exception {
// 1 加载驱动
Class.forName("com.mysql.jdbc.Driver");
// 2 通过驱动管理对象获得连接对象
String url = "jdbc:mysql://localhost:3306/java2217?useSSL=false";
String username = "root";
String password = "123456";
Connection conn = DriverManager.getConnection(url, username, password);
// 3 通过连接对象创建执行语句对象
Statement statement = conn.createStatement( );
// 4 通过执行语句对象执行sql,获得结果
String sql = "update tb_user set username = '小孟', phone = '666666' where id = 3";
int num = statement.executeUpdate(sql);
if (num > 0) {
System.out.println("更新成功!" );
}
// 5 将对象的流关闭
statement.close();
conn.close();
}
}
4.3 删除
public class Demo3_delete {
public static void main(String[] args) throws Exception {
Class.forName("com.mysql.jdbc.Driver");
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/java2217?useSSL=false", "root", "123456");
Statement statement = conn.createStatement( );
int num = statement.executeUpdate("delete from tb_user where id = 3");
if (num > 0) {
System.out.println("删除成功!");
}
statement.close();
conn.close();
}
}
五、查询结果集ResultSet【重要】
查询返回的是一种虚拟表,Java的JDBC中是使用结果集(ResultSet)来封装这个虚拟表,结果集就是一个集合,内部就存储了列名和每行数据,那么学习查询的重点是
- 从结果集取值
package com.qf.jdbc;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
/**
public class Demo4_select {
public static void main(String[] args) throws Exception {
Class.forName("com.mysql.jdbc.Driver");
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/java2217?useSSL=false", "root", "123456");
Statement statement = conn.createStatement( );
String sql = "select id,username,password from tb_user";
// 执行查询的方法executeQuery,方法返回值是ResultSet
ResultSet rs = statement.executeQuery(sql);
/**
* ResultSet 内部包含了整个查询返回的虚拟表数据
* 内部提供了方法可以操作结果集
* boolean next(); 判断结果集有没有下一行数据,返回false,即没有下一行数据返回
* true就是有下一行数据,此时就可以进入取值
* getObject() 获得数据,返回值是Object
* getInt/getString/getDate() 获得数据,返回对应数据类型
* --------------------------------------
* getXxx(int columnIndex) 通过列下标获得对应Xxx数据类型的数据
* 下标从1开始,顺序是按照查询返回虚拟表顺序
* getXxx(String columnLabel) 通过列名获得对应Xxx数据类型的数据
* 根据虚拟表列名,如果有别名那就是别名
*/
while (rs.next()) {
// 通过列下标获得数据
// int id = rs.getInt(2);
// String username = rs.getString(1);
// 通过列名获得数据 【推荐】
int id = rs.getInt("id");
String username = rs.getString("username");
System.out.println(id + "-" + username);
}
statement.close();
conn.close();
}
}
六、登录案例【重要】
需求:
- 通过控制台用户输入用户名和密码。
- 用户输入的用户名和密码作为条件,编写查询 SQL 语句。
- select * from user where usename = xxx and password = xxx
- 如果该用户存在,提示登录成功,反之提示失败。
package com.qf.jdbc;
import com.mysql.jdbc.Driver;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Scanner;
/**
*
*/
public class Demo5_Login {
public static void main(String[] args) {
// 1 输入用户名和密码
Scanner scanner = new Scanner(System.in);
System.out.println("请输入用户名:" );
String username = scanner.nextLine( );
System.out.println("请输入密码:" );
String password = scanner.nextLine( );
// 2 根据用户名和密码查人
boolean isOk = findUserByLogin(username,password);
// 3 结果
if (isOk) {
System.out.println("登录成功!" );
} else {
System.out.println("用户名或密码错误!" );
}
}
// 使用捕获代码完成
private static boolean findUserByLogin(String username, String password) {
Connection conn = null;
Statement statement = null;
boolean isOk = false;
try {
Class.forName("com.mysql.jdbc.Driver");
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/java2217?useSSL=false", "root", "123456");
statement = conn.createStatement( );
// 根据用户名和密码查询,注意字符串拼接.特别注意单引号
ResultSet rs = statement.executeQuery("select * from tb_user where username = '"+username+"' and password = '"+password+"'");
// 只要有值,就说明数据库有这个信息,登录成功
if (rs.next()) {
// System.out.println("登录成功!" );
int id = rs.getInt("id");
String uname= rs.getString("username");
// ...
System.out.println(id+"-"+username);
isOk = true;
} else {
// System.out.println("用户名或密码错误!!" );
}
}catch (Exception e) {
System.out.println("SQL操作出错!" );
e.printStackTrace();// 打印异常
} finally {
try{
statement.close();
conn.close();
}catch (Exception e) {
System.out.println("关流异常" );
e.printStackTrace();// 打印异常
}
}
return isOk;
}
}
七、ORM【重要】
7.1 什么是ORM
目前使用JDBC完成了CRUD,但是现在是进行CRUD,增删改方法要设计很多参数,查询的方法需要设计集合才能返回.
在实际开发中,我们需要将零散的数据封装到对象处理.
ORM (Object Relational Mapping) 对象关系映射
是指
数据库表
与Java的实体类
有关系,可以进行映射
- 数据库表 --> Java的类
- tb_user —> User.java
- 字段 --> 类的属性
- id int --> private int id;
- username varchar --> private String username;
- …
- 一行数据 --> 类的对象
7.2 实体类
实体类: 数据表中零散数据的载体,用来封装数据.
- 表名 设计 类名
- 将列名设计成属性名
- id --> id
- create_time --> createTime (下划线转驼峰)
- 将列的数据类型设计成属性的数据类型
- 给类提供对应set get
一般项目中一个表就会对应一个实体类,所有的实体类都会放在model/entity/pojo/javabeen包结构中
将来写项目,数据库设计完,搭建完项目,第一件事件就是根据表结构,创建实体类
package com.qf.model; // 包
public class User { // 实体类,是表名
// 属性是字段名
private int id;
private String username;
private String password;
private String phone;
private Date createTime;
private double money;
private int sex;
// setter getter...
}
据.
- 表名 设计 类名
- 将列名设计成属性名
- id --> id
- create_time --> createTime (下划线转驼峰)
- 将列的数据类型设计成属性的数据类型
- 给类提供对应set get
一般项目中一个表就会对应一个实体类,所有的实体类都会放在model/entity/pojo/javabeen包结构中
将来写项目,数据库设计完,搭建完项目,第一件事件就是根据表结构,创建实体类
package com.qf.model; // 包
public class User { // 实体类,是表名
// 属性是字段名
private int id;
private String username;
private String password;
private String phone;
private Date createTime;
private double money;
private int sex;
// setter getter...
}