文章目录
- 概念
- 快速入门
- 驱动导入
- 实现
- 插入一条数据:
- 往表中添加一条数据
- 修改表
- 详解出现的几个对象:
- DriverManager
- Connection:数据库连接对象
- Statement:执行sql的对象
- ResultSet:结果集对象,封装查询结果
- JDBC工具类(util)
- PreparementStatement:执行SQL的对象
概念
- 概念:Java DataBase Connectivity 数据库连接,Java语言操作数据库
- 本质:定义的一套操作所有关系型数据库的规则,即接口。各个数据库厂商去实现这些接口,提供数据库驱动的jar包,我们可以用这套接口(JDBC)编程,真正执行的代码是jar包中的实现类。
快速入门
步骤:
- 导入驱动jar包(下载地址)
- 注册驱动
- 获取数据库连接对象(Connection)
- 定义sql
- 获取执行sql语句的对象Statement
- 执行sql
- 处理结果
- 释放资源
驱动导入
(1)在项目下新建一个文件夹libs,复制mysql-connector-java-5.1.49-bin.jar到项目的libs目录下
(2)右键文件夹–>Add as Library*/
实现
在 数据库world中原有的一个表:
插入一条数据:
package cn.itcast.jdbc;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
public class jdbcDemo1 {
public static void main(String[] args) throws Exception {
/* 1、导入jar包:mysql-connector-java-5.1.49-bin.jar
//2、注册驱动
Class.forName("com.mysql.jdbc.Driver");
//3、获取数据库的连接对象
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/world","root","xiao123");
//4、定义sql语句
String sql = "insert into student values (03,'Tony')";
//5、获取执行sql的对象statement
Statement stmt = conn.createStatement();
//6、执行sql
int count = stmt.executeUpdate(sql);
//7、处理结果
System.out.println(count);
//8、释放资源
stmt.close();
conn.close();
}
}
代码运行成功:
往表中添加一条数据
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
/*
往表student中添加一条记录
*/
public class jdbcDemo2 {
public static void main(String[] args) {
Statement stmt = null;
Connection conn = null;
//1、注册驱动
try {
Class.forName("com.mysql.jdbc.Driver");
//2、定义sql
String sql="insert student values(4,'Cater')";
//3、获取Connection对象
conn = DriverManager.getConnection("jdbc:mysql:///world","root","xiao123");
//4、获取执行sql的对象 Statement
stmt = conn.createStatement();
//5、执行sql
int count = stmt.executeUpdate(sql); //返回影响的行数
//6、处理结果
System.out.println(count);
if (count > 0){
System.out.println("添加成功!");
}else{
System.out.println("添加失败!");
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException throwables) {
throwables.printStackTrace();
}finally {
//stmt.close; stmt在try的作用域中,在finally中看不到stmt,需要提升stmt的作用域
//执行到步骤三时,可能会报错,这样后面的代码不会执行,直接进入到catch中,此时stmt为null,stmt.close会造成空指针异常
//为了避免空指针异常
if (stmt != null){
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (conn != null){
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
}
修改表
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
/*
修改student表
*/
public class jdbcDemo3 {
public static void main(String[] args) {
Connection conn = null;
Statement stmt = null;
//1、注册驱动
try {
Class.forName("com.mysql.jdbc.Driver");
//2、获取连接对象
conn = DriverManager.getConnection("jdbc:mysql:///world","root","xiao123");
//3、定义sql
String sql = "update student set id = 4 where name =Tony ";
//4、获取执行sql对象
stmt = conn.createStatement();
//5、执行sqlr
int count = stmt.executeUpdate(sql);
//6、处理结果
System.out.println(count);
if (count > 0 ){
System.out.println("修改成功!");
}else{
System.out.println("修改失败");
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
//7、释放资源
finally {
if (stmt != null){
try {
stmt.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if (conn != null){
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
}
详解出现的几个对象:
- DriverManager:驱动管理对象
- Connection:数据库连接对象
- Statement:执行sql的对象
- ResultSet:结果集对象
- PrepareStatement:执行sql的对象(功能比Statement更加强大)
DriverManager
功能:
- 注册驱动
static void registerDriver(Driver driver) :注册与给定的驱动程序DriverManager
class.forName("com.mysql.jdbc.Driver") 写代码时使用
通过查看源码,发现在com.mysql.jdbc.Driver类中存在静态代码块
所以,实际注册驱动的是DriverManager , class.forName(“com.mysql.jdbc.Driver”)这样写不过是简写。
由图可知在service中已经注册好Driver
在MySQL5之后的驱动jar包可自动注册驱动,所以MySQL5之后的可以省略注册驱动的步骤
- 获取数据库连接
1. 方法:static Connection getConnection(String url,String user,String password)
,方法名是getConnection,返回一个Connection对象
2. 参数:url—指定路径,语法:jdbc://mysql://ip地址(或域名):端口号/数据库名称
。如果连接的是本机的MySQL服务器,并且MySQL服务器端口为默认端口号3306,url可以简写为:jdbc:mysql:///数据库名称
,user和password就没什么可说的了。
Connection:数据库连接对象
功能:
- 获取执行的sql对象
上文中Statement stmt = conn.createStatement();
int count = stmt.executeUpdate(sql);
createStatement可返回Statement,Statement可执行相应的sql语句executeUpdate(sql),除此之外,还存在方法:
- Statement createment()
- Prepare Statement prepareStatement(String sql)
- 管理事务(第二篇文章):
- 开启事务:void setAutoCommit(boolean autoCommit) : 调用该方法设置参数为false,即开启事务
- 提交事务:Commit()
- 回滚事务:rollback()
Statement:执行sql的对象
- 功能:
- 执行sql
- boolean execute(String sql):可以执行任意的sql(了解即可,并不常用)
- int executeUpdate(String sql):执行DML(insert、update、delete)语句、DDL语句(create、alter、drop),返回值是影响的行数,返回值>0则执行成功,反之失败
- Resultset executeQuery(String sql) : 执行DQL(select)语句
package cn.itcast.jdbc;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
/*
DDL
*/
public class jdbcDemo5 {
public static void main(String[] args) {
Connection conn = null;
Statement stmt = null;
//1、注册驱动
try {
Class.forName("com.mysql.jdbc.Driver");
//2、获取连接对象
conn = DriverManager.getConnection("jdbc:mysql:///world","root","xiao123");
//3、定义sql
String sql = "create table employee (id int,name varchar(20))";
//4、获取执行sql对象
stmt = conn.createStatement();
//5、执行sqlr
int count = stmt.executeUpdate(sql);
//6、处理结果
System.out.println(count);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
//7、释放资源
finally {
if (stmt != null){
try {
stmt.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if (conn != null){
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
}
ResultSet:结果集对象,封装查询结果
- boolean next():游标向下移动一行,判断当前行是否有数据,如果有数据,返回false,没有数据则返回true.
- getXxx(参数):获取数据,Xxx为所获取数据的数据类型;
参数:
1、int:代表列的编号,从1开始 如:getString(1) 代表从第一列开始
2、String:代表列的名称,如:getString(“name”)
package cn.itcast.jdbc;
import java.sql.*;
/*
ResultSet中两个方法的使用
*/
public class jdbcDemo6 {
public static void main(String[] args) {
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
//1、注册驱动
try {
Class.forName("com.mysql.jdbc.Driver");
//2、获取连接对象
conn = DriverManager.getConnection("jdbc:mysql:///world","root","xiao123");
//3、定义sql
String sql = "select * from student";
//4、获取执行sql对象
stmt = conn.createStatement();
//5、执行sqlr
rs = stmt.executeQuery(sql);
//6、处理结果
//6.1 让光标向下移动一行
rs.next();
//6.2 获取数据
int id = rs.getInt(1);
String name = rs.getString("name");
System.out.println(id);
System.out.println(name);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
//7、释放资源
finally {
if (stmt != null){
try {
stmt.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if (conn != null){
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (rs != null){
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
}
package cn.itcast.jdbc;
import java.sql.*;
/*
遍历结果集
*/
public class jdbcDemo7 {
public static void main(String[] args) {
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
//1、注册驱动
try {
Class.forName("com.mysql.jdbc.Driver");
//2、获取连接对象
conn = DriverManager.getConnection("jdbc:mysql:///world","root","xiao123");
//3、定义sql
String sql = "select * from student";
//4、获取执行sql对象
stmt = conn.createStatement();
//5、执行sqlr
rs = stmt.executeQuery(sql);
//6、处理结果
/* //6.1 让光标向下移动一行
if (rs.next()){ //判断是否有数据
int id = rs.getInt(1);
String name = rs.getString("name");
System.out.println(id);
System.out.println(name);
}
//6.2 获取数据*/
while(rs.next()){
//循环判断结果集是否有下一行
//获取数据
int id = rs.getInt(1);
String name = rs.getString("name");
System.out.println(id);
System.out.println(name);
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
//7、释放资源
finally {
if (stmt != null){
try {
stmt.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if (conn != null){
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (rs != null){
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
}
JDBC工具类(util)
目的:简化书写
分析:
- 注册驱动
- 抽取一个方法获取连接对象
- 抽取一个方法,释放资源
url=jdbc:mysql:///world
user=root
password=xiao123
driver=com.mysql.jdbc.Driver
package cn.itcast.jdbc;
import java.io.FileReader;
import java.io.IOException;
import java.sql.*;
import java.util.Properties;
/*
JDBC工具类Utils
*/
public class jdbcUtils {
private static String url;
private static String user;
private static String password;
private static String driver;
/*
文件的读取只需要读取一次即可拿到这些值,使用静态代码块,只有静态的变量才能被静态的代码块使用
*/
static {
//读取资源文件,获取值
try {
//1、创建Properties集合类
Properties pro = new Properties();
//2、加载文件
pro.load(new FileReader("src/JDBCUtils.properties"));
//3、获取数据,赋值
url = pro.getProperty("url");
user = pro.getProperty("user");
password = pro.getProperty("password");
driver = pro.getProperty("driver");
//4、注册驱动
Class.forName(driver);
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
/*
获取连接,返回连接对象
*/
public static Connection getConnection() throws SQLException {
return DriverManager.getConnection(url,user,password);
}
/*
释放资源
*/
public static void close(ResultSet rs,Statement stmt, Connection conn){
if (stmt != null){
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (conn != null){
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (rs != null){
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
//2、获取连接对象
/*Class.forName("com.mysql.jdbc.Driver");
//2、获取连接对象
conn = DriverManager.getConnection("jdbc:mysql:///world","root","xiao123");*/
jdbcUtils.getConnection();
finally {
/*if (stmt != null){
try {
stmt.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if (conn != null){
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (rs != null){
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}*/
jdbcUtils.close(rs,stmt,conn);
}
PreparementStatement:执行SQL的对象
- SQL注入问题:在拼接SQL时,有一些SQL的特殊关键字参与字符串的拼接,会造成安全性问题
SQL注入即是指web应用程序对用户输入数据的合法性没有判断或过滤不严,攻击者可以在web应用程序中事先定义好的查询语句的结尾上添加额外的SQL语句,在管理员不知情的情况下实现非法操作,以此来实现欺骗数据库服务器执行非授权的任意查询,从而进一步得到相应的数据信息。
- 解决:使用PrepareStatement对象
- 预编译的SQL:参数使用?作为占位符
- 使用步骤
1. 导入驱动jar包 mysql-connector-java-5.1.37-bin.jar
2. 注册驱动
3. 获取数据库连接对象(Connection)
4. 定义sql
注意:sql的参数使用?作为占位符。如:select * from user where username = ? and password = ?
;
5. 获取执行sql语句的对象PrepareStatement
,调用Connection.prepareStatement(String sql)
6. 给?赋值:
方法:setXxx(参数1(?的位置),参数2(?的值))
7. 执行sql,接受返回结果,不需要传递sql语句
8. 处理结果
9. 释放资源 - 后期大多使用PrepareStatement来完成增删改查所有操作,可防止SQL注入,而且效率更高
package cn.itcast.jdbc;
import java.sql.*;
import java.util.Scanner;
/*
练习:
1、通过键盘录入用户名和密码
2、判断用户是否登录成功
*/
public class jdbcDemo8 {
public static void main(String[] args) {
//1、键盘录入用户名和密码
Scanner sc = new Scanner(System.in);
System.out.println("请输入用户名:");
String username = sc.nextLine();
System.out.println("请输入密码:");
String password = sc.nextLine();
//2、调用方法,ctrl + alt + v可快速生成对象
boolean flag = new jdbcDemo8().login2(username, password);
//3、判断结果,输出不同语句
if (flag){
System.out.println("登录成功");
}else{
System.out.println("用户名或密码错误!");
}
}
/*
登录方法
*/
public boolean login(String username, String password){
if (username == null && password == null){
return false;
}
//连接数据库是否登录成功
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
//1、获取连接
try {
conn = jdbcUtils.getConnection();
//2、定义SQL
String sql = "select * from user where username = '"+username+"' and password = '”+password+“'";
//3、获取执行sql的对象
stmt = conn.createStatement();
//4、执行查询
rs = stmt.executeQuery(sql);
//5、判断
/* if (rs.next()){ //如果有下一行则返回true
return true;
}else{
return false;
}*/
return rs.next(); //如果有下一行则返回true
} catch (SQLException e) {
e.printStackTrace();
}finally {
jdbcUtils.close(rs,stmt,conn);
}
return false;
}
/* 登录方法2 */
public boolean login2(String username, String password){
if (username == null && password == null){
return false;
}
//连接数据库是否登录成功
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
//1、获取连接
try {
conn = jdbcUtils.getConnection();
//2、定义SQL
String sql = "select * from user where username = ? and password = ?";
//3、获取执行sql的对象
pstmt = conn.prepareStatement(sql);
//给?赋值
pstmt.setString(1,username);
pstmt.setString(2,password);
//4、执行查询,不需要传参
rs = pstmt.executeQuery();
//5、判断
/* if (rs.next()){ //如果有下一行则返回true
return true;
}else{
return false;
}*/
return rs.next(); //如果有下一行则返回true
} catch (SQLException e) {
e.printStackTrace();
}finally {
jdbcUtils.close(rs,pstmt,conn);
}
return false;
}
}