当前位置: 代码迷 >> 综合 >> MySQL---当Java遇上MySQL②---ResultSet 、Statement 、PreparedStatement
  详细解决方案

MySQL---当Java遇上MySQL②---ResultSet 、Statement 、PreparedStatement

热度:67   发布时间:2023-10-21 16:42:06.0

数据库连接工具类

  • 配置文件jdbc.properties  该文件存放在src目录下
##MySQL
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://127.0.0.1:3306/hncu?useUnicode=true&characterEncoding=utf-8
username=root
password=1234
  • 读取配置文件,并采用单例生成一个数据库连接对象。
package cn.hncu.utils;import java.sql.Connection;
import java.sql.DriverManager;
import java.util.Properties;/*** 产生数据库连接工具* CreateTime: 2018年9月17日 下午10:30:37	* @author 宋进宇  Email:447441478@qq.com*/
public class ConnUtil {private static Connection con;static {try {//创建Properties对象Properties p = new Properties();// 通过类加载器  加载配置文件p.load( ConnUtil.class.getClassLoader().getResourceAsStream( "jdbc.properties" ) );//获取配置信息String driver = p.getProperty("driver");String url = p.getProperty("url");String user = p.getProperty("username");String password = p.getProperty("password");//加载驱动Class.forName( driver );//获取连接con = DriverManager.getConnection(url, user, password);} catch (Exception e) {throw new RuntimeException( e.getMessage(), e);}}private ConnUtil() {}/*** 获取数据库了连接对象* @return 数据库连接对象*/public static Connection getConnection() {return con;}
}

在Java中实现跨库查询

很简单:给表名加个前缀,如 test.aa 就是 数据库test 中的表 aa

	@Testpublic void demo() throws Exception {Connection con = ConnUtil.getConnection();Statement st = con.createStatement();String sql = "select * from test.aa";st.executeQuery(sql);}

准备数据库

下面脚本是为下面演示所需的数据库和表还有一些数据。

CREATE DATABASE hncu CHARACTER SET utf8;
USE hncu;
CREATE TABLE tb_user(id INT PRIMARY KEY AUTO_INCREMENT,username VARCHAR(10),PASSWORD VARCHAR(10)
);INSERT INTO tb_user(username,PASSWORD) VALUES('jack','1234');
INSERT INTO tb_user(username,PASSWORD) VALUES('张三','333');
INSERT INTO tb_user(username,PASSWORD) VALUES('Alice','1111');

ResultSet中的几个常用getXXX()方法

