一、JDBC概述(mysql)
1、Java DataBase Connective
1)概念:JDBC其实就是一套Java操作数据库的规范(接口);
2)数据库驱动:
各个数据库厂商要让java语言去操作数据库就必须实现这套接口,每个数据库都写有一套实现类叫数据库驱动。
3)使用:
//导入mysql数据库jar包
//将jar放在lib目录下 右键add--->builderpath
//加载驱动
Class.forName("com.mysql.jdbc.Driver");
//获取一个数据库连接对象
String url = "jdbc:mysql://localhost:3306/mydb_01";//主协议:子协议://ip:端口号/数据库名
String user = "root";
String password = "root";
Connection conn = DriverManager.getConnection(url, user, password);
//获取操作对象
Statement stat = conn.createStatement();
//执行sequel语句
String sql = "sql的增删改查语句";
ResultSet set = stat.executeQuery(sql); //查 返回的是一个结果集合
//set.next() set.getString("username");
int i = stat.executeUpdate(sql); //增、删、改 返回值i影响的行数 为0修改失败
boolean b = stat.execute(sql); //所有
//处理结果,释放资源
stat.close();
conn.close();
4)sql注入:
通过一些特殊的字符串拼接,绕过数据库的检验;
例:
select * from login where username = ‘1‘ or ‘1‘=‘1‘ and password = ‘1‘ or ‘1‘=‘1‘;
改进:
Connection conn = DriverManager.getConnection(url, user, password);
String sql = "select * from login where username=? and password=?";
//获取预编译操作对象 取代获取操作对象
PreparedStatement statement = conn.prepareStatement(sql);
//给?号赋值 问号从1开始数
String username="1‘ or ‘1‘=‘1";
String password="1‘ or ‘1‘=‘1";
statement.setString(1, username);
statement.setString(2, password);
ResultSet resultSet = statement.executeQuery();
conn.close();
statement.close();
resultSet.close();
5)调用储存过程
CallableStatement stat = conn.prepareCall("call 储存过程名");
stat.executeUpdate();
2、事务
1)概念:是指一组最小逻辑操作单元,里面有多个操作组成。组成事务的每一部分必须要同时提交成功,如果有一个操作失败,整个操作就回滚。
//简便的说就是 一件事情独立的单元 要么同时成功,要么同时失败
2)ACID特性
原子性(Atomicity):最小逻辑操作单元
一致性(Consistency):过程中,数据处于一致状态
隔离性(Isolation):多个并发事务之间要相互隔离
持久性(Durability):对数据库中数据的改变就是永久性的
3)事务的使用
//JDBCUtil 自己写的简易的连接数据库的工具类 import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import com.mysql.jdbc.Statement; public class JDBCUtil { private static String url = null; private static String username = null; private static String password = null; static{ //提前加载驱动 try { Class.forName("com.mysql.jdbc.Driver"); url = "jdbc:mysql://localhost:3306/mydb_01"; username = "root"; password = "root"; } catch (ClassNotFoundException e) { e.printStackTrace(); } } private JDBCUtil() { super(); } public static Connection getConnection() throws Exception{ Connection conn = DriverManager.getConnection(url, username, password); return conn; } public static void close(Connection conn,Statement stat,ResultSet resultSet) throws Exception{ if(conn != null){ conn.close(); } if(stat != null){ stat.close(); } if(resultSet != null){ resultSet.close(); } } public static void close(Connection conn,Statement stat) throws Exception{ if(conn != null){ conn.close(); } if(stat != null){ stat.close(); } } }
import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; import java.sql.Savepoint; import org.westos.util.JDBCUtil; import com.mysql.jdbc.Statement; public class Shiwu { public static void main(String[] args) { Savepoint point = null; Connection conn = null; PreparedStatement stat1 = null; PreparedStatement stat2 = null; PreparedStatement stat3 = null; PreparedStatement stat4 = null; try { conn = JDBCUtil.getConnection(); String sql1 = "update bank set money=money-100 where name=‘qwe‘"; String sql2 = "update bank set money=money+100 where name=‘asd‘"; //开启事务 conn.setAutoCommit(false); // 为 true 表示启用自动提交模式;为 false 表示禁用自动提交模式 stat1 = conn.prepareStatement(sql1); stat2 = conn.prepareStatement(sql2); stat1.executeUpdate(); stat2.executeUpdate(); //设置回滚点 point = conn.setSavepoint(); String sql3 = "update bank set money=money-1000 where name=‘qwe‘"; String sql4 = "update bank set money=money+1000 where name=‘asd‘"; stat3 = conn.prepareStatement(sql3); stat4 = conn.prepareStatement(sql4); stat3.executeUpdate(); System.out.println(1/0); stat4.executeUpdate(); } catch (Exception e) { //一旦异常 回滚 try { // conn.rollback(); //回滚到最初状态-->开启事务 conn.rollback(point); //回滚到回滚点 } catch (SQLException e1) { e1.printStackTrace(); } }finally{ //提交事务 将事务中的系列操作提交给数据库 try { conn.commit(); } catch (SQLException e) { e.printStackTrace(); } try { JDBCUtil.close(conn, (Statement) stat1); JDBCUtil.close(null, (Statement) stat2); JDBCUtil.close(null, (Statement) stat3); JDBCUtil.close(null, (Statement) stat4); } catch (Exception e) { e.printStackTrace(); } } } }
二、数据库连接池产品 ———— 连接数据库的第三方jar包
1、DBCP
阿帕奇基金组织产品、高效的管理连接对象,需要导入DBCP两个jar包
1)硬编码的使用方式(不推荐)
//创建连接池对象
BasicDataSource ds = new BasicDataSource();
//设置参数
ds.setDriverClassName("com.mysql.jdbc.Driver");
ds.setUrl("jdbc:mysql:///mydemo");
ds.setUsername("root");
ds.setPassword("root");
//获取预编译对象
Connection conn = ds.getConnection();
String sql = "sql语句";
PreparedStatement statement = conn.prepareStatement(sql);
//执行 关闭资源
2)配置文件的使用方式
//dbcp.properties配置文件
#连接基本设置
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/mydemo
username=root
password=123456
#<!--扩展配置 了解-->
//使用
//创建属性集合类对象
Properties properties = new Properties();
//将dbcp.properties文本中的数据读取到Properties中
properties.load(new FileInputStream("src/dbcp.properties"));
//创建连接池对象
DataSource ds = BasicDataSourceFactory.createDataSource(properties);
//获取预编译对象
Connection conn = ds.getConnection();
String sql = "sql语句";
PreparedStatement statement = conn.prepareStatement(sql);
//执行 关闭资源
2、C3P0 —— 需要导入C3P0jar包
1)硬编码格式
//创建连接池对象
ComboPooledDataSource ds = new ComboPooledDataSource();
//设置参数
ds.setJdbcUrl("");
ds.setDriverClass("");
ds.setUser("");
ds.setPassword("");
//获取预编译对象
Connection conn = ds.getConnection();
PreparedStatement statement = conn.prepareStatement("");
//执行 关闭资源
2)使用配置文件
//要求
a:配置文件的文件名和后缀名固定的 c3p0.properties/c3p0-config.xml
b:配置文件必须放在src目录下
//c3p0.properties配置文件
c3p0.driverClass=com.mysql.jdbc.Driver
c3p0.jdbcUrl=jdbc:mysql:///mydemo
c3p0.user=root
c3p0.password=123456
//c3p0-config.xml配置文件多了个命名的配置
<named-config name="PZWJ">
//使用
ComboPooledDataSource ds = new ComboPooledDataSource("PZWJ");//也可以不写"PZWJ"
Connection conn = ds.getConnection();
//后续一系列操作
3、DBUtils
阿帕奇基金组织出品,封装操作对象的增删改查,需要配合C3P0使用,导入C3P0 jar包和DBUtils jar包
//当然C3P0的配置文件也需要拷进来
1)使用
//创建对象
ComboPooledDataSource ds = new ComboPooledDataSource();
QueryRunner runner = new QueryRunner(ds);
//执行sql语句
String sql = "insert into user values(4,‘qwe‘)";
runner.update(sql); //执行增删改操作
2)查询操作
String sql = "select * from user";
List<User> list = runner.query(sql, new BeanListHandler<>(User.class));
//需要写一个javabean,User类来封装查询到的信息,将信息封装好后存到List集合中
//通过增强for()循环变量User
for(User u : list){
syso(u);
}