JDBC流程快速浏览
接下来进行jdbc的正式学习,在学习之前,我们要先在mysql中要用的表
#创建数据库
CREATE DATABASE how2j;
#创建表
CREATE TABLE hero (
id INT(11) AUTO_INCREMENT,
NAME VARCHAR(30) ,
hp FLOAT ,
damage INT(11) ,
PRIMARY KEY (id)
) DEFAULT CHARSET=utf8;
#在表中插入数据
INSERT INTO hero VALUES (NULL, '盖伦', 616, 100);
生成的表如下结构:
使用jdbc主要步骤如下:
1)导入驱动jar包
2)注册驱动
3)获取数据库连接对象Connection
4)定义sql语句
5)获取执行SQL的对象statement
6)执行sql,接收返回结果
7)处理结果
8)释放资源
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
public class jdbcDemo1 {
public static void main(String[] args) throws Exception {
//导入驱动jar包,上个笔记的内容
//注册驱动
Class.forName("com.mysql.jdbc.Driver");
//获取数据库连接对象
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/how2j","root","root");
//定义sql语句
String sql="update hero set hp=100 where id =1";
//获取执行sql的对象
Statement stmt = conn.createStatement();
//执行sql
int count = stmt.executeUpdate(sql);
//处理执行结果
System.out.println(count);
//释放资源
stmt.close();
conn.close();
}
}
执行程序之后可以看到hero表中的id=1的hp变为了100。下面开始具体解释每个步骤。
初始化驱动
package jdbc;
public class TestJDBC {
public static void main(String[] args) {
try {
//导入的jar包中有一个驱动类com.mysql.jdbc.Driver
//需要抛出异常
Class.forName("com.mysql.jdbc.Driver");
System.out.println("数据库加载成功");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
获取数据库连接对象Connection
这里需要提供:
数据库所处于的ip:127.0.0.1 (本机)
数据库的端口号: 3306 (mysql专用端口号)
数据库名称 how2java
编码方式 UTF-8
账号 root
密码 admin
package jdbc;
import java.sql.Connection;
import java.sql.DriverManager;
public class TestJDBC {
public static void main(String[] args) {
try {
Class.forName("com.mysql.jdbc.Driver");
//?后面的部分是指明编码方式,防止乱码
String url="jdbc:mysql://127.0.0.1:3306/how2j?characterEncoding=UTF-8";
String user="root";
String password="root";
Connection c=DriverManager.getConnection(url, user, password);
} catch (Exception e) {
e.printStackTrace();
}
}
}
定义sql语句、获取执行SQL的对象、执行sql
执行下列程序成功后可以在mysql中看到插入了一条“提莫”数据。
package jdbc;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
public class TestJDBC {
public static void main(String[] args) {
try {
Class.forName("com.mysql.jdbc.Driver");
String url="jdbc:mysql://127.0.0.1:3306/how2j?characterEncoding=UTF-8";
String user="root";
String password="root";
Connection c=DriverManager.getConnection(url, user, password);
//定义sql语句
String sql="insert into hero values(null,"+"'提莫'"+","+313.0f+","+50+")";
//获取执行sql的对象statemenet
Statement s = c.createStatement();
//执行sql
s.execute(sql);
System.out.println("执行插入语句成功");
} catch (Exception e) {
e.printStackTrace();
}
}
}
关闭连接
数据库的连接是有限资源,相关操作结束后,养成关闭数据库的好习惯,关闭的顺序是:先打开的后关闭,后打开的先关闭。
//有隐患的关闭方式
package jdbc;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
public class TestJDBC {
public static void main(String[] args) {
try {
Class.forName("com.mysql.jdbc.Driver");
String url="jdbc:mysql://127.0.0.1:3306/how2j?characterEncoding=UTF-8";
String user="root";
String password="root";
Connection c=DriverManager.getConnection(url, user, password);
String sql="insert into hero values(null,"+"'提莫'"+","+313.0f+","+50+")";
Statement s = c.createStatement();
s.execute(sql);
System.out.println("执行插入语句成功");
//关闭连接
//但是这种关闭是有隐患的,比如s.execute(sql);语句抛出了异常,那么下面的语句不再执行,所以会导致连接一直没有关闭。
s.close();
c.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
最好的办法是将关闭连接的两个语句放到finally语句中去执行,这样的话不论是否出现异常,finally中的语句肯定会被执行。
//直接放进finally块中会报错
package jdbc;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
public class TestJDBC {
public static void main(String[] args) {
try {
Class.forName("com.mysql.jdbc.Driver");
String url="jdbc:mysql://127.0.0.1:3306/how2j?characterEncoding=UTF-8";
String user="root";
String password="root";
Connection c=DriverManager.getConnection(url, user, password);
String sql="insert into hero values(null,"+"'提莫'"+","+313.0f+","+50+")";
Statement s = c.createStatement();
s.execute(sql);
System.out.println("执行插入语句成功");
} catch (Exception e) {
e.printStackTrace();
} finally {
//关闭连接, 但是这样会报错,因为try块中生命的对象旨在try中起作用
s.close();
c.close();
}
}
}
解决的办法是在块外面先声明Connection和Statement对象
package jdbc;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
public class TestJDBC {
public static void main(String[] args) {
Connection c = null;
Statement s = null;
try {
Class.forName("com.mysql.jdbc.Driver");
String url="jdbc:mysql://127.0.0.1:3306/how2j?characterEncoding=UTF-8";
String user="root";
String password="root";
c=DriverManager.getConnection(url, user, password);
String sql="insert into hero values(null,"+"'提莫'"+","+313.0f+","+50+")";
s = c.createStatement();
s.execute(sql);
System.out.println("执行插入语句成功");
} catch (Exception e) {
e.printStackTrace();
} finally {
//关闭连接, 但是这样会报错,因为try块中生命的对象旨在try中起作用
s.close();
c.close();
}
}
}
现在finally中的关闭对象语句扔旧会报错,这是因为需要抛出异常,所以最终程序如下:
package jdbc;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
public class TestJDBC {
public static void main(String[] args) {
Connection c = null;
Statement s = null;
try {
Class.forName("com.mysql.jdbc.Driver");
String url="jdbc:mysql://127.0.0.1:3306/how2j?characterEncoding=UTF-8";
String user="root";
String password="root";
c=DriverManager.getConnection(url, user, password);
String sql="insert into hero values(null,"+"'提莫'"+","+313.0f+","+50+")";
s = c.createStatement();
s.execute(sql);
System.out.println("执行插入语句成功");
} catch (Exception e) {
e.printStackTrace();
} finally {
if(s != null)
try {
s.close();
} catch (SQLException e) {
e.printStackTrace();
}
if(c != null)
try {
c.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
try-with-resources关闭流
上面的关闭流方式很麻烦,使用 try-with-resources方式可以简化这种过程,这是从JDK7开始支持的技术。把流定义在try()里,try,catch或者finally结束的时候,会自动关闭流,因此程序可以这样写。
package jdbc;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
public class TestJDBC {
public static void main(String[] args) {
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
String url="jdbc:mysql://127.0.0.1:3306/how2j?characterEncoding=UTF-8";
String user="root";
String password="root";
//()括号里面是重点
try(Connection c=DriverManager.getConnection(url, user, password);
Statement s = c.createStatement();
){
String sql="insert into hero values(null,"+"'提莫'"+","+313.0f+","+50+")";
s.execute(sql);
} catch(SQLException e){
e.printStackTrace();
}
}
}
CRUD增删查改
增删改查都很类似,区别只在于sql语句的定义不同。
增加一条数据
package jdbc;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
public class TestJDBC {
public static void main(String[] args) {
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
String url="jdbc:mysql://127.0.0.1:3306/how2j?characterEncoding=UTF-8";
String user="root";
String password="root";
//()括号里面是重点
try(Connection c=DriverManager.getConnection(url, user, password);
Statement s = c.createStatement();
){
String sql="insert into hero values(null,"+"'提莫'"+","+313.0f+","+50+")";
s.execute(sql);
} catch(SQLException e){
e.printStackTrace();
}
}
}
删除一条数据
package jdbc;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
public class TestJDBC {
public static void main(String[] args) {
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
String url="jdbc:mysql://127.0.0.1:3306/how2j?characterEncoding=UTF-8";
String user="root";
String password="root";
try(Connection c=DriverManager.getConnection(url, user, password);
Statement s = c.createStatement();
){
//删除id为5的一条数据
String sql="delete from hero where id=5";
s.execute(sql);
} catch(SQLException e){
e.printStackTrace();
}
}
}
修改一条数据中的一个字段内容
package jdbc;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
public class TestJDBC {
public static void main(String[] args) {
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
String url="jdbc:mysql://127.0.0.1:3306/how2j?characterEncoding=UTF-8";
String user="root";
String password="root";
try(Connection c=DriverManager.getConnection(url, user, password);
Statement s = c.createStatement();
){
//将id为3的英雄名字设置为name3
String sql="update hero set name='name3' where id=3";
s.execute(sql);
} catch(SQLException e){
e.printStackTrace();
}
}
}
练习
设计一个方法
public static void execute(String sql),方法接受的参数是SQL语句,无论是增加,删除,还是修改,都调用这个方法,每次传不同的SQL语句作为参数。
package jdbc;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
public class TestJDBC {
public static void main(String[] args) {
String sql_insert = "insert into hero values(null,"+"'大嘴'"+","+233.0f+","+34+")";
String sql_delete="delete from hero where id=6";
String sql_update="update hero set name='name1' where id=1";
excute(sql_delete);
}
public static void excute(String sql) {
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
String url="jdbc:mysql://127.0.0.1:3306/how2j?characterEncoding=UTF-8";
String user="root";
String password="root";
try(Connection c=DriverManager.getConnection(url, user, password);
Statement s = c.createStatement();
){
String sql1=sql;
s.execute(sql1);
System.out.println("成功!");
} catch(SQLException e){
e.printStackTrace();
}
}
}
executeQuery 执行SQL查询语句并返回结果集ResultSet
package jdbc;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class TestJDBC {
public static void main(String[] args) {
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
String url="jdbc:mysql://127.0.0.1:3306/how2j?characterEncoding=UTF-8";
String user="root";
String password="root";
try(Connection c=DriverManager.getConnection(url, user, password);
Statement s = c.createStatement();
){
//检索表hero中的所有数据
String sql="select * from hero";
//执行查询,并返回结果集
ResultSet rs= s.executeQuery(sql);
//遍历结果集
while(rs.next()) {
int id = rs.getInt(1);//获取第一个字段信息,也可以直接指定字段int id = rs.getInt("id");
String name = rs.getString(2);//同上
float hp = rs.getFloat(3);
int damage = rs.getInt(4);
System.out.println(id+" "+name+" "+hp+" "+damage);
}
System.out.println("成功!");
} catch(SQLException e){
e.printStackTrace();
}
}
}
SQL语句判断账号密码是否正确
先在MySQL中创建一个接下来要用的表user
CREATE TABLE USER (
id INT(11) AUTO_INCREMENT,
NAME VARCHAR(30) ,
PASSWORD VARCHAR(30),
PRIMARY KEY (id)
) ;
INSERT INTO USER VALUES(NULL,'dashen','thisispassword');
然后检索当前用户名的密码是否正确
package jdbc;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class TestJDBC {
public static void main(String[] args) {
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
String url="jdbc:mysql://127.0.0.1:3306/how2j?characterEncoding=UTF-8";
String user="root";
String password="root";
try(Connection c=DriverManager.getConnection(url, user, password);
Statement s = c.createStatement();
){
String name1 = "dashen";
String password1 = "thisispassword1";//正确的密码为thisispassword
String sql = "select * from user where name = '" + name1 +"' and password = '" + password1+"'";
ResultSet rs= s.executeQuery(sql);
if (rs.next()) System.out.println("密码正确");
else System.out.println("密码错误");
} catch(SQLException e){
e.printStackTrace();
}
}
}
查看hero表中总共有多少条数据
package jdbc;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class TestJDBC {
public static void main(String[] args) {
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
String url="jdbc:mysql://127.0.0.1:3306/how2j?characterEncoding=UTF-8";
String user="root";
String password="root";
try(Connection c=DriverManager.getConnection(url, user, password);
Statement s = c.createStatement();
){
String sql = "select count(*) from hero";
ResultSet rs= s.executeQuery(sql);
int count=0;
if (rs.next()) {
count=rs.getInt(1);
}
System.out.println(count);
} catch(SQLException e){
e.printStackTrace();
}
}
}
练习
设计一个方法,进行分页查询public static void list(int start, int count)。start表示开始页数,count表示一页显示的总数,list(0,2) 表示第一页,一共显示2条数据,list(10,2) 表示第10页,一共显示2条数据
package jdbc;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class TestJDBC {
public static void main(String[] args) {
//从0开始查询2行
list(0,2);
}
public static void list(int start, int count) {
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
String url="jdbc:mysql://127.0.0.1:3306/how2j?characterEncoding=UTF-8";
String user="root";
String password="root";
try (
Connection c = DriverManager.getConnection(url, user, password);
Statement s = c.createStatement();
) {
String sql=String.format("select * from hero limit %d,%d", start,count);
ResultSet rs = s.executeQuery(sql);
while(rs.next()) {
int id=rs.getInt("id");
String name = rs.getString("name");
float hp=rs.getFloat(3);
int damage = rs.getInt(4);
System.out.println(id+" "+name+" "+hp+" "+damage);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}