JDBC
JDBC概念
什么是JDBC:Java DataBase Connectivity 使用 Java语言链接数据库的技术
本质:就是官方定义的操作数据库的一套规范、规则,都是接口。各个数据库厂商去实现这套接口,提供对应的数据库驱动jar包。
我们可以使用这个驱动jar包,来完成链接数据库操作数据库的功能。
快速入门
步骤:
快速回忆:
多表链接:
内链接:隐式内连接 用逗号“,”链接条件使用where,没有inner join、显氏内连接使用关键字[inner]join on条件
外连接:左外连接 left[outer] join on 条件、右外链接 right[outer] join on条件
子查询:
单行单列 使用比较运算符 > < != <>...条件放在where语句后面
多行单列 使用in运算符 in(散列数据) 条件放在where语句的后面
多行多列 放在from的后面 作为一张表进行二次查询的条件判断
介绍JDBC快速入门使用的包和类
java.sql 所有与JDBC访问数据库相关的类和接口
javax.sql用到数据库连接池 数据库的扩展包,提供数据库操作的额外一些功能,如:链接池
DriverManager 驱动管理 注册驱动 还有获取数据库链接对象
Connection 链接对象 用于创建执行sql的对象 statement、preparedStatement对象
Statrment:sql语句执行对象,用于将sql语句发送给数据库服务器
PreparedStatement sql语句执行对象 是Statement接口的子接口
ResultSet 用于封装从数据库查询出来的结果值
DriverManager
从JDBC3开始,可以不用注册驱动可以直接使用。Class.forName();
connection getConnection(url,user,password);可以获取到数据库的链接对象
Connection getConnection(String url,Properties infro);通过链接字符串喝属性对象 获取数据库链接对象
user登录数据库用户名
password 登录数据库的密码
url 链接数据库的路径 对于mysql而言 jdbc:mysql://服务器ip地址:端口号3306/数据库名称?
【参数名=参数值】
驱动类路径 com.mysql.jdbc.Driver
jdbc:mysql://服务器ip地址:端口号3306/数据库名称?【参数名=参数值】如果数据库的服务器是在本地中,胜率掉ip地址和
端口号---->jdbc:mysql:///数据库名称?[参数名=参数值]
如果数据传输引发了乱码,后面可以使用参数characterEncoding = utf8
jdbc:mysql:///数据库名称?characterEncoding = utf8
Connection接口
作用:链接数据库,它是一个接口,由具体的厂商来提供具体的实现类,代表的是一个链接对象
Statement createStatement()创建一个sql执行对象
PrepareStatement preparedStatement() 创建一个sql预处理对象
Statement接口
作用:用来执行sql语句,本质是把sql语句发送给数据库服务器 int executeUpdate(sql)用于把sql语句发送给服务器,执行增删改操作。
返回值int影响数据库的记录数(行数)
ResultSet excuteQuery(String sql)用于把sql语句发送给服务器 执行查询操作。返回值ResultSet查询返回的结果集
preparedStatement
执行sql的对象
会防止一些sql注入问题,在拼接sql语句时,可能会造成安全性问题如
“select*from account where username like %”+username + "%'and balance='+balance+
使用预编译的sql,参数使用?作为占位符
操作:
在sql语句中涉及到参数时使用?替代具体的数据 如:select*from user where username =? and password = ?
使用预编译对象执行sql语句获取编译对象onnection.preparedStatemen(String sql)
给?赋值:
使用方法:setXxx(?索引下标,?对应的实际值)
使用预编译对象执行sql,获取返回的结果集值--->preparedStatement.executeQuery();
处理结果
释放资源
需要释放的资源对象:ResultSet对象 Statement对象 Connection对象
释放的顺序:先开后关,后开先关 ResultSet--->Statement--->Connection
释放资源:使用finally语句块,一定会被加载到,不能单独使用,需要搭配try语句块
常用数据库数据类型和java类型对照
sql | jdbc方法 | java |
---|---|---|
int | getint() | int |
bigint | getlong() | long |
bit | getBoolean() | boolean |
varchar | getString() | String |
date/time/TimeStamp | getDate/getTime/getTimeStamp | java.sql.Time/java.util.Date/java.sql.Timestamp |
double | double | double |
备注:java.sql.Date/Time/TimeStamp(时间戳)三个共同的父类时--->java.util.Date
数据库工具类 DBUtil
package Demo03;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;
import com.zhiyou100.entity.Account;
public class JDBCDemo03 {
//定义四个常量值
private static final String DRIVER="com.mysql.jdbc.Driver";
private static final String URL="jdbc:mysql:///java31?characterEncoding=utf8";
private static final String USER="root";
private static final String PASSWORD="root";
private static Connection con = null;
private static Statement ct = null;
private static ResultSet set = null;
static {
try {
Class.forName(DRIVER);
con = DriverManager.getConnection(URL, USER, PASSWORD);
ct = con.createStatement();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void main(String[] args) {
//增加数据
//insertData("insert into account values(null,'赵六',11)");
//删除数据
//deleteDate("delete from account where username='赵六'");
//修改数据
//updateDate("update account set balance=20000 where username='看见立刻'");
//查询数据
//queryData("select * from account where username = '赵六'");
List<Account> list=queryAll2("select * from account ");
//stream 的操作 优化集合 函数模型 可以结合Lambda表达式
Stream<Account> stream = list.stream();
//id值小于2过滤掉 保留id>=2
stream.filter(account -> account.getId() >= 2
).forEach(account -> System.out.println(account));
}
//关闭连接的方法
public static void closeAll() {
if(set!=null) {
try {
set.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(ct!=null) {
try {
ct.close();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(con!=null) {
try {
con.close();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
//查询全部数据优化
public static List<Account> queryAll2(String sql) {
//在外面使用单列集合Collection ArrayList
ArrayList<Account> list = new ArrayList<>();//空的集合
try {
set = ct.executeQuery(sql);
//取出的次数不确定 使用while循环
while(set.next()) {
//构建Account类的对象 1个对象对应的就是表中的一条记录
Account account = new Account();
//取出每一条记录当中的字段值
int id = set.getInt("id");
String name = set.getString("username");
double double1 = set.getDouble("balance");
//把每次取出的记录字段值存进对象汇总
account.setId(id);
account.setUsername(name);
account.setBalance(double1);
//把每次构建的对象存进集合当中
list.add(account);
//System.out.println(id+name+double1);
//容器 集合 ArrayList HasMap Object
// 映射类 model 封装类 类的对象 对象也可以当成一个容器 对象放的是属性
//model类 他应该取映射数据库中的表
// model类中的属性和数据库表的字段应该一一对应
/* 对应内容 属性 字段
* 名称 属性名称 字段名称 一一对应
* 数据类型 属性类型 字段类型 一一对应
* 如账户表 account
* 创建Account类的时候需要和account表中的字段保持一致
* 对象来存储查询的每条记录值,如果有多条记录那么可以使用对象数组或者时集合
* (单列集合、双列集合)
*
*/
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
//关闭时 先关闭resultSet
closeAll();
}
//把查询的结果集返回给方法调用者处
return list;
}
//查询全部数据
public static void queryData3(String sql) {
try {
set = ct.executeQuery(sql);
//next()----》判断结果集中是否有下一个元素 (一条记录)
boolean result1 = set.next();
if(result1) {
//有下一个记录值
/*getInt(int columIndex) 字段的索引 从1开始 用的不多
* getInt(String) 字段名称
*
*/
//int id = set.getInt(1);
int id2 = set.getInt("id");
System.out.println(id2);//3
String username = set.getString("username");
System.out.println(username);
//余额
double double1 = set.getDouble("balance");
System.out.println(double1);
}
//判断是否华友下一个元素
boolean result2 = set.next();
if(result2) {
int id2 = set.getInt("id");
System.out.println(id2);//3
String username = set.getString("username");
System.out.println(username);
//余额
double double1 = set.getDouble("balance");
System.out.println(double1);
}else {
System.out.println("结果值已经呗取完了");
}
boolean result3 = set.next();
if(result3) {
int id2 = set.getInt("id");
System.out.println(id2);//3
String username = set.getString("username");
System.out.println(username);
//余额
double double1 = set.getDouble("balance");
System.out.println(double1);
}else {
System.out.println("结果值已经呗取完了");
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
//关闭时 先关闭resultSet
if(set!=null) {
try {
set.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(ct!=null) {
try {
ct.close();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(con!=null) {
try {
con.close();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
//查询数据
public static void queryData2(String sql) {
//执行sql语句
try {
set = ct.executeQuery(sql);
//next()----》判断结果集中是否有下一个元素 (一条记录)
boolean result1 = set.next();
if(result1) {
//有下一个记录值
/*getInt(int columIndex) 字段的索引 从1开始 用的不多
* getInt(String) 字段名称
*
*/
//int id = set.getInt(1);
int id2 = set.getInt("id");
System.out.println(id2);//3
String username = set.getString("username");
System.out.println(username);
//余额
double double1 = set.getDouble("balance");
System.out.println(double1);
}
//判断是否华友下一个元素
boolean result2 = set.next();
if(result2) {
int id2 = set.getInt("id");
System.out.println(id2);//3
String username = set.getString("username");
System.out.println(username);
//余额
double double1 = set.getDouble("balance");
System.out.println(double1);
}else {
System.out.println("结果值已经呗取完了");
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
//关闭时 先关闭resultSet
if(set!=null) {
try {
set.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(ct!=null) {
try {
ct.close();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(con!=null) {
try {
con.close();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
//查询数据
public static void queryData(String sql) {
try {
set = ct.executeQuery(sql);
//使用迭代器 Iteration next() --->获取下一个元素 hasnext()判断是否有下一个元素
//在ResultSet中 next() 判断是否有下一个元素 如果有返回true 没有返回false
if(set.next()) {
System.out.println("查询到需要的数据");
}else {
System.out.println("没有查询到需要的数据");
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
//关闭时 先关闭resultSet
if(set!=null) {
try {
set.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(ct!=null) {
try {
ct.close();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(con!=null) {
try {
con.close();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
//修改数据
public static void updateDate(String sql) {
try {
int count = ct.executeUpdate(sql);
if(count>0) {
System.out.println("修改成功!");
}else {
System.out.println("修改失败!");
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
//尽量先判断下打开的链接对象是否为空 Connection Statement ResultSet
if(ct!=null) {
try {
ct.close();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(con!=null) {
try {
con.close();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
//删除数据
public static void deleteDate(String sql) {
//2
//3
//4
//5.
//6.
try {
int count = ct.executeUpdate(sql);
if(count>0) {
System.out.println("数据删除成功");
}else {
System.out.println("数据删除失败!");
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
//尽量先判断下打开的链接对象是否为空 Connection Statement ResultSet
if(ct!=null) {
try {
ct.close();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(con!=null) {
try {
con.close();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
//添加数据
public static void insertData(String sql){
//2.注册驱动
try {
//Class.forName(DRIVER);
//3.获取链接
//4.准备sql语句 id username balance double
//String sql="insert into account values(null,'王五',10)";
//5.获取执行sql执行对象
//Statement statement = con.createStatement();
//6.执行sql语句 把sql发送给服务器
int count = ct.executeUpdate(sql);
if(count>0) {
System.out.println("数据插入成功!");
}else {
System.out.println("数据插入失败!");
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
try {
ct.close();
con.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
表与类的关系
整个表可以看做成一个类
表的每一行称之为一条记录,可以看作一个类的实例
表中的每一列可以看做还成实例对象中的每个属性值。
实体类、model类需要和数据库中的类进行一一映射
表中的列名和model类的属性名保持一致
表中的列字段数据类型和model类中的属性数据类型保持一致
操作:数据库java31 中的表account