最终一定要熟练使用Durid 和 DButils
JDBC(Java DataBase Connectivity)为访问不同数据库提供统一的接口,不同的数据库厂商实现接口。
java程序员只需要使用JDBC,就可以连接任何提供了JDBC驱动程序的数据库系统。本文使用mysql数据库
序号 | 程序编写步骤 |
---|---|
1 | 注册驱动 |
2 | 获取连接 |
3 | 执行操作 |
4 | 释放资源 |
先看一眼,先了解就行。看到代码就懂了。先看代码也可(1.2.6 练习)。
包含sql注入、批处理、事务的操作。复习嘛,快就完了(哈哈),看Aapi一下就想起来。想不起来的小笨蛋,看对应的代码。
注册两种方法
mysql5之后可以省略注册驱动的步骤,不需要通过DriverManager调用静态方法registerDriver()。
Driver类被加载就可以了。
1、new 一个driver实例
2、通过反射,进行类加载。class.forname(String classFullpath)
序号 | 方法 | 含义 |
---|---|---|
1 | static Connection getConnection(String url, String username, String password) | 获取连接Connection对象 url :jdbc:mysql://ip地址(域名):端口号/数据库名称 想实现批处理在url后加rewriteBatchedStatements=true user:数据库用户名 password:数据库密码 |
2-1 | setAutoCommit(boolean autoCommit) | 参数为false,则开启事务。 |
2-2 | commit() | 提交事务 |
2-3 | rollback() | 回滚事务 |
序号 | 方法 | 含义 |
---|---|---|
1 | Statement createStatement(); | 获取普通执行对象,Statement对象,用来执行sql语句的对象。不防止sql注入,不建议使用 |
1 | PreparedStatement prepareStatement(String sql) | 获取预编译执行对象,PrepareStatement对象,用来执行sql语句的对象。有效防止sql注入,不建议使用 |
2 | void close(); | 释放资源,关闭连接。 |
可以学习,但不推荐 。因为其不能防止sql注入。大多数情况被PrepareStatement对象代替。
序号 | 方法 | 含义 |
---|---|---|
1 | ResultSet executeQuery() | 执行DQL语句(select 语句)。根据查询返回封装了查询结果的对象,ResultSet对象。 |
2 | int executeUpdate() | 执行DML语句(create、delete、insert语句)。返回影响行数(返回大于0的数表示执行成功,反之sql语句执行失败) |
3 | void close() | 释放资源 |
预编译sql语句的执行者对象。在执行sql语句之前,将sql语句进行提前编译
明确sql语句的格式后,格式不会改变。内容整体都会认为是参数
能防止sql注入还能批量处理sql语句
序号 | 方法 | 含义 |
---|---|---|
1 | ResultSet executeQuery() | 执行DQL语句(select 语句)。根据查询返回封装了查询结果的对象,ResultSet对象。 |
2 | int executeUpdate() | 执行DML语句(create、delete、insert语句)。返回影响行数(返回大于0的数表示执行成功,反之sql语句执行失败) |
3 | void close() | 释放资源 |
4-1 | setAutoCommit(boolean autoCommit) | 开启事务 。参数为false,则开启事务。 |
4-2 | commit() | 提交事务 。 |
4-3 | rollback() | 回滚事务 。 |
5-1 | addBatch() | 添加需要批处理的sql语句 |
5-2 | executeBatch() | 执行批量处理语句 |
5-3 | clearBatch() | 清空批处理包的语句 |
看一眼,看到代码就明白了。
表示查询结果集的数据表
ResultSet对象保持一个光标指向数据行,一行行的判断有无数据,下移光标读取。(next()方法和while配合)
序号 | 方法 | 含义 |
---|---|---|
1 | boolean next() | 判断是否还有数据。 true:有数据,并将索引下移 |
2 | void close() | 释放资源 |
3 | String getString(String name) | 返回字符串。获取改行数据列名为name的字符串 还有很多类似放方法。想返回什么类型数据"get数据类型"=。大同小异,具体查看API |
4 | String getString(int index) | index 从1开始,作用与上一致 |
实现代码,说穿就是API。照着前面列好的API看
mysqlLogin.properties
user=root
url=jdbc\:mysql\://localhost\:3306/revJ?rewriteBatchedStatements=true
password=mima
driver=com.mysql.jdbc.Driver
Properties properties = new Properties();
Connection connection = null;
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
try {
properties.load(new FileInputStream("./mysqlLogin.properties"));
String classFullPath = properties.getProperty("driver");
String url = properties.getProperty("url");
String user = properties.getProperty("user");
String password = properties.getProperty("password");
//一、动态加载Driver
Class.forName(classFullPath);
//二、获取连接 通过DriverManger
connection = DriverManager.getConnection(url, user, password);
//三、数据库操作 执行查找操作
String sql = "select * from test1 where id > ?";
preparedStatement = connection.prepareStatement(sql);
preparedStatement.setInt(1, 2);
resultSet = preparedStatement.executeQuery();
while (resultSet.next()) {
int id = resultSet.getInt(1);
String name = resultSet.getString("name");
System.out.printf("id=%d,name=%s\n", id, name);
}
// String sql = "insert into test1 value(?,?)";
// preparedStatement = connection.prepareStatement(sql);
// preparedStatement.setInt(1,9);
// preparedStatement.setString(2,"yu9");
// int effectRowNum = preparedStatement.executeUpdate();
// System.out.println(effectRowNum>0?String.format("执行成功,影响%d行",effectRowNum):"执行失败");
} catch (IOException | ClassNotFoundException | SQLException e) {
e.printStackTrace();
} finally {
//四、释放资源
try {
if (resultSet != null) {
resultSet.close();
}
if (preparedStatement != null) {
preparedStatement.close();
}
if (connection != null) {
connection.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
System.out.println("---结束---");
真有小笨蛋,看api想不来呀,呜呜,好吧。我也一样。上代码。
url后要加 rewriteBatchedStatements=true
String sql = "insert into test1 value(?,?)";
preparedStatement = connection.prepareStatement(sql);
//批量添加数据 向test1表种添加50条数据
for (int i = 1; i <= 50; i++) {
preparedStatement.setInt(1,i);
preparedStatement.setString(2,"yu"+i);
//1、addBatch()
preparedStatement.addBatch();
//2、executeBatch()
//3、clearBatch()
if(i%10==0) {
preparedStatement.executeBatch();
preparedStatement.clearBatch();
}
}
Properties properties = new Properties();
Connection connection = null;
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
try {
properties.load(new FileInputStream("./mysqlLogin.properties"));
String classFullPath = properties.getProperty("driver");
String url = properties.getProperty("url");
String user = properties.getProperty("user");
String password = properties.getProperty("password");
Class.forName(classFullPath);
connection = DriverManager.getConnection(url, user, password);
//1、看这里 根注释走
connection.setAutoCommit(false);
String sql = "insert into test1 value(?,?)";
preparedStatement = connection.prepareStatement(sql);
preparedStatement.setInt(1, 51);
preparedStatement.setString(2, "yu51");
int effectRowNum = preparedStatement.executeUpdate();
//故意出现异常、测试是否会回滚事务
//会失败(我设计的)异常会导致事务回滚
int cuo = 10 /0;
//3、 事务提交
connection.commit();
} catch (Exception e) {
e.printStackTrace();
//2、事务回滚
connection.rollback();
System.out.println("执行失败");
} finally {
try {
if (resultSet != null) {
resultSet.close();
}
if (preparedStatement != null) {
preparedStatement.close();
}
if (connection != null) {
connection.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
System.out.println("---结束---");
使用JDBC的基本代码不会变,每次用都写一样的代码,啰嗦!封装起来,下次还能用。
import java.io.FileInputStream;
import java.sql.*;
import java.util.Properties;
/**
* @author Jyu
* @version 1.0
*/
public class JDBCUtils {
private static String user;
private static String password;
private static String url;
private static String driver;
static {
Properties properties = new Properties();
try {
properties.load(new FileInputStream("./mysqlLogin.properties"));
user = properties.getProperty("user");
password = properties.getProperty("password");
url = properties.getProperty("url");
driver = properties.getProperty("driver");
Class.forName(driver);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public static Connection getConnection() {
try {
return DriverManager.getConnection(url,user,password);
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
public static void close(ResultSet resultSet, Statement statement, Connection connection) {
try {
if(resultSet != null) {
resultSet.close();
}
if(statement != null) {
statement.close();
}
if(connection!= null) {
connection.close();
}
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}
我们用到:
druid.properties
#key=value
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/revj?rewriteBatchedStatements=true
#url=jdbc:mysql://ip:端口/数据库名
username=root
password=ysk
#initial connection Size
initialSize=10
#min idle connecton size
minIdle=5
#max active connection size
maxActive=20
#max wait time (5000 mil seconds)
maxWait=5000
获取连接方式
Properties properties = new Properties();
properties.load(new FileInputStream("src/druid.properties"));
//1、看这里
DataSource dataSource = DruidDataSourceFactory.createDataSource(properties);
Connection connection = dataSource.getConnection();
import com.alibaba.druid.pool.DruidDataSourceFactory;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
/**
* @author xiaoyu
* @version 1.0
*/
public class JDBCUtilsByDruid {
private static DataSource dataSource;
//dataSource初始化
static {
try {
Properties properties = new Properties();
//properties.load(new FileInputStream("src\\druid.properties"));
properties.load(JDBCUtilsByDruid.class.getClassLoader().getResourceAsStream("druid.properties"));
dataSource = DruidDataSourceFactory.createDataSource(properties);
} catch (Exception e) {
e.printStackTrace();
}
}
public static Connection getConnection() throws SQLException {
return dataSource.getConnection();
}
public static void close(ResultSet resultSet, Statement statement, Connection connection) {
try {
if(resultSet != null) {
resultSet.close();
}
if(statement != null){
statement.close();
}
if(connection != null) {
connection.close();
}
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}
我们用到
序号 | 方法 | 含义 |
---|---|---|
1 | public T query(Connection conn, String sql, ResultSetHandler rsh, Object… params) | 执行DQL语句(select 语句) ResultSetHandler是一个接口,参数是一个其实现类对象 Object… param :就是给 sql 语句中的? 赋值,可以有多个值,所以是可变参数 |
2 | public int update(Connection conn, String sql, Object… params) | 执行DML语句(create、delete、insert语句) |
3 | public int[] batch(Connection conn, String sql, Object[] []params) | 批处理 |
BeanHandler 将查询结果的一行封装到javaBean对象
Bean ListHandler 将查询结果的每一行封装到javaBean对象,然后再存入List集合
ScalerHandler 将结果集第一行的某一列放到某个对象中
…
还有很多,根据需要看api吧
import TestDurid.utils.JDBCUtilsByDruid;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.apache.commons.dbutils.handlers.ScalarHandler;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;
/**
* @author xiaoyu
* @version 1.0
* BasicDAO 是其他类的父类
*/
public class BasicDAO<T> { //泛型指定具体类型
private QueryRunner queryRunner = new QueryRunner();
//开发通用的dml方法, 针对任意的表
public int update(String sql,Object... parameters){
Connection connection = null;
try {
connection = JDBCUtilsByDruid.getConnection();
return queryRunner.update(connection,sql,parameters);
} catch (SQLException e) {
throw new RuntimeException(e);
} finally {
JDBCUtilsByDruid.close(null, null, connection);
}
}
public Object queryScalar(String sql, Object... parameters){
Connection connection = null;
try {
connection = JDBCUtilsByDruid.getConnection();
return queryRunner.query(connection,sql,new ScalarHandler(),parameters);
} catch (SQLException e) {
throw new RuntimeException(e);
} finally {
JDBCUtilsByDruid.close(null, null, connection);
}
}
public T querySingle(String sql,Class<T> clazz, Object... parameters) {
Connection connection = null;
try {
connection = JDBCUtilsByDruid.getConnection();
return queryRunner.query(connection,sql, new BeanHandler<T>(clazz),parameters);
} catch (SQLException e) {
throw new RuntimeException(e);
} finally {
JDBCUtilsByDruid.close(null,null,connection);
}
}
public List<T> queryMulti(String sql,Class<T> clazz, Object... parameters){
Connection connection = null;
try {
connection = JDBCUtilsByDruid.getConnection();
return queryRunner.query(connection,sql,new BeanListHandler<T>(clazz),parameters);
} catch (SQLException e) {
throw new RuntimeException(e);
} finally {
JDBCUtilsByDruid.close(null, null, connection);
}
}
}