	@Testpublic void demo1() throws Exception {Connection con = ConnUtil.getConnection();Statement st = con.createStatement();ResultSet resultSet = st.executeQuery(" select * from tb_user ");System.out.println( "id\t用户名\t密码" );while(resultSet.next()) {//方式1:通过字段名获取相应的数据int id = resultSet.getInt("id");//方式2:通过字段的顺序获取对应的数据(以1开始)String username = resultSet.getString(2);//方式3:通过getObject()获取数据类型未知的数据,参数同上面两种Object obj = resultSet.getObject(3);System.out.println( id+"\t"+username+"\t"+obj);}}

Statement的三种执行SQL语句的方法

第一种: Statement.execute(sql)

该方式通吃所有SQL语句,包括:增、删、改、查,通过 st.execute(sql)的返回值判断,执行的sql语句是属于“查询” 还是“增、删、改或其他”,true:查询 ,false:增、删、改或其他。

	@Testpublic void demo2_1() throws Exception {Connection con = ConnUtil.getConnection();Statement st = con.createStatement();String sql = "";//增//sql = " insert into tb_user(username,password) values('Rose','4321') ";//删//sql = " delete from tb_user where id = 4 ";//改//sql = " update tb_user set password='hncu' where username='张三' ";//查sql = " select * from tb_user ";boolean boo = st.execute(sql);if( boo ) {ResultSet resultSet = st.getResultSet();System.out.println( "id\t用户名\t密码" );while(resultSet.next()) {int id = resultSet.getInt("id");String username = resultSet.getString("username");String password = resultSet.getString("password");System.out.println( id+"\t"+username+"\t"+password);}}con.close();}

第二种: Statement.executeUpdate(sql)

该种方式只能执行 insert、delete、update,不能执行 select。

	@Testpublic void demo2_2() throws Exception {Connection con = ConnUtil.getConnection();Statement st = con.createStatement();String sql = "";//增sql = " insert into tb_user(username,password) values('Rose','4321') ";//删//sql = " delete from tb_user where id = 5 ";//改//sql = " update tb_user set password='hncu' where username='张三' ";int update = st.executeUpdate(sql); //返回值是执行后,影响表的行数System.out.println( update );con.close();}

第三种: Statement.executeQuery(sql)

该种方式只能执行 select,不能执行 insert、delete、update。

	@Testpublic void demo2_3() throws Exception {Connection con = ConnUtil.getConnection();Statement st = con.createStatement();String sql = " select * from tb_user ";ResultSet resultSet = st.executeQuery(sql);System.out.println( "id\t用户名\t密码" );while(resultSet.next()) {int id = resultSet.getInt("id");String username = resultSet.getString("username");String password = resultSet.getString("password");System.out.println( id+"\t"+username+"\t"+password);}con.close();}

模拟用户注册

存在BUG版本:用户名或密码出现 '字符就挂,如 aa'bb

	@Test //黑:用户名或密码出现 '字符就挂,如 aa'bbpublic void regDemo() throws Exception {Connection con = ConnUtil.getConnection();Statement st = con.createStatement();Scanner in = new Scanner( System.in );System.out.println("请输入用户名:");String username = in.nextLine();System.out.println("请输入密码:");String password = in.nextLine();in.close();//写死的sql语句//String sql = " insert into tb_user(username,password) values('Bob','666666')";//写活String sql = " insert into tb_user(username,password) values('"+username+"','"+password+"')";int update = st.executeUpdate(sql);if( update>0 ) {System.out.println("注册成功!!!");}con.close();}

模拟用户登录

存在BUG版本:密码出现  ' or '1'='1  就可以直接登录

	@Test //黑:' or '1'='1public void loginDemo() throws Exception {Connection con = ConnUtil.getConnection();Statement st = con.createStatement();Scanner in = new Scanner( System.in );System.out.println("请输入用户名:");String username = in.nextLine();System.out.println("请输入密码:");String password = in.nextLine();in.close();String sql = " select count(1) from tb_user where username='"+username+"' and password='"+password+"' " ;System.out.println(sql);ResultSet resultSet = st.executeQuery(sql);if( resultSet.next() ) {int i = resultSet.getInt(1);if( i > 0 ) {System.out.println("登录成功");}else {System.out.println("登录失败");}}con.close();}

无BUG版

由于使用Statement 会出现上述BUG 所以,这时候应该采用PreparedStatement类, 该对象可以通过'占位符'的方式,先预编译sql语句, 等接收到相应的数据时在通过 setxxx()来补充sql语句 ,最后再执行。

	@Test //防黑:' or '1'='1public void loginDemo2() throws Exception {Connection con = ConnUtil.getConnection();//使用'占位符':? 来代替真正的变化的数据的位置。String sql = " select count(1) from tb_user where username=? and password=?";PreparedStatement pst = con.prepareStatement(sql);//接收用户输入Scanner in = new Scanner( System.in );System.out.println("请输入用户名:");String username = in.nextLine();System.out.println("请输入密码:");String password = in.nextLine();in.close();//把用户输入的数据补充到原先占位符的位置,注意:从1开始。pst.setString(1, username); //该方法内部把敏感字符进行转义了。pst.setString(2, password);ResultSet resultSet = pst.executeQuery();if( resultSet.next() ) {int i = resultSet.getInt(1);if( i > 0 ) {System.out.println("登录成功");}else {System.out.println("登录失败");}}con.close();}

源码

源码链接

  相关解决方案