Java实现 通过JDBC连接MySQL数据库及其相关拓展
1、idea实现Java连接MySQL数据库进行增删改查
1.1、创建项目
1、启动idea,File->new->Project->弹出新项目创建窗口
2、一直next,直到更改项目名称,填写项目名称。
3、点击finish即创建新项目成功。
1.2、编写代码
代码步骤总结
1、加载驱动
2、连接数据库DriverMananger
3、获得执行sql的对象 Statement
4、获得返回的数据结果集
5、释放连接
代码截图如下所示:
2、statement对象详解
executeQuery
用于产生单个结果集的语句,用于执行 SELECT 语句(SELECT无疑是是使用最多的 SQL 语句) ,返回值为ResultSet
读取操作
Statement st = conn.createStatement();
String sql = "select * from users";
ResutlSet rs = st.executeUpdate(sql);
while(rs.next()){
//根据获取到的数据类型,分别调用rs的相应方法映射到Java对象中
}
executeUpdate
用于执行 INSERT、UPDATE 或 DELETE 语句以及 SQL DDL(数据定义语言)语句,例如 CREATE TABLE 和 DROP TABLE。
executeUpdate 的返回值是一个整数,指示受影响的行数(即更新计数)。对于 CREATE TABLE 或 DROP TABLE 等不操作行的语句,executeUpdate 的返回值总为零。
添加操作insert
Statement st = conn.createStatement();
String sql = "insert into users(...) values(...)";
int num = st.executeUpdate(sql);//不进行操作时,返回的num值默认为0
if(num>0){
System.our.println("插入成功!")
}
修改操作update
Statement st = conn.createStatement();
String sql = "update users set name='' where name=''";
int num = st.executeUpdate(sql);//不进行操作时,返回的num值默认为0
if(num>0){
System.our.println("修改成功!")
}
删除操作delete
Statement st = conn.createStatement();
String sql = "delete from users where id=1";
int num = st.executeUpdate(sql);//不进行操作时,返回的num值默认为0
if(num>0){
System.our.println("删除成功!")
}
execute
用于执行返回多个结果集、多个更新计数或二者组合的语句。execute对与结果的处理比较麻烦
execute方法应该仅在语句能返回多个ResultSet对象、多个更新计数或ResultSet对象与更新计数的组合时使用。
返回值指示类型情况:如果下一个结果为 ResultSet 对象,则返回 true;如果其为更新计数或者不存在更多结果,则返回 false
//代码实现、提取工具类
import jdk.internal.util.xml.impl.Input;
import javax.swing.plaf.nimbus.State;
import java.io.IOException;
import java.io.InputStream;
import java.sql.*;
import java.util.Properties;
import java.util.concurrent.ExecutionException;
public class JdbcUtils {
private static String driver=null;
private static String url=null;
private static String username=null;
private static String password=null;
static {
try{
InputStream in = JdbcUtils.class.getClassLoader().getResourceAsStream("db.properties");
Properties properties = new Properties();
properties.load(in);
driver = properties.getProperty("driver");
url = properties.getProperty("url");
username = properties.getProperty("username");
password = properties.getProperty("password");
//1,驱动只用加载一次
Class.forName(driver);
} catch (IOException e) {
e.printStackTrace();
}catch (ClassNotFoundException e){
e.printStackTrace();
}
}
//获取连接
public static Connection getConnection() throws SQLException {
return DriverManager.getConnection(url, username, password);
}
//释放连接资源
public static void release(Connection conn, Statement st, ResultSet rs){
if(rs!=null){
try{
rs.close();
}catch (SQLException e){
e.printStackTrace();
}
}
if(st!=null){
try{
st.close();
}catch (SQLException e){
e.printStackTrace();
}
}
if(conn!=null){
try{
conn.close();
}catch (SQLException e){
e.printStackTrace();
}
}
}
}
3、PreparedStatement对象
- prepareStatement对象防止sql注入的方式是把用户非法输入的单引号用\反斜杠做了转义,从而达到了防止sql注入的目的
- Statement会使数据库频繁编译SQL,可能造成数据库缓冲区溢出。PreparedStatement可对SQL进行预编译,从而提高数据库的执行效率。并且PreperedStatement对于sql中的参数,允许使用占位符的形式进行替换,简化sql语句的编写
防止SQL注入
package com.feng;
import com.utils.JdbcUtils;
import java.sql.*;
public class SQL注入 {
//登录业务
public static void main(String[] args) {
login("'' or 1=1","1234");//用PreparedStatement成功防范了SQL注入。
//login("zhangsan","123456");
}
public static void login(String username, String pwd){
Connection con = null;
PreparedStatement st = null;
ResultSet rs = null;
try {
con = JdbcUtils.getConnection();//获取数据库连接
//SQL注解方式,恶意获取数据库信息
//String sqlzhujie = "select * from users where name = 1 or 1=1 and password = '' or 1=1;";
//PreparedStatement 防止SQL注入的本质,把传递进来的参数当做字符
//假设其中存在转义字符、比如说''会被直接转义
String sql="select * from users where name=? and password = ?;";
st = con.prepareStatement(sql);//获取SQL的执行对象
st.setString(1,username);
st.setString(2,pwd);
rs = st.executeQuery();
while(rs.next()){
System.out.println(rs.getString("name"));
System.out.println(rs.getString("password"));
System.out.println("=========================");
}
} catch (SQLException e) {
e.printStackTrace();
}finally {
JdbcUtils.release(con,st,rs);
}
}
}
4、idea连接数据库
1、创建新连接
2、对连接信息进行配置。
3、点击apply即可使用,常用界面
5、MySQL数据库事务
特性:
- 原子性
- 一致性
- 隔离性
- 持久性
隔离性的问题:
脏读、不可重复读、虚读等问题
代码实现:
1、开启事务
2、一组业务执行完毕、提交事务
3、可以在catch语句中现实的定义 回滚语句,但默认失败就会回滚
package com.affair;
import com.utils.JdbcUtils;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class TestTransaction1 {
public static void main(String[] args) {
Connection con=null;
PreparedStatement st = null;
ResultSet rs = null;
try {
con = JdbcUtils.getConnection();
//关闭数据库的自动提交,自动会开启事务
con.setAutoCommit(false);//开启事务
String sql1 = "update account set money=money-100 where name='A'";
st = con.prepareStatement(sql1);
st.executeUpdate();
//int x=1/0;//如果失败了,则全都会回滚,整个事务回滚
String sql2 = "update account set money=money-100 where name='B'";
st = con.prepareStatement(sql2);
st.executeUpdate();
//业务完毕,提交事务
con.commit();
System.out.println("操作成功");
} catch (SQLException e) {
try {
con.rollback();//如果失败则回滚事务
} catch (SQLException ex) {
ex.printStackTrace();
}
e.printStackTrace();
} finally {
JdbcUtils.release(con,st,rs);
}
}
}
6、数据库连接池
数据库连接—执行完毕—释放
连接—释放 十分浪费系统资源
池化技术:准备一些预先的资源,过来就连接预先准备好的
最小连接数:10
最大连接数:100
等待超时:100ms
编写连接池,实现一个接口 DataSource
开放数据源实现
DBCP
C3P0
Druid:阿里巴巴(这里不做详细介绍!)
使用了这些数据库连接池之后,我们在项目开发中就不需要编写连接数据库的代码了。
DBCP
需要用到的jar包
commons-dbcp2-2.7.0、commons-pool2-2.8.0、commons-logging-1.2.jar(一个都不能少,少一个报错!改半天,经验教训总结得来的)
C3P0
mchange-commons-java-0.2.3.4.jar 、c3p0-0.9.2.1.jar
:10
最大连接数:100
等待超时:100ms
编写连接池,实现一个接口 DataSource
开放数据源实现
DBCP、C3P0、Druid:阿里巴巴(这里不做详细介绍!)
使用了这些数据库连接池之后,我们在项目开发中就不需要编写连接数据库的代码了。
DBCP
需要用到的jar包
commons-dbcp2-2.7.0、commons-pool2-2.8.0、commons-logging-1.2.jar(一个都不能少,少一个报错!改半天,经验教训总结得来的)
C3P0
mchange-commons-java-0.2.3.4.jar 、c3p0-0.9.2.1.jar
结语:这里给出条件。后面我会将相关资源上传到csdn上,供朋友们下载,或通过百度网盘的方式共享出来。本次博文就到此结束了。