持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第30天,点击查看活动详情
05、Mysql_JDBC
01.JDBC_Java程序和MySQL的关系:
1).Java程序跟其它MySQL客户端一样,就是一个"客户端",用于"封装SQL语句"并发送给MySQL服务器,
MySQL服务器会直接返回结果给我们的程序。
02.JDBC_驱动的概念:
由数据库厂商为每种编程语言提供的一个程序包。有两种语言组成:前端:所面向的编程语言;后端:数据库本身的语言。
它可以使各种编程语言直接访问本语言,就可以访问数据库软件,方便操作。
03.JDBC_JDBC的概念:
由SUN公司提出的Java连接数据库的规范,它规范了Java连接各种数据库所遵循的步骤和数据类型。它要求各数据库厂商的驱动
程序必须遵守这套规范,也需要Java程序员直接学习这套规范,这样可以使得Java程序员访问各种数据库都使用同样的步骤和数据类型。
JDBC物理上由一组类和接口组成,随JDK一起发放。
04.JDBC_JDBC的四个核心类:
1).DriverManager(类) : 驱动管理器。 用于连接数据库的"驱动程序",并通过驱动程序去连接数据库软件,向程序返回一个"连接通道(Connection对象)"。
2).Connection(接口) : "连接"对象。代表了程序和数据库之间的一个"连接通道"。
3).Statement(接口) : SQL执行器。用于执行SQL语句。
4).ResultSet(接口) : 结果集。当Statement执行"查询"语句时,会返回此对象。
05.JDBC_JDBC的开发步骤:
1).下载MySQL的Java驱动包,并复制到项目目录下,并添加到构建路径:
mysql-connector-java-5.1.37-bin.jar
2).开发步骤:
1.注册驱动
2.获取连接
3.获取SQL执行器
4.执行SQL,并获取结果集(查询)
5.解析结果集
6.关闭资源 // 关闭资源一定要按顺序关闭
//1.注册驱动 //反射加载 驱动类Class对象 Driver 到内存中,第二步用 由驱动管理器来用
Class.forName("com.mysql.jdbc.Driver");
//2.获取连接 // 第一个参数 http url 路径 getConnection找到第一步 Driver Class 对象,创建一个对象 负责把三个参数信息传给driver类,driver类负责连接数据库,连接数据库之后返回一个连接通道,所以getConnection方法有返回值,返回值是Connection接口的子类对象 ;driver 遵守Connection接口 协议,所以返回其子类对象;DriverManager是一个普通类,驱动管理器
Connection conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/hei70_day21db_1", "root", "123");
//3.获取SQL执行器 //Statement 是一个接口,
Statement stmt = conn.createStatement();
//4.执行SQL,并获取结果集(查询)
String sql = "select * from product";
ResultSet rs = stmt.executeQuery(sql);
//5.解析结果集
06.JDBC_关于Statement的常用方法:
1).public int executeUpdate(String sql):用于执行添加(insert)、修改(update)、删除(delete)语句的。
返回值:int,影响的行数
2).public ResultSet executeQuery(String sql):用于执行查询(select)
返回值:ResultSet结果集。
public boolean execute(String sql); // 返回值 boolean 值 好像建表成功也返回false 好像所有sql语句都能执行
注意:两种不能混用。不能用executeUpdate()执行查询语句,反之也不可以。
07.JDBC_关于ResultSet的使用:
1).ResultSet就类似于之前的"迭代器"
迭代器:while(it.hasNext()) 结果集:while(rs.next())
it.next(); rs.get数据类型(String 列名)
或者
rs.get数据类型(int 列索引)
大招:
rs.getObject(String 列名) //不知道字段什么类型
rs.getObject(int 列索引) // 可以填字段名,也可以填 第几个字段 比如 1 2 3 第一个字段为 1
while(rs.next()){
System.out.println(rs.getInt("id")+"\t"+
rs.getString("name")+"\t"+
rs.getInt("age"));
}
08.JDBC_使用JDBC实现增删改查:
09.JDBC_JDBC工具类的制作:
public class JDBCUtils {
//1.获取Connection对象--代码重用的目的
public static Connection getConnection() throws Exception{
Class.forName("com.mysql.jdbc.Driver");
Connection conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/hei70_day21db_1","root","123");
return conn;
}
//2.关闭资源 // 关闭资源要按顺序依次关闭
public static void closeAll(ResultSet rs,Statement stmt,Connection conn) throws SQLException{
if(rs != null){
rs.close();
}
if(stmt != null){
stmt.close();
}
if(conn != null){
conn.close();
}
}
}
10.JDBC_SQL语句的封装:
public class Demo {
public static void main(String[] args) throws Exception {
Scanner sc = new Scanner(System.in);
System.out.println("请输入商品名称:");
String pname = sc.next();//海尔冰柜
System.out.println("价格:");
int price = sc.nextInt();//2300
System.out.println("类别ID:");
int cid = sc.nextInt();//1
//1.获取连接对象
Connection conn = JDBCUtils.getConnection();
//2.获取SQL执行器
Statement stmt = conn.createStatement();
//3.【封装SQL语句】 // SQL 语句的拼接
//先想象,封装后的SQL语句:"insert into product values(null,'海尔冰柜',2300,1)"
String sql = "insert into product values(null,'" + pname +
"'," + price + "," +
cid + ")";
System.out.println(sql);
//4.执行SQL语句
int row = stmt.executeUpdate(sql);
System.out.println("添加影响的行数:" + row);
//5.释放资源
JDBCUtils.closeAll(null, stmt, conn);
}
}
11.JDBC_关于SQL注入的问题:
1).什么是SQL注入:是指在用户的数据中,包含了一些SQL的格式化符号,例如:)或者(或者,或者',如果程序接收后,不加以判断直接封装到SQL语句中会导致SQL语句的错误。这种现象就叫:SQL注入。
2).SQL注入的登录演示:
Scanner sc = new Scanner(System.in);
System.out.println("请输入登录名:");
String loginName = sc.nextLine();//jfdks
System.out.println("输入密码:");
String loginPwd = sc.nextLine();//jfdjfd' or '1=1
//1.获取连接对象
Connection conn = JDBCUtils.getConnection();
Statement stmt = conn.createStatement();
String sql = "select * from users where uname = '" + loginName +
"' and password = '" + loginPwd + "'";
System.out.println(sql);
ResultSet rs = stmt.executeQuery(sql);
if(rs.next()){
System.out.println("欢迎:" + loginName + " 登录系统!");
}else{
System.out.println("用户名或密码错误!!");
}
//2.释放资源
JDBCUtils.closeAll(rs, stmt, conn);
3).怎样解决SQL注入的问题:
3).怎样解决SQL注入的问题:
不用Statement,改用它的子接口:PreparedStatement--预处理的SQL执行器
PreparedStatement:它可以严格的区分出"SQL语句"和"数据",不会将数据中的SQL的格式化符号解析为SQL格式化符号,而认为就是数据。
12.JDBC_使用PreparedStatement解决SQL注入的问题:
Scanner sc = new Scanner(System.in);
System.out.println("请输入登录名:");
String loginName = sc.nextLine();
System.out.println("输入密码:");
String loginPwd = sc.nextLine();
Connection conn = JDBCUtils.getConnection();
//1.先封装SQL语句,数据部分要用?号占位,任何数据类型不需要单引号
String sql = "select * from users where uname = ? and password = ?"; / /如果拼接字符串的话会报错
//2.获取PreparedStatemet对象
PreparedStatement ps = conn.prepareStatement(sql);
//3.填充数据 // 第一个 问号 是 1 不是 0
ps.setString(1, loginName);
ps.setString(2, loginPwd);
//4.执行
ResultSet rs = ps.executeQuery();//注意:不要再传SQL语句了,因为之前已经有SQL语句了
if(rs.next()){
System.out.println("欢迎:" + loginName + " 登录系统!");
}else{
System.out.println("用户名或密码错误!!");
}
//2.释放资源
JDBCUtils.closeAll(rs, ps, conn);
13.JDBC_使用PreparedStatement完成增删改查(CRUD)
public void add() throws Exception{
//1.获取连接对象
Connection conn = JDBCUtils.getConnection();
//2.获取预处理对象
String sql = "insert into product values(null,?,?,?)";
PreparedStatement ps = conn.prepareStatement(sql);
//3.填充数据
ps.setString(1, "奔驰");
ps.setInt(2, 440000);
ps.setInt(3, 1);
//4.执行SQL
int row = ps.executeUpdate();
System.out.println("添加影响的行数:" + row);
//5.释放资源
JDBCUtils.closeAll(null, ps, conn);
}
public void update() throws Exception{
//1.获取连接对象
Connection conn = JDBCUtils.getConnection();
//2.获取预处理对象
String sql = "update product set pname = ? , price = ? where pid = ?";
PreparedStatement ps = conn.prepareStatement(sql);
//3.填充数据
ps.setString(1, "奔驰E级");
ps.setInt(2, 420000);
ps.setInt(3, 9);
//4.执行SQL
int row = ps.executeUpdate();
System.out.println("修改影响的行数:" + row);
//5.释放资源
JDBCUtils.closeAll(null, ps, conn);
}
public void delete() throws Exception{
Connection conn = JDBCUtils.getConnection();
String sql = "delete from product where pid = ?";
PreparedStatement ps = conn.prepareStatement(sql);
ps.setInt(1, 9);
int row = ps.executeUpdate();
System.out.println("删除影响的行数:" + row);
JDBCUtils.closeAll(null, ps, conn);
}
public void findAll() throws Exception{
Connection conn = JDBCUtils.getConnection();
String sql = "select * from product";
PreparedStatement ps = conn.prepareStatement(sql);
ResultSet rs = ps.executeQuery();
while(rs.next()){
System.out.println(rs.getInt("pid") + "\t" + rs.getString("pname") + "\t"
+ rs.getInt("price") + "\t" + rs.getInt("cid"));
}
JDBCUtils.closeAll(rs, ps, conn);
}
@Test
public void findById() throws Exception{
Connection conn = JDBCUtils.getConnection();
String sql = "select * from product where pid = ?";
PreparedStatement ps = conn.prepareStatement(sql);
ps.setInt(1, 1);
ResultSet rs = ps.executeQuery();
if(rs.next()){
System.out.println(rs.getInt("pid") + "\t" + rs.getString("pname") + "\t"
+ rs.getInt("price") + "\t" + rs.getInt("cid"));
}
JDBCUtils.closeAll(rs, ps, conn);
}