Java操作数据库基本原理
创始人
2024-05-30 10:30:55
0

- 四年前存稿

Java操作数据库基本原理


概述

全称Java Database Connectivity,Java的数据库连接,使用Java语言操作数据库,定义了操作所有关系型数据库规则(接口)

使用步骤

我的mysql是8版本的,使用jar包时必须使用8版本的,如果驱动jar包跟mysql版本不一样,执行时会报错。且要把注册驱动改为com.mysql.cj.jdbc.Driver,在url那边也要修改,在表名后面加?useUnicode=true&characterEncoding=UTF-8&userSSL=false&serverTimezone=GMT%2B8。不然也报错。同时,mysql5之后的驱动jar包可以省略注册驱动的步骤
但是以下步骤是基础,真正使用的时候不用Statement对象(作了解),而是使用PreparedStatement对象,参照后面使用PreparedStatement ,能防止SQL注入问题,安全性更高,效率也更高。

 public static void main(String[] args) throws Exception {//1.导入驱动jar包//2.注册驱动,这里可以注释掉不需要。Class.forName("com.mysql.cj.jdbc.Driver");//3.获取数据库连接对象Connection conn =  DriverManager.getConnection("jdbc:mysql://localhost:3306/db3?useUnicode=true&characterEncoding=UTF-8&userSSL=false&serverTimezone=GMT%2B8","root","888888");//4.定义一个sql语句String sql = "update account set balance = 500 where id = 1";//5.获取执行sql对象Statement stmt = conn.createStatement();//6.执行sql,返回影响行数int count = stmt.executeUpdate(sql);//7.打印结果System.out.println(count);//8.释放资源stmt.close();conn.close();}

JDBC各个类详解

DriverManager - - 驱动管理对象
①注册驱动:告知程序该使用哪一个数据库驱动jar包

 //2.注册驱动,mysql5之后驱动jar包可以省略注册驱动,即这里可以注释掉不需要
Class.forName("com.mysql.cj.jdbc.Driver");

②获取数据库连接:
static Connection getConnection(String url,String user,String password)
url — 指定的连接路径
语法 — jdbc:mysql://ip地址(域名):端口号/数据库名称
例如 —"jdbc:mysql://localhost:3306/db3?useUnicode=true&characterEncoding=UTF-8&userSSL=false&serverTimezone=GMT%2B8"
其中,若mysql连接的是本地的mysql服务器,并且mysql默认服务端口号是3306,则url可以简写为"jdbc:mysql:///db3?useUnicode=true&characterEncoding=UTF-8&userSSL=false&serverTimezone=GMT%2B8"(即省略ip地址和端口号:jdbc:mysql:///数据库名称)
user — 用户名
passwor — 密码

 //3.获取数据库连接对象
Connection conn =  DriverManager.getConnection("jdbc:mysql://localhost:3306/db3?useUnicode=true&characterEncoding=UTF-8&userSSL=false&serverTimezone=GMT%2B8","root","888888");

Connection - - - 数据库连接对象
①获取执行的sql对象
②管理事务
setAutoCommit(boolean autoCommit) – 开启事务
commit() - - 提交事务
rollback() - - 回滚事务


Statement - - - 执行sql对象
①执行sql语句
int executeUpdate(String sql) - - 执行DML(insert、update、delete)、DDL(create、alter、drop)
ResultSet executeQuery(String sql) - - 执行DQL(select)语句

执行insert语句测试.java

public static void main(String[] args) {Statement stmt = null;Connection conn = null;try{//1.注册驱动Class.forName("com.mysql.cj.jdbc.Driver");//2.定义sqlString sql = "insert into account values(null,'monkey',3000)";//3.获取Connection对象conn = DriverManager.getConnection("jdbc:mysql:///db3?useUnicode=true&characterEncoding=UTF-8&userSSL=false&serverTimezone=GMT%2B8","root","888888");//4.获取执行sql的对象 Statementstmt = conn.createStatement();//5.执行sqlint count = stmt.executeUpdate(sql);//影响行数,若是ddl语句,count返回0//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();}finally {//7.释放资源//释放顺序应该是先stmt再是conn,但是看看try语快里面的执行顺序,很容易造成空指针异常if (stmt != null){try{stmt.close();}catch (SQLException e){e.printStackTrace();}}if (conn != null){try{conn.close();}catch (SQLException e){e.printStackTrace();}}}}

ResultSet查询指定的数据.java

public static void main(String[] args) {Statement stmt = null;Connection conn = null;ResultSet res = null;try{//1.注册驱动Class.forName("com.mysql.cj.jdbc.Driver");//2.定义sqlString sql = "select * from account";//3.获取Connection对象conn = DriverManager.getConnection("jdbc:mysql:///db3?useUnicode=true&characterEncoding=UTF-8&userSSL=false&serverTimezone=GMT%2B8","root","888888");//4.获取执行sql的对象 Statementstmt = conn.createStatement();//5.执行sqlres = stmt.executeQuery(sql);//影响行数,若是ddl语句,count返回0//6.处理结果while (res.next()){int id =  res.getInt(1);String name = res.getString("name");double balance = res.getDouble(3);System.out.println(id);System.out.println(name);System.out.println(balance);}/*  打印第二行数据,默认数据游标最初指向第一行的列名行res.next();int id =  res.getInt(1);String name = res.getString("name");double balance = res.getDouble(3);System.out.println(id);System.out.println(name);System.out.println(balance);*/}catch (ClassNotFoundException e){e.printStackTrace();} catch (SQLException e) {e.printStackTrace();}finally {//7.释放资源//释放顺序应该是先stmt再是conn,但是看看try语快里面的执行顺序,很容易造成空指针异常if (res != null){try{res.close();}catch (SQLException e){e.printStackTrace();}}if (stmt != null){try{stmt.close();}catch (SQLException e){e.printStackTrace();}}if (conn != null){try{conn.close();}catch (SQLException e){e.printStackTrace();}}}}

ResultSet - - - 结果集对象,封装查询结果
boolean next() - - 向下移动一行,判断是否有数据(末尾行),true为有,false没有
getXxx([可选参数]) - - 获取数据(Xxx代表数据类型),如int getInt()、String getString();可选参数int型代表列数编号如getString(1),可选参数String代表列名名称,getDouble(“price”)

/*
循环读取表中的数据
游标默认初始执向列名的一行,使用next()方法时向下移动一次
如果有数据返回true,没有返回false
类似于迭代器
*/
while(rs.next()){int id = rs.getInt(1);String name = rs.getString("name");double balance = rs.getDouble(3);
}

PreparedStatement - - - 预编译执行sql对象,提高安全性
SQL注入问题 - - 在拼接sql时,有一些特殊关键字参与字符串拼接,造成安全性问题
解决SQL注入问题 - - 使用PreparedStatement对象解决
预编译的SQL - -参数使用?作为占位符
eg:select * from user where username=? and password=?
使用步骤如下,效率更加高,且能防止SQL注入问题,怎么改参见下面登录案例的代码

1.导入驱动包
2.注册驱动
3.获取数据库连接对象 Connection
4.定义sql,eg: select * from user where username=? and password=?
5.获取sql语句对象,Connection.preparedStatement(String sql)
6.给占位符 ? 赋值:setXxx(参数1,参数2)- - 参数1代表?的位置标号,从1开始,参数2代表?的值
7.执行sql,返回结果,不需要传递sql语句
8.处理结果
9.释放资源
 Connection conn = null;PreparedStatement pstmt = null;ResultSet rs = null;//连接数据检验是否正确try {//1.获取数据库连接conn = JDBCUtils.getConnection();//2.定义sqlString sql = "select * from user where xxx1= ? and xxx2=?";//3.获取执行sql的对象,预编译pstmt = conn.prepareStatement(sql);//4.给?赋值pstmt.setString(1,xxx1);pstmt.setString(2,xxx2);//5.执行查询rs = pstmt.executeQuery();//这里不需要传参//6.处理结果} catch (SQLException e) {e.printStackTrace();}finally {JDBCUtils.close(rs,pstmt,conn);}


JDBCUtils工具类

抽取JDBC工具类JDBCUtils,因为每次都要写JDBC的步骤(看上面的代码,每次写都要捕捉异常,判断,代码重复太高),为了方便所以来抽取一个工具类,拿来公用

创建在src文件下的配置文件jdbc.properties

url = jdbc:mysql:///db3?useUnicode=true&characterEncoding=UTF-8&userSSL=false&serverTimezone=GMT%2B8
user = root
password = 888888
driver = com.mysql.cj.jdbc.Driver

JDBCUtils.java

import java.io.FileReader;
import java.io.IOException;
import java.sql.*;
import java.util.Properties;/*JDBC工具类*/
public class JDBCUtils {private static String url;private  static String user;private static  String password;private static  String driver;//静态代码块,只会执行一次static {//读取资源,获取值//1.创建Properties集合类Properties pro = new Properties();try {//2.加载文件pro.load(new FileReader("src/jdbc.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);}/*** 释放资源* @param rs* @param stmt* @param coon*/public static void close(ResultSet rs,Statement stmt, Connection coon){if (rs != null){try{rs.close();}catch (SQLException e){e.printStackTrace();}}if (stmt != null){try{stmt.close();}catch (SQLException e){e.printStackTrace();}}if (coon != null){try{coon.close();}catch (SQLException e){e.printStackTrace();}}}/*重写函数,参数个数不同*/public static void close(Statement stmt, Connection coon){if (stmt != null){try{stmt.close();}catch (SQLException e){e.printStackTrace();}}if (coon != null){try{coon.close();}catch (SQLException e){e.printStackTrace();}}}
}


实例 - - 登录

1.通过键盘录入用户名和密码
2.判断用户是否登录成功

在这里插入图片描述
使用到的JDBCUtils类参照上面工具类代码,配置文件根据自己情况修改
代码.java

public class jdbcDemo7 {/*** 登录函数*/public  boolean login(String username,String password){if (username == null && password == null){return false;}Connection conn = null;PreparedStatement pstmt = null;//Statement stmt = null;ResultSet rs = null;//连接数据检验是否正确try {//1.获取数据库连接conn = JDBCUtils.getConnection();//2.定义sqlString sql = "select * from user where username= ? and password=?";//3.获取执行sql的对象,预编译pstmt = conn.prepareStatement(sql);// stmt = conn.createStatement();//4.给?赋值pstmt.setString(1,username);pstmt.setString(2,password);//5.执行查询rs = pstmt.executeQuery();//这里不需要传参// rs = stmt.executeQuery(sql);return rs.next();} catch (SQLException e) {e.printStackTrace();}finally {JDBCUtils.close(rs,pstmt,conn);}return false;}/*测试*/public static void main(String[] args) {Scanner sc = new Scanner(System.in);System.out.print("请输入用户名:");String username = sc.nextLine();System.out.print("请输入密码:");String password = sc.next();// boolean flag = login(username,password);//直接调用静态方法staticboolean flag = new jdbcDemo7().login(username,password);//非静态方法用这种方式访问if(flag){System.out.println("登录成功");}else{System.out.println("用户名或密码错误");}}
}

相关内容

热门资讯

六月二十七日望湖楼醉书 这首诗... 六月二十七日望湖楼醉书 这首诗的写作结构是怎样的?雨前:黑云到入船。雨停:第三句。雨后:最后一句
如果我带着醉意出生,或许我会忘... 如果我带着醉意出生,或许我会忘掉所有的哀伤,这是哪本书上的句子《八百万种死法》,最近电视剧无懈可击之...
优美动人怎么造句孑 优美动人怎么造句孑她的舞姿优美动人,真是让人难以忘怀!
在科学上没有平坦的大道,只有不... 在科学上没有平坦的大道,只有不畏艰险沿着陡峭山路攀登的人,才有希望达到光辉的顶点。这句话的意思。这句...
有什么好看的网王小说?要完结的 有什么好看的网王小说?要完结的四叶三叶草,我的幸福《网王守望幸福《网王——今生无忧》(《夏之纪年》《...
郭达换大米剧本谁写的 郭达换大米剧本谁写的换大米的作者是 郭达和蔡明
园林绿化公司怎么起名 园林绿化公司怎么起名我们是做园林绿化设计、施工管理的自然世界园林绿化公司,新鲜空气园林绿化公司,超时...
命运石之门,谁发信对主人公说你... 命运石之门,谁发信对主人公说你知道的太多了FB指示萌郁发送的(官方资料设定集里写了)FB即是楼下的显...
有关超市开业播放的音乐 有关超市开业播放的音乐请各位关注本问题的大侠们,帮我找一下超市、商场开业时用到的喜庆音乐!谢谢,有追...
现代人物人物苦学成才的故事 现代人物人物苦学成才的故事现代人物人物苦学成才的故事 张恨水先生是我国著名的现代作家。17岁时,他...
是惊的成语,以惊字结尾的成语,... 是惊的成语,以惊字结尾的成语,惊字在后面的成语 第四个字是惊的成语详细〔 胆颤心惊 〕颤:发抖。形...
判断一个女人对你“欲擒故纵”,... 判断一个女人对你“欲擒故纵”,还是“压根没戏”,关键看哪几点?首先知竖,对方给你回消息的语气。如历芹...
自己写的儿童诗 自己写的儿童诗有什么可以帮你的追问:我要自己写的儿童诗,谢谢了!追答:主要是我都不知道有什么要求啊追...
地下城堡2聚火之心有用吗 地下城堡2聚火之心有用吗有用。《地下城堡2:黑暗觉醒》是一款模拟经营与地牢探险游戏高贺轿。游戏中聚火...
在学校如何和老师斗智斗勇 在学校如何和老师斗智斗勇 老师说上课是对牛弹琴时,作为学生的我们应该感到高兴,因为老师说的是事实啊...
神级龙卫男主和谁在一起 神级龙卫男主和谁在一起你好。神级龙卫男主沈浪跟女主白倾雨,苏若雪,柳潇潇最终走到一起了。让我们来看看...
开学以来作文520初中 开学以来作文520初中初一的感觉 似水流年,今天的我们已不再是在草地里玩过家家的小朋友;今天的我们已...
家有黄仙能养两只猫吗 家有黄仙能养两只猫吗可以养的,不犯冲突,猫捉老鼠是老鼠的天敌,养猫后家里的老鼠会少很多。
失忆后的人会不会有恐惧和绝望的... 失忆后的人会不会有恐惧和绝望的心理?我是指那种完全忘记了自己的一切的人。失忆...如果真的全部忘记,...
胡萝卜长期保存方法 胡萝卜长期保存方法胡萝卜放保鲜袋里放冰箱可以放很长时间。