JDBC 使用以及注意问题

时间:2022-01-05 15:00:36

         今天我来说一下MySql 中jdbc 的使用以及一些需要注意的问题,通常使用JDBC的时候,是使用以

  下代码来进行数据库的连接和查询的:

public static void main(String[] args) throws Exception {
String url = "jdbc:mysql://127.0.0.1:3306/mydb";
String user = "root" ;
String password = "root";
//加载驱动器
 Class.forName("com.mysql.jdbc.Driver");
Connection conn = DriverManager.getConnection(url, user, password);
Statement stat = conn.createStatement();
String sql = "select * from students";
ResultSet rs = stat.executeQuery(sql);
while(rs.next()){
String id = rs.getString("id");
String name = rs.getString("name");
String chinese = rs.getString("chinese");
String math = rs.getString("english");
String english = rs.getString("math");
System.out.println(id+"."+name+"."+chinese+"."+math+"."+english);
}
rs.close();
conn.close();
stat.close();
}
}

首先 用 Class.forName("com.mysql.jdbc.Driver") 来加载驱动,在 com.mysql.jdbc.Driver这个类里面

有一个静态代码块是加载驱动的:

                 JDBC 使用以及注意问题

利用Class.forName("com.mysql.jdbc.Driver")这句代码的意思就是让代码执行静态代码块中的

内容,该方式免去了导入包,和新建对象的操作。

通常statment 执行的是查询语句的话,就调用excuteQuery()方法

如果是增,删,该等操作的话,就调用excuteUpdate()方法

通常情况下,我们会把JDBC 的操作封装在一个JdbcUtil里面:



/**
* JDBC工具类
*/
public class JdbcUtil {
private JdbcUtil(){}
private static String driver;
private static String url;
private static String user;
private static String password;
/**
* 读取db.properties文件,只读一次,且越早读越好
*/
static{
try {
InputStream is = JdbcUtil.class.getClassLoader().
getResourceAsStream("db.properties");
Properties props = new Properties();
props.load(is);
driver = props.getProperty("mysql.driver").trim();
url = props.getProperty("mysql.url").trim();
user = props.getProperty("mysql.user").trim();
password = props.getProperty("mysql.password").trim();
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
/**
* 注册数据库驱动,只注册一次,且越早越好
*/
static{
try {
Class.forName(driver);
} catch (ClassNotFoundException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
/**
* 获取数据库连接
*/
public static Connection getConnection(){
try {
return DriverManager.getConnection(url,user,password);
} catch (SQLException e) {
e.printStackTrace();
//抛出运行时异常
throw new RuntimeException(e);
}
}
/**
* 关闭数据库连接---ResultSet
*/
public static void close(ResultSet rs){
if(rs!=null){
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
//抛出运行时异常
throw new RuntimeException(e);
}
}
}
/**
* 关闭数据库连接---Statement
* 1)普通:父类/接口在的地方,子类/接口都有使用
* 2)专业:Java多态
*/
public static void close(Statement stmt){
if(stmt!=null){
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
//抛出运行时异常
throw new RuntimeException(e);
}
}
}
/**
* 关闭数据库连接---Connection
*/
public static void close(Connection conn){
if(conn!=null){
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
//抛出运行时异常
throw new RuntimeException(e);
}
}
}
}

该类封装了从properties文件读取数据库连接信息,并且提供了获取连接,关闭连接对象等方法。


还有一点需要注意的问题是,sql注入问题,通常我们验证用户提交的表单数据的时候是通过验证

用户名和密码来完成的,这时候,如果用户输入 '  or true  or  '  这样的字符串的话,通过上面的方法

是完全可以从数据库中查询信息出来的,这个时候就会出现未知的错误。


这个原因产生是因为数据库没有自带检查这类问题的功能,而statment对象对于执行的sql 语句没有做

安全性检测,所以会有这个问题,解决这个问题的方法是: 使用PrepareStatment 对象,该对象可以在sql

语句中添加占位符,然后经过预编译之后,在传入参数,就会有检测功能,多说无益,下面请看代码:

                String sql = "select id,name,sal,hire from users where name=? and sal=?";
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
try{
conn = JdbcUtil.getConnection();
//创建具有预编译功能的PreparedStatement
pstmt = conn.prepareStatement(sql);
//为上述二个占位符设置值,从左向右依次编码为1,2,3,....
//参数一:表示编号
//参数二:表示实际值
//不光能够绑定?占位符,且能够做安全检查
pstmt.setString(1,name);
pstmt.setDouble(2,sal);
//执行SQL语句,并返回结果
rs = pstmt.executeQuery();
//判断
if(rs.next()){
System.out.println("登录成功");
}else{
System.out.println("登录失败");
}
}catch(Exception e){
e.printStackTrace();
throw new RuntimeException(e);
}finally{
JdbcUtil.close(rs);
JdbcUtil.close(pstmt);
JdbcUtil.close(conn);
}
}

我总结的JDBC知识基本上就是这些了,有些知识没有在这里说明的请不要喷。。。。。