java JDBC 增删改查及封装
1、插入数据
package com;
import java.sql.*;
public class lxc {
public static void main(String[] args) {
// /useUnicode表示允许使用自定义的Unicode, //characterEncoding是给定自定义的Unicode是什么,解决乱码或问号的问题
String url = "jdbc:mysql://127.0.0.1:3306/java_pro?useUnicode=true&characterEncoding=utf8";
String user = "root";
String password = "lvxingchen@123";
Connection conne = null;
Statement sta = null;
try {
// 注册驱动
Class.forName("com.mysql.jdbc.Driver");
// 获取连接 - 连接mysql数据库
try {
conne = DriverManager.getConnection(url, user, password); // 获取连接对象
sta = conne.createStatement();// createStatement 专门执行sql语句的
String sql = "insert into user(name, age, address) values('吕星辰', 20, '烟台市')";
// 专门执行DML语句的,返回的是影响数据库的数据条数
int count = sta.executeUpdate(sql);
System.out.println(count == 1 ? "插入成功" : "插入失败");
} catch (SQLException throwables) {
throwables.printStackTrace();
} finally {
// 在finally中释放资源,并且按顺序依次关闭
try {
if(sta != null) {
sta.close();
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}
try {
if(conne != null) {
conne.close();
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
2、抽离全局配置
上边我们可以把全局的变量抽离出来,放在properties文件中:
项目目录
db.properties与com同级
db.properties
url=jdbc:mysql://127.0.0.1:3306/java_pro?useUnicode=true&characterEncoding=utf8
user=root
password=lvxingchen@123
driver=com.mysql.jdbc.Driver
在项目文件中引入通过ResourceBundle加载配置文件
package com;
import java.sql.*;
import java.util.ResourceBundle;
public class lxc {
public static void main(String[] args) {
ResourceBundle resourceBundle = ResourceBundle.getBundle("db");
String driver = resourceBundle.getString("driver");
String url = resourceBundle.getString("url");
String user = resourceBundle.getString("user");
String password = resourceBundle.getString("password");
Connection conne = null;
Statement sta = null;
try {
Class.forName(driver);
try {
conne = DriverManager.getConnection(url, user, password); // 获取连接对象
sta = conne.createStatement();// createStatement 专门执行sql语句的
String sql = "insert into user(name, age, address) values('吕星辰', 20, '烟台市')";
int count = sta.executeUpdate(sql);
System.out.println(count == 1 ? "插入成功" : "插入失败");
} catch (SQLException throwables) {
throwables.printStackTrace();
} finally {
try {
sta.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
try {
conne.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
3、java连接数据库封装(以mysql为例)
db.properties 配置文件
// db.properties
url=jdbc:mysql://127.0.0.1:3306/java_pro?useUnicode=true&characterEncoding=utf8
user=root
password=lvxingchen@123
driver=com.mysql.jdbc.Driver
封装JDBCutil.java文件,下边只是简单的封装,查询结果集直接拼接字符串打印的:
package com;
import java.sql.*;
import java.util.ResourceBundle;
/**
* @对外暴露的方法:
* (1)public void login(String name,String password) 账号密码登录
* (2)public void getAll() 获取数据
* (3)public void insert(String name,int age,String address,String password) 插入数据
*/
public class JDBCutil {
private final static String url;
private final static String user;
private final static String password;
public Connection driverManager = null; // 获取数据库连接对象
private static JDBCutil jdbc;
// 静态代码块注册驱动 - 在类加载的时候执行一次。
static {
ResourceBundle resourceBundle = ResourceBundle.getBundle("db");
String driver = resourceBundle.getString("driver");
url = resourceBundle.getString("url");
user = resourceBundle.getString("user");
password = resourceBundle.getString("password");
try {
Class.forName(driver); // 注册驱动
jdbc = new JDBCutil();
// jdbc.getConnection(); // 连接数据库,及获取数据库对象
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
// 子类会重写父类的main方法,所以父类main方法不会执行!
// public static void main(String[] args) {
// System.out.println("执行了+++++++++++++++++++++++");
// new com.B.JDBCutil().getConnection(); // 连接数据库
// }
// 获取数据库连接对象
private void getConnection() {
try {
jdbc.driverManager = DriverManager.getConnection(url, user, password);
} catch (SQLException throwables) {
throwables.printStackTrace();
System.out.println("连接失败");
}
System.out.println("****************************连接成功************************");
}
// 账号密码登录,成功返回true,失败返回false
public Boolean getOne(String name, String password) {
// Statement statement = null;
PreparedStatement statement = null; // PreparedStatement:预编译的数据库操作对象,可防止SQL注入
ResultSet resultSet = null;
boolean resStatus = false;
try {
System.out.println("jdbc.driverManager:"+jdbc.driverManager);
// 这地方在加一层判断,因为增删改查完之后,会关闭数据库连接
if(jdbc.driverManager == null) {
jdbc.getConnection();
}
/**
* 使用 Statement
* Statement statement = null; // SQL注入
* statement = jdbc.driverManager.createStatement(String sql)
* resultSet = statement.executeQuery();
*/
String sq = "select * from java_pro where name = ? and password = ?"; // 提前定义好SQL语句的框架 ?:表示占位符,单引号不能使用单引号括起来!
// 预编译上边的SQL语句
statement = jdbc.driverManager.prepareStatement(sq);
// 给占位符 ? 传值
// 第一个问号下标为1,第二个问号下标是2,以此类推
statement.setString(1, name);
statement.setString(2, password);
// 专门执行查询语句 executeQuery()
resultSet = statement.executeQuery(); // 返回的是一个查询结果集 - 结果集也需要关闭
// 遍历查询结果集:
// resultSet.next() 方法 - 让光标往下移动一行,如果走到的的这一行有数据,则返回true,
// 则把这一行数据分贝取出来即可;继续往下移动下一行;依次循环,如果没数据next() 方法会返回false,停止循环
boolean status = resultSet.next();
int count = 0;
System.out.println("***********************************************************");
if(status) {
resStatus = true;
}
System.out.println("***********************一共"+count+"条数据!************************");
} catch (SQLException throwables) {
throwables.printStackTrace();
}finally {
if(resultSet != null) {
try {
resultSet.close(); // 关闭结果集
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if(statement != null) {
try {
statement.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
// 关闭数据库连接
jdbc.close();
}
return resStatus;
}
// 查询
public void getAll() {
PreparedStatement statement = null;
ResultSet resultSet = null;
try {
System.out.println("jdbc.driverManager:"+jdbc.driverManager);
// 这地方在加一层判断,因为增删改查完之后,会关闭数据库连接
if(jdbc.driverManager == null) {
jdbc.getConnection();
}
String sql = "select * from java_pro";
// 预编译sql语句,防止SQL注入
statement = jdbc.driverManager.prepareStatement(sql);
// 专门执行查询语句 executeQuery()
resultSet = statement.executeQuery(); // 返回的是一个查询结果集 - 结果集也需要关闭
// 遍历查询结果集:
// resultSet.next() 方法 - 让光标往下移动一行,如果走到的的这一行有数据,则返回true,
// 则把这一行数据分贝取出来即可;继续往下移动下一行;依次循环,如果没数据next() 方法会返回false,停止循环
boolean status = resultSet.next();
int count = 0;
System.out.println("***********************************************************");
while(status) {
count ++;
// 取数据
// .getString() 不管数据库里边的数据类型是什么,都以字符串形式返回!getTnt() 取出的是数字类型,别的类型,请查看文档 ··· ···
// .getString(1): 通过下标取数据(注意下边从1开始);
// .getString("name"): 通过列字段取数据;
String name = resultSet.getString("name");
int age = resultSet.getInt("age");
String address = resultSet.getString("address");
System.out.println("查询出的数据结果为:"+name+"-"+age+"-"+address);
status = resultSet.next();
}
System.out.println("***********************一共"+count+"条数据!************************");
} catch (SQLException throwables) {
throwables.printStackTrace();
}finally {
if(resultSet != null) {
try {
resultSet.close(); // 关闭结果集
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if(statement != null) {
try {
statement.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
// 关闭数据库连接
jdbc.close();
}
}
// 插入sql语句执行,暂时无返回数据
public void insert(String name,int age,String address,String password) {
PreparedStatement statement = null;
try {
// 这地方在加一层判断,因为增删改查完之后,会关闭数据库连接
if(jdbc.driverManager == null) {
jdbc.getConnection();
}
String sql = "insert into java_pro (name, age, address, password) values (?, ?, ?, ?)";
// 预编译sql语句,当值sql注入
statement = jdbc.driverManager.prepareStatement(sql);
// 把?替换为用户传过来的参数
statement.setString(1, name);
statement.setInt(2, age);
statement.setString(3, address);
statement.setString(4, password);
// 执行sql语句
int count = statement.executeUpdate();
System.out.println(count == 1 ? "成功" : "失败");
} catch (SQLException throwables) {
throwables.printStackTrace();
}finally {
if(statement != null) {
try {
statement.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
// 关闭数据库连接
jdbc.close();
}
}
// 关闭数据库连接
private void close() {
try {
if(jdbc.driverManager != null) {
jdbc.driverManager.close();
jdbc.driverManager = null;
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
补充:
解决SQL注入的关键问题
用户提供的信息中,即使含有sql语句的关键字,但是这些关键字并没有参与编译,不起作用。
Statment和PreparedStatment对比?
Statment:存在sql注入的问题,编译一次执行一次。
PreparedStatment:解决了sql注入的问题,执行效率较高,编译一次执行N次,它会在编译阶段做类型检查。
还没有评论,来说两句吧...