连接查询
交叉连接、笛卡尔积
将两张表中的数据两两组合,得到的结果就是交叉连接的结果,也称为笛卡尔积
集合A:{a,b}
集合B:{1,2,3}
集合A x 集合B={a1,a2,a3,b1,b2,b3}
select * from 表1,表2;
select * from 表1 cross join 表2;
select * from 表1 inner join 表2;
将两张表中的数据互相组合成一张新表,其中有很多无效数据。
内连接
select * from 表1,表2 where 表1.字段=表2.字段;
select * from 表1 inner join 表2 on 表1.字段=表2.字段;
-- 如查询图书类型表(类型编号、类型名称)和图书详情表(图书编号、类型编号、图书名称)
select * from 图书类型表 t1 ,图书详情表 t2 where t1.类型编号=t2.类型编号;
select * from 图书类型表 t1 inner join 图书详情表 t2 on t1.类型编号=t2.类型编号;
- 通常是通过主表的主键字段关联从表的外键字段
- 如果两张表中关联的字段名一致,一定要通过"表名.字段名"进行区分,通常给表重命名
- 如果使用inner join,带条件时需要加入where子句;如果使用,隔开各个表,带条件时使用and拼接条件
- 内连接只会显示两张表中有关联的数据
左连接
-- 在保证左表数据显示完整的情况下,关联右表中的数据,没有关联的数据用null表示
select * from 表1 left join 表2 on 表1.字段=表2.字段;
-- 以上语句中表1称为左表,表2称为右表,会完整显示表1中的数据
右连接
-- 在保证右表数据显示完整的情况下,关联左表中的数据,没有关联的数据用null表示
select * from 表2 right join 表1 on 表1.字段=表2.字段;
-- 以上语句中表1称为左表,表2称为右表,会完整显示表2中的数据
嵌套查询
将查询出的结果继续嵌套使用在另一个查询语句中
-- 查询大于平均价格的图书
select * from 表
where price >(select avg(price) from 表)
-- 根据作者分组,查询每组大于平均价格的图书
select *
from 表 t1,(select author,avg(price) avg_price from 表)t2
where t1.author=t2.author and price>avg_price
Jar
以.jar为后缀的文件,称为Java归档文件,保存的是Java的字节码.class文件。
在Java程序中导入某个.jar文件,就能使用其中的.class文件。
在Java项目中使用.jar文件
1.创建一个Java项目,最好新建一个文件夹,将.jar文件保存在其中
2.在.jar文件上右键,点击“add as library”
JDBC
Java Database Connectivity Java数据库连接
用于Java程序连接不同的数据库。
实际在Java中定义的相关数据库连接时所需的接口,不同的数据库对其进行了实现。
核心接口
- Connection:用于设置连接的数据库的地址、账号、密码
- PreparedStatement:用于预处理、执行sql语句
- ResultSet:用于接收查询后的数据
以上接口都来自于java.sql包中
数据查询
import java.sql.*;
public class JDBCTest {
public static void main(String[] args) throws SQLException, ClassNotFoundException {
//连接mysql数据库,实现查询功能
//连接对象
//Connection conn;
//sql预处理对象
//PreparedStatement pst;
//结果集对象
//ResultSet rs;
//查询的流程
//1.加载mysql驱动
Class.forName("com.mysql.cj.jdbc.Driver");
//2.连接指定的mysql
String url="jdbc:mysql://localhost:3306/gamedb?serverTimezone=Asia/Shanghai";
String username="root";
String password="root";
Connection conn=DriverManager.getConnection(url,username,password);
//3.构造sql语句
String sql="select * from hero";
//4.预处理sql语句
PreparedStatement pst=conn.prepareStatement(sql);
//5.执行查询的方法
ResultSet rs =pst.executeQuery();
//6.循环读取数据
while(rs.next()){//rs.next()方便表示读取且判断是否还有后续数据
//获取读取到的数据 rs.get数据类型(int columnIndex)根据字段索引获取值 rs.get数据类型(String columnName)根据字段名获取值
int id = rs.getInt(1);
String name = rs.getString("name");
String sex = rs.getString("sex");
String position = rs.getString("position");
int price = rs.getInt("price");
String shelf_date = rs.getString(6);
System.out.println(id+"--"+name+"--"+sex+"--"+position+"--"+price+"--"+shelf_date);
}
//7.释放与mysql的连接资源
rs.close();
pst.close();
conn.close();
}
}
数据增删改
public void addHero(Hero hero) throws SQLException, ClassNotFoundException {
//1.加载驱动
Class.forName("com.mysql.cj.jdbc.Driver");
//2.获取连接对象
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/gamedb?serverTimezone=Asia/Shanghai", "root", "root");
//3.构造sql,参数使用?占位
String sql = "insert into hero values(null,?,?,?,?,curdate())";
//4.预处理sql
pst = conn.prepareStatement(sql);
//给?赋值
pst.setString(1,hero.getName());
pst.setString(2,hero.getPosition());
pst.setString(3,hero.getSex());
pst.setInt(4,hero.getPrice());
//5.调用更新的方法
int i = pst.executeUpdate();
//6.判断执行结果
if(i>0){
System.out.println("添加成功");
}else{
System.out.println("添加失败");
}
//7.释放资源
pst.close();
conn.close();
}
SQL注入
在构造sql语句时,如果使用字符串拼接的方式构造动态sql,可能会造成sql注入的风险,导致执行不是预期的sql语句
-- 如删除的sql:String sql = "delete from 表 where id="+参数;
-- 实际传值时,参数为 ''or 1=1 会导致sql变成
delete from battle where id= ''or 1=1
-- 这样就会删除所有数据
-- 查询时的sql: "select * from 表 where name="+参数+" and pwd= "+参数
-- 实际传值时,第一个参数为 'or 1=1 -- 会导致sql变成
select * from hero where id=''or 1=1 -- ' and name='亚索'
-- 这样会查询出所有数据
使用数据库帮助类简化JDBC操作
DBUtil类
package com.hqyj.util;
import java.sql.*;
/*
* 数据库工具类
* 连接方法
* 释放资源方法
* */
public class DBUtil {
//连接数据库所需字符串
private static String url = "jdbc:mysql://localhost:3306/bookdb?serverTimezone=Asia/Shanghai";
private static String username = "root";
private static String password = "root";
/*
* 静态代码块
* 加载驱动
* */
static {
try {
Class.forName("com.mysql.cj.jdbc.Driver");
} catch (ClassNotFoundException e) {
System.out.println("加载驱动异常" + e);
}
}
/*
* 静态方法
* 获取连接
* */
public static Connection getConn() {
Connection connection = null;
try {
connection = DriverManager.getConnection(url, username, password);
} catch (SQLException e) {
System.out.println("连接数据库异常" + e);
}
return connection;
}
/*
* 静态方法
* 释放资源
* */
public static void release(Connection conn, PreparedStatement pst, ResultSet rs) {
try {
if(conn!=null){
conn.close();
}
if(pst!=null){
pst.close();
}
if(rs!=null){
rs.close();
}
}catch (SQLException e){
System.out.println("释放资源异常"+e);
}
}
}
实体类BookInfo
package com.hqyj.entity;
/*
* book_info表对应的实体类
* */
public class BookInfo {
private int bookId;
private String bookName;
private String bookAuthor;
private int bookPrice;
private int bookNum;
private String publisherDate;
/*
* 全参数构造方法
* 用于查询时创建对象
* */
public BookInfo(int bookId, String bookName, String bookAuthor, int bookPrice, int bookNum, String publisherDate) {
this.bookId = bookId;
this.bookName = bookName;
this.bookAuthor = bookAuthor;
this.bookPrice = bookPrice;
this.bookNum = bookNum;
this.publisherDate = publisherDate;
}
/*
* 不含id和出版时间的构造方法
* 用于添加时创建对象
* */
public BookInfo(String bookName, String bookAuthor, int bookPrice, int bookNum) {
this.bookName = bookName;
this.bookAuthor = bookAuthor;
this.bookPrice = bookPrice;
this.bookNum = bookNum;
}
@Override
public String toString() {
return "BookInfo{" +
"bookId=" + bookId +
", bookName='" + bookName + '\'' +
", bookAuthor='" + bookAuthor + '\'' +
", bookPrice=" + bookPrice +
", bookNum=" + bookNum +
", publisherDate='" + publisherDate + '\'' +
'}';
}
public int getBookId() {
return bookId;
}
public void setBookId(int bookId) {
this.bookId = bookId;
}
public String getBookName() {
return bookName;
}
public void setBookName(String bookName) {
this.bookName = bookName;
}
public String getBookAuthor() {
return bookAuthor;
}
public void setBookAuthor(String bookAuthor) {
this.bookAuthor = bookAuthor;
}
public int getBookPrice() {
return bookPrice;
}
public void setBookPrice(int bookPrice) {
this.bookPrice = bookPrice;
}
public int getBookNum() {
return bookNum;
}
public void setBookNum(int bookNum) {
this.bookNum = bookNum;
}
public String getPublisherDate() {
return publisherDate;
}
public void setPublisherDate(String publisherDate) {
this.publisherDate = publisherDate;
}
}
数据操作类BookInfoDao
package com.hqyj.dao;
import com.hqyj.entity.BookInfo;
import com.hqyj.util.DBUtil;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
/*
* book_info表的操作类
* */
public class BookInfoDao {
//定义成员变量,用于操作数据库的3个接口
Connection conn;
PreparedStatement pst;
ResultSet rs;
/*
* 查询所有
* */
public List<BookInfo> queryAll() {
//创建集合
ArrayList<BookInfo> list = new ArrayList<>();
try {
//通过数据库工具类获取连接
conn = DBUtil.getConn();
//预处理sql
pst = conn.prepareStatement("select * from book_info");
//调用查询
rs = pst.executeQuery();
//遍历结果集
while (rs.next()) {
int id = rs.getInt(1);
String name = rs.getString(3);
String author = rs.getString(4);
int price = rs.getInt(5);
int num = rs.getInt(6);
String time = rs.getString(7);
BookInfo bookInfo = new BookInfo(id, name, author, price, num, time);
list.add(bookInfo);
}
} catch (Exception e) {
System.out.println("查询所有异常" + e);
} finally {
DBUtil.release(conn, pst, rs);
}
return list;
}
/*
* 根据id查询
* */
public BookInfo queryById(int bookId) {
try {
//通过数据库工具类获取连接
conn = DBUtil.getConn();
//预处理sql
pst = conn.prepareStatement("select * from book_info where book_id=?");
//给?赋值
pst.setInt(1, bookId);
//调用查询
rs = pst.executeQuery();
//遍历结果集
if (rs.next()) {
String name = rs.getString(3);
String author = rs.getString(4);
int price = rs.getInt(5);
int num = rs.getInt(6);
String time = rs.getString(7);
BookInfo bookInfo = new BookInfo(bookId, name, author, price, num, time);
return bookInfo;
}
} catch (Exception e) {
System.out.println("根据id查询异常" + e);
} finally {
DBUtil.release(conn, pst, rs);
}
return null;
}
/*
* 添加
* */
public boolean insert(BookInfo bookInfo) {
conn = DBUtil.getConn();
try {
pst = conn.prepareStatement("insert into book_info values(null,1,?,?,?,?,curdate())");
pst.setString(1, bookInfo.getBookName());
pst.setString(2, bookInfo.getBookAuthor());
pst.setInt(3, bookInfo.getBookPrice());
pst.setInt(4, bookInfo.getBookNum());
return pst.executeUpdate() > 0;
} catch (SQLException e) {
System.out.println("添加异常" + e);
} finally {
DBUtil.release(conn, pst, rs);
}
return false;
}
/*
* 修改
* */
public boolean update(int bookId, int newPrice, int newNum) {
conn = DBUtil.getConn();
try {
pst = conn.prepareStatement("update book_info set book_price=? ,book_num=? where book_id=?");
pst.setInt(1, newPrice);
pst.setInt(2, newNum);
pst.setInt(3, bookId);
return pst.executeUpdate() > 0;
} catch (Exception e) {
System.out.println("修改异常" + e);
} finally {
DBUtil.release(conn, pst, rs);
}
return false;
}
/*
* 删除
* */
public boolean delete(int bookId) {
conn = DBUtil.getConn();
try {
pst = conn.prepareStatement("delete from book_info where book_id=?");
pst.setInt(1, bookId);
return pst.executeUpdate() > 0;
} catch (Exception e) {
System.out.println("删除异常" + e);
} finally {
DBUtil.release(conn, pst, rs);
}
return false;
}
}
, rs);
}
return false;
}
/*
* 删除
* */
public boolean delete(int bookId) {
conn = DBUtil.getConn();
try {
pst = conn.prepareStatement("delete from book_info where book_id=?");
pst.setInt(1, bookId);
return pst.executeUpdate() > 0;
} catch (Exception e) {
System.out.println("删除异常" + e);
} finally {
DBUtil.release(conn, pst, rs);
}
return false;
}
}