介绍
jdbc :
- Java DataBase Connectivity , 即java数据库连接
- 是Java为连接数据库所制定的标准规范,即Java中用来规范客户端程序如何来访问数据库的应用程序(API)接口
- 不同的数据库,通过实现jdbc接口,访问数据库
- 提供了诸如查询和更新数据库中数据的方法。
连接数据库
本文使用的编辑器是:IDEA ;数据库是MySQL。
mysql-connector-java-5.1.46.jar里面是mysql厂商对java的jdbc做出的实现
我使用的IDEA为汉化版
步骤
一、创建Java工程
二、在项目根目录下创建lib文件夹,将mysql-connector-java-5.1.46.jar复制到该文件夹下
工程名 ——》 new(新建) ——》 Directory(目录)
三、导入jar包
1.File(文件) ——》Project structure(项目结构)
2.Modules ——》“+” ——》Library...
3. NEW LIBRARY... ——》java
4. 选择lib文件夹 ——》确定
5.勾选lib签的对号
代码编写
- 注册驱动
- 获得连接对象
- 获得执行语句对象
- 执行SQL
- 关流
public static void main(String[] args) throws ClassNotFoundException, SQLException {
//1. 注册驱动
Class.forName("com.mysql.jdbc.Driver");
//2. 获得连接对象
// jdbc协议:mysql协议//ip:端口/数据库名
String url = "jdbc:mysql://localhost:3306/java28";
String userName = "root"; // mysql用户名
String password = "123456"; // mysql 密码
Connection conn = DriverManager.getConnection(url, userName, password);
// 3. 通过连接对象获得执行语句对象
Statement s = conn.createStatement();
// 4. 执行sql语句
String sql = "insert into emp values(5,'周瑜',30,'1990-01-01',100)";
// 增删改都是Update,返回值是受影响的行数
int rowNum = s.executeUpdate(sql);
if(rowNum == 1){
System.out.println("执行成功");
}
// 5. 关流
s.close();
conn.close();
}
DML操作
插入
如上例题
更新
public static void main(String[] args) {
try {
Class.forName("com.mysql.jdbc.Driver");
String url = "jdbc:mysql://localhost:3306/java28";
String userName = "root";
String password = "123456";
Connection conn = DriverManager.getConnection(url, userName, password);
Statement s = conn.createStatement();
String sql = "update emp set e_salary=300 where e_id = 5";
int rowNum = s.executeUpdate(sql);
if (rowNum > 0){
System.out.println("更新成功");
}else {
System.out.println("更新失败");
}
}catch(Exception e){
System.out.println(e.getMessage());
}
}
删除
public static void main(String[] args) {
try{
//1
Class.forName("com.mysql.jdbc.Driver");
//2
String url = "jdbc:mysql://localhost:3306/java28";
String uerName = "root";
String password = "123456";
Connection conn = DriverManager.getConnection(url, uerName, password);
//3
Statement s = conn.createStatement();
//4
String sql = "delete from emp where e_id=1";
int rowNum = s.executeUpdate(sql);
if (rowNum > 0) {
System.out.println("删除成功");
} else {
System.out.println("删除失败");
}
//5
s.close();
conn.close();
}catch (Exception e){
System.out.println(e.getMessage());
}
}
DQL操作
public static void main(String[] args) {
try {
//1
Class.forName("com.mysql.jdbc.Driver");
//2
String url = "jdbc:mysql://localhost:3306/java28";
String userName = "root";
String password = "123456";
Connection conn = DriverManager.getConnection(url, userName, password);
//3
Statement s = conn.createStatement();
//4 查询使用executeQuery()
String sql = "select * from emp";
ResultSet rs = s.executeQuery(sql);
while (rs.next()) {
//通过下标获得该字段的数据,下标从1开始
//注意 : 是按照虚拟表的字段顺序
int id = rs.getInt(1);
System.out.print("e_id = " + id);
//通过列名获得该字段的数据 注意 : 是按照虚拟表的列名
String name = rs.getString("e_name");
System.out.print(" , e_name = " + name);
String age = rs.getString("e_age");
System.out.print(" , e_age = " + age);
Date birthday = rs.getDate("e_birthday");
System.out.print(" , e_birthday = " + birthday);
double salary = rs.getDouble("e_salary");
System.out.print(" , e_salary = " + salary);
System.out.println();
}
}catch (Exception e){
System.out.println(e.getMessage());
}
}
封装结果集
表 ——》 实体类
字段 ——》属性
行数据 ——》对象
- 根据表创建出对应的实体类
- 根据表字段即类型 设置实体类对应的 属性
public static void main(String[] args) {
try {
//1
Class.forName("com.mysql.jdbc.Driver");
//2
String url = "jdbc:mysql://localhost:3306/java28";
String userName = "root";
String password = "123456";
Connection conn = DriverManager.getConnection(url, userName, password);
//3
Statement s = conn.createStatement();
//4 查询使用executeQuery()封装
String sql = "select * from emp";
ResultSet rs = s.executeQuery(sql);
while (rs.next()) {
//通过下标获得该字段的数据,下标从1开始
//注意 : 是按照虚拟表的字段顺序
int id = rs.getInt("e_id");
String name = rs.getString("e_name");
int age = rs.getInt("e_age");
Date birthday = rs.getDate("e_birthday");
double salary = rs.getDouble("e_salary");
Emp emp = new Emp();
emp.setE_id(id);
emp.setE_name(name);
emp.setE_age(age);
emp.setE_birthday(birthday);
emp.setE_salary(salary);
System.out.println(emp);
}
}catch (Exception e){
System.out.println(e.getMessage());
}
}
Emp类
package test_Login;
import java.util.Date;
public class Emp {
private int e_id;
private String e_name;
private String e_password;
private int e_age;
private Date e_birthday;
private double e_salary;
public int getE_id() {
return e_id;
}
public void setE_id(int e_id) {
this.e_id = e_id;
}
public String getE_name() {
return e_name;
}
public void setE_name(String e_name) {
this.e_name = e_name;
}
public String getE_password() {
return e_password;
}
public void setE_password(String e_password) {
this.e_password = e_password;
}
public int getE_age() {
return e_age;
}
public void setE_age(int e_age) {
this.e_age = e_age;
}
public Date getE_birthday() {
return e_birthday;
}
public void setE_birthday(Date e_birthday) {
this.e_birthday = e_birthday;
}
public double getE_salary() {
return e_salary;
}
public void setE_salary(double e_salary) {
this.e_salary = e_salary;
}
@Override
public String toString() {
return "Emp{" +
"e_id=" + e_id +
", e_name='" + e_name + '\'' +
", e_password='" + e_password + '\'' +
", e_age=" + e_age +
", e_birthday=" + e_birthday +
", e_salary=" + e_salary +
'}';
}
}
预处理sql语句
是一种编译过的要执行的SQL语句模板,可以使用不同的变量参数定制它。预处理语句具有两个主要的优点:
- 查询只需要被解析(或准备)一次,但可以使用相同或不同的参数执行多次。当查询准备好(Prepared)之后,数据库就会分析,编译并优化它要执行查询的计划。对于复杂查询来说,如果你要重复执行许多次有不同参数的但结构相同的查询,这个过程会占用大量的时间,使得你的应用变慢。通过使用一个预处理语句你就可以避免重复分析、编译、优化的环节。简单来说,预处理语句使用更少的资源,执行速度也就更快。
- 传给预处理语句的参数不需要使用引号,底层驱动会为你处理这个。如果你的应用独占地使用预处理语句,你就可以确信没有SQL注入会发生。(但是,如果你仍然在用基于不受信任的输入来构建查询的其他部分,这仍然是具有风险的)。
用法:当sql语句使用参数时,可以用“ ? ”来代替参数值
使用预处理查询:
public Emp select(int id) {
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
Emp emp = null;
try {
Class.forName("com.mysql.jdbc.Driver");
String url = "jdbc:mysql://localhost:3306/java28";
String mysqlName = "root";
String mysqlPwd = "123456";
conn = DriverManager.getConnection(url, mysqlName, mysqlPwd);
String sql = "select * from emp where e_id = ?";
ps = conn.prepareStatement(sql);
ps.setInt(1,id);
rs = ps.executeQuery();
while (rs.next()) {
emp = new Emp();
emp.setE_id(rs.getInt("e_id"));
emp.setE_name(rs.getString("e_name"));
emp.setE_password(rs.getString("e_password"));
emp.setE_age(rs.getInt("e_age"));
emp.setE_birthday(rs.getDate("e_birthday"));
emp.setE_salary(rs.getDouble("e_salary"));
}
}catch (Exception e) {
System.out.println(e.getMessage());
}finally {
try {
rs.close();
ps.close();
conn.close();
}catch (SQLException se){
System.out.println(se.getMessage());
}
}
return emp;
}
使用预处理添加:
public boolean insert(Emp emp){
Connection conn = null;
PreparedStatement ps = null;
try {
Class.forName("com.mysql.jdbc.Driver");
String mysqlUrl = "jdbc:mysql://localhost:3306/java28";
String mysqlName = "root";
String mysqlPwd = "123456";
conn = DriverManager.getConnection(mysqlUrl,mysqlName,mysqlPwd);
String sql = "insert into emp values(?,?,?,?,?,?)";
ps = conn.prepareStatement(sql);
ps.setInt(1,emp.getE_id());
ps.setString(2,emp.getE_name());
ps.setString(3,emp.getE_password());
ps.setInt(4,emp.getE_age());
ps.setDate(5, new Date(emp.getE_birthday().getTime()));
ps.setDouble(6,emp.getE_salary());
int rowNum = ps.executeUpdate();
if (rowNum > 0) {
System.out.println("添加成功");
return true;
}
}catch (Exception e){
System.out.println("添加失败 , 错误 : \n" + e.getMessage());
}finally {
try {
ps.close();
conn.close();
}catch (SQLException se){
System.out.println(se.getMessage());
}
}
System.out.println("添加失败");
return false;
}
封装SQL语句
DBUtil
jdbc 操作 : 步骤固定
注册驱动
获得连接
获得执行语句对象
执行sql
关流
将每次的重复步骤封装成工具方法,方便使用à 减少重复,提供效率
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
/**
* @desc 数据库操作工具类
*/
public class DBUtil {
static final String url = "jdbc:mysql://localhost:3306/java28";
static final String username = "root";
static final String password = "123456";
/**
* 静态代码块:保证数据库驱动先加载且只加载一次
*/
static {
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException e) {
System.out.println("加载驱动异常");
e.printStackTrace();
}
}
/**
* 获得数据库连接对象
*/
public static Connection getConnection() {
Connection conn = null;
try {
conn = DriverManager.getConnection(url,username,password);
} catch (Exception e) {
System.out.println("获得连接异常!");
e.printStackTrace();
}
return conn;
}
/**
* 关流
*/
public static void closeAll(Statement s,Connection conn) {
try {
s.close();
} catch (SQLException e) {
System.out.println("Statement 关流异常");
e.printStackTrace();
}
try {
conn.close();
} catch (SQLException e) {
System.out.println("Connection 关流异常");
e.printStackTrace();
}
}
/**
* 关流
*/
public static void closeAll(ResultSet rs,Statement s,Connection conn) {
try {
rs.close();
} catch (SQLException e) {
System.out.println("ResultSet 关流异常");
e.printStackTrace();
}
try {
s.close();
} catch (SQLException e) {
System.out.println("Statement 关流异常");
e.printStackTrace();
}
try {
conn.close();
} catch (SQLException e) {
System.out.println("Connection 关流异常");
e.printStackTrace();
}
}
}
DBUtil加强版
import java.sql.*;
/**
* 数据库操作工具类
*/
public class DBUtil {
private static final String url = "jdbc:mysql://localhost:3306/homework";
private static final String user = "root";
private static final String password = "123456";
private static Connection conn = null;
private static PreparedStatement ps = null;
private static ResultSet rs = null;
/**
* 静态代码块 : 加载驱动 , 获得数据库对象
*/
static {
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
try {
conn = DriverManager.getConnection(url,user,password);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 获得数据库对象
*/
// public void getConnection(){
// try {
// conn = DriverManager.getConnection(url,user,password);
// } catch (Exception e) {
// e.printStackTrace();
// }
// }
/**
* 关流
*/
public void closeAll(){
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
try {
ps.close();
} catch (SQLException e) {
e.printStackTrace();
}
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
/**
* 说明 : 进行数据库的增删改操作
* @param sql 传入的sql语句,参数使用?代替
* @param o sql语句会使用到的参数,顺序与sql语句中一致
*/
public int update(String sql, Object... o){
int rowNum = -1;
try {
ps = conn.prepareStatement(sql);
for (int i = 0; i < o.length; i++){
ps.setObject(i+1,o[i]);
}
rowNum = ps.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
}
return rowNum;
}
/**
* 说明 : 进行数据库的查询操作
* @param sql 传入的sql语句,参数使用?代替
* @param o sql语句会使用到的参数,顺序与sql语句中一致
*/
public ResultSet select(String sql,Object... o){
try {
ps = conn.prepareStatement(sql);
for (int i = 0; i < o.length; i++){
ps.setObject(i+1,o[i]);
}
rs = ps.executeQuery();
} catch (Exception e) {
e.printStackTrace();
}
return rs;
}
}