一、下载mysql驱动
下载mysql驱动教程链接:https://jingyan.baidu.com/article/c275f6ba6bf785e33d756707.html
二、把下载好的mysql驱动复制粘贴到项目的lib文件夹下 (如果没有lib文件夹,就在项目下新建一个lib文件夹),然后选中mysql驱动包鼠标右键选择 Build Path → Add to Build Path
三、优化 JDBC连接Mysql数据库的 增加、删除和修改方法
3.1、首先让我们来看一下优化前的添加、修改和删除方法 有什么缺点
3.1.1、创建一个Student实体类,用于JDBC连接Mysql数据库
package com.mysql.pojo;
public class Student implements Serializable{
private Integer id;
private String name;
private String sex;
public Student() {}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String toString() {
return "Student [id=" + id + ", name=" + name + ", sex=" + sex + "]";
}
}
3.1.2、添加数据方法
public void add(Student student) {
Connection conn = null;
PreparedStatement stmt = null;
try {
// 1、注册驱动
Class.forName("com.mysql.jdbc.Driver");
String url = "jdbc:mysql://localhost:3306/mytest"; //连接数据库的url 格式:协议 ://主机名:端口号/数据库名称
String user = "root"; //mysql数据库账号
String password = "123456"; //mysql数据库密码
//2、获取与mysql数据库的连接 Connection
conn = DriverManager.getConnection(url, user, password);
//3、编写mysql语句
String sql = "insert into student(id,name,sex) values(?,?,?)";
stmt = conn.prepareStatement(sql);
//4、替换mysql语句中的问号 (注意:下标是从1开始的)
stmt.setObject(1, student.getId());
stmt.setObject(2, student.getName());
stmt.setObject(3, student.getSex());
//5、执行executeUpdate
int executeUpdate = stmt.executeUpdate();
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
//6、释放资源
if (stmt != null) {
try {
stmt.close();
} catch (SQLException sqlex) {
throw new RuntimeException(sqlex);
}
stmt = null;
}
if (conn != null) {
try {
conn.close();
} catch (SQLException sqlex) {
throw new RuntimeException(sqlex);
}
conn = null;
}
}
}
3.1.3、修改数据方法
public void update(Student student) {
Connection conn = null;
PreparedStatement stmt = null;
try {
// 1、注册驱动
Class.forName("com.mysql.jdbc.Driver");
String url = "jdbc:mysql://localhost:3306/mytest"; // 连接数据库的url 格式:协议 ://主机名:端口号/数据库名称
String user = "root"; // mysql数据库账号
String password = "123456"; // mysql数据库密码
// 2、获取与mysql数据库的连接 Connection
conn = DriverManager.getConnection(url, user, password);
// 3、编写mysql语句
String sql = "update student set name=?, sex=? where id=?";
stmt = conn.prepareStatement(sql);
// 4、替换mysql语句中的问号 (注意:下标是从1开始的)
stmt.setObject(1, student.getName());
stmt.setObject(2, student.getSex());
stmt.setObject(3, student.getId());
// 5、执行executeUpdate
int executeUpdate = stmt.executeUpdate();
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
// 6、释放资源
if (stmt != null) {
try {
stmt.close();
} catch (SQLException sqlex) {
throw new RuntimeException(sqlex);
}
stmt = null;
}
if (conn != null) {
try {
conn.close();
} catch (SQLException sqlex) {
throw new RuntimeException(sqlex);
}
conn = null;
}
}
}
3.1.4、删除数据方法
public void delete(Integer id) {
Connection conn = null;
PreparedStatement stmt = null;
try {
// 1、注册驱动
Class.forName("com.mysql.jdbc.Driver");
String url = "jdbc:mysql://localhost:3306/mytest"; // 连接数据库的url 格式:协议 ://主机名:端口号/数据库名称
String user = "root"; // mysql数据库账号
String password = "123456"; // mysql数据库密码
// 2、获取与mysql数据库的连接 Connection
conn = DriverManager.getConnection(url, user, password);
// 3、编写mysql语句
String sql = "delete from student where id=?";
stmt = conn.prepareStatement(sql);
// 4、替换mysql语句中的问号 (注意:下标是从1开始的)
stmt.setObject(1, id);
// 5、执行executeUpdate
int executeUpdate = stmt.executeUpdate();
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
// 6、释放资源
if (stmt != null) {
try {
stmt.close();
} catch (SQLException sqlex) {
throw new RuntimeException(sqlex);
}
stmt = null;
}
if (conn != null) {
try {
conn.close();
} catch (SQLException sqlex) {
throw new RuntimeException(sqlex);
}
conn = null;
}
}
}
3.2、通过对比发现,添加、修改和删除方法,除了方法参数、mysql数据库语句和替换mysql语句中的问号不同,其他步骤都是相同的,这时我们可以对这三个方法进行提取和优化,使其变成一个方法,其优化之后的结果如下:
3.2.1、创建一个jdbc.properties文件,在文件中添加如下信息:
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/mytest
name=root
password=123456
3.2.2、优化之后的MysqlDemo类
package com.mysql.demo;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.Properties;
public class MysqlDemo {
private static Properties properties = null;
private static Connection connection = null;
private static PreparedStatement statement = null;
private static ResultSet resultSet = null;
static {
try {
// 1.注册驱动
InputStream resourceAsStream = MysqlDemo.class.getClassLoader().getResourceAsStream("jdbc.properties");
properties = new Properties();
properties.load(resourceAsStream);
String property = properties.getProperty("className");
Class.forName(property);
} catch (Exception e) {
e.printStackTrace();
}
}
// 获取与mysql数据库的连接
public static Connection getConnection() {
try {
// 2.获取连接
String url = properties.getProperty("url");
String user = properties.getProperty("user");
String password = properties.getProperty("password");
return DriverManager.getConnection(url, user, password);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/*
* 添加、修改和删除方法优化
* 返回值为Integer:影响行数
* 参数:
* sql:Mysql数据库查询语句
* array:可变参数
*/
public static Integer Update(String sql, Object... array) {
try {
connection = MysqlDemo.getConnection();
statement = connection.prepareStatement(sql);
for (int i = 0; i < array.length; i++) {
statement.setObject(i + 1, array[i]);
}
return statement.executeUpdate();
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
closeAll(null, statement, connection);
}
}
// 关闭资源
public static void closeAll(ResultSet resultSet, PreparedStatement statement, Connection connection) {
// 关闭resultSet
if (resultSet != null) {
try {
resultSet.close();
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
resultSet = null;
}
}
// 关闭statement
if (statement != null) {
try {
statement.close();
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
statement = null;
}
}
// 关闭connection
if (connection != null) {
try {
connection.close();
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
connection = null;
}
}
}
}
3.2.3、使用方式如下:
public static void main(String[] args) {
Student student = new Student();
student.setId(1);
student.setName("李四");
student.setSex("男");
// ------------添加数据操作------------
String addSql = "insert into student(id,name,sex) values(?,?,?)";
MysqlDemo.Update(addSql, student.getId(), student.getName(), student.getSex());
// ------------修改数据操作------------
student.setName("王五");
student.setSex("女");
String updateSql = "update student set name=?, sex=? where id=?";
MysqlDemo.Update(updateSql, student.getId(), student.getName(), student.getSex());
// ------------删除数据操作------------
String deleteSql = "delete from student where id=?";
MysqlDemo.Update(updateSql, student.getId());
}
四、优化 JDBC连接Mysql数据库的 查询方法
4.1、由于查询比较复杂,查询的返回结果可以是一个对象、一个对象集合、一个字段集合或者一个字段(例如查询count(*) ),首先让我们来看一下优化前的查询方法,有什么缺点
4.1.1、查询数据方法,并返回一个对象
public Student select(Integer id) {
Connection conn = null;
PreparedStatement stmt = null;
ResultSet resultSet = null;
try {
// 1、注册驱动
Class.forName("com.mysql.jdbc.Driver");
String url = "jdbc:mysql://localhost:3306/mytest"; // 连接数据库的url 格式:协议 ://主机名:端口号/数据库名称
String user = "root"; // mysql数据库账号
String password = "123456"; // mysql数据库密码
// 2、获取与mysql数据库的连接 Connection
conn = DriverManager.getConnection(url, user, password);
// 3、编写mysql语句
String sql = "select * from student where id=?";
stmt = conn.prepareStatement(sql);
// 4、替换mysql语句中的问号 (注意:下标是从1开始的)
stmt.setObject(1, id);
// 5、执行executeQuery
resultSet = stmt.executeQuery();
// 6、创建Student实体类对象
Student student = new Student();
if (resultSet.next()) {
student.setId(resultSet.getInt("id"));
student.setName(resultSet.getString("name"));
student.setSex(resultSet.getString("sex"));
}
return student;
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
// 6、释放资源
if (stmt != null) {
try {
stmt.close();
} catch (SQLException sqlex) {
throw new RuntimeException(sqlex);
}
stmt = null;
}
if (conn != null) {
try {
conn.close();
} catch (SQLException sqlex) {
throw new RuntimeException(sqlex);
}
conn = null;
}
if (resultSet != null) {
try {
resultSet.close();
} catch (SQLException sqlex) {
throw new RuntimeException(sqlex);
}
resultSet = null;
}
}
}
4.1.2、查询数据方法,并返回一个对象的集合
public List<Student> select(String sex) {
Connection conn = null;
PreparedStatement stmt = null;
ResultSet resultSet = null;
try {
// 1、注册驱动
Class.forName("com.mysql.jdbc.Driver");
String url = "jdbc:mysql://localhost:3306/mytest"; // 连接数据库的url 格式:协议 ://主机名:端口号/数据库名称
String user = "root"; // mysql数据库账号
String password = "123456"; // mysql数据库密码
// 2、获取与mysql数据库的连接 Connection
conn = DriverManager.getConnection(url, user, password);
// 3、编写mysql语句
String sql = "select * from student where sex=?";
stmt = conn.prepareStatement(sql);
// 4、替换mysql语句中的问号 (注意:下标是从1开始的)
stmt.setObject(1, sex);
// 5、执行executeQuery
resultSet = stmt.executeQuery();
// 6、声明Student实体类对象
Student student = null;
//7、创建对象集合
ArrayList<Student> list = new ArrayList<>();
while (resultSet.next()) {
student = new Student();
student.setId(resultSet.getInt("id"));
student.setName(resultSet.getString("name"));
student.setSex(resultSet.getString("sex"));
//8、添加到对象集合中
list.add(student);
}
return list;
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
// 9、释放资源
if (stmt != null) {
try {
stmt.close();
} catch (SQLException sqlex) {
throw new RuntimeException(sqlex);
}
stmt = null;
}
if (conn != null) {
try {
conn.close();
} catch (SQLException sqlex) {
throw new RuntimeException(sqlex);
}
conn = null;
}
if (resultSet != null) {
try {
resultSet.close();
} catch (SQLException sqlex) {
throw new RuntimeException(sqlex);
}
resultSet = null;
}
}
}
4.1.3、查询数据方法,并返回一个字段集合
public List<String> select() {
Connection conn = null;
PreparedStatement stmt = null;
ResultSet resultSet = null;
try {
// 1、注册驱动
Class.forName("com.mysql.jdbc.Driver");
String url = "jdbc:mysql://localhost:3306/mytest"; // 连接数据库的url 格式:协议 ://主机名:端口号/数据库名称
String user = "root"; // mysql数据库账号
String password = "123456"; // mysql数据库密码
// 2、获取与mysql数据库的连接 Connection
conn = DriverManager.getConnection(url, user, password);
// 3、编写mysql语句
String sql = "select name from student";
stmt = conn.prepareStatement(sql);
// 4、执行executeQuery
resultSet = stmt.executeQuery();
// 5、创建String数据类型集合
ArrayList<String> list = new ArrayList<>();
while (resultSet.next()) {
String num = resultSet.getString("name");
// 6、添加到String数据类型集合中
list.add(num);
}
return list;
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
// 6、释放资源
if (stmt != null) {
try {
stmt.close();
} catch (SQLException sqlex) {
throw new RuntimeException(sqlex);
}
stmt = null;
}
if (conn != null) {
try {
conn.close();
} catch (SQLException sqlex) {
throw new RuntimeException(sqlex);
}
conn = null;
}
if (resultSet != null) {
try {
resultSet.close();
} catch (SQLException sqlex) {
throw new RuntimeException(sqlex);
}
resultSet = null;
}
}
}
4.2、通过对比发现,查询的三个方法,除了方法参数、mysql数据库语句、替换mysql语句中的问号、resultSet结果集处理和返回值不同,其他步骤都是相同的,这时我们可以对这三个方法进行提取和优化,使其变成一个方法,其优化之后的结果如下:
4.2.1、创建一个jdbc.properties文件,在文件中添加如下信息:
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/mytest
name=root
password=123456
4.2.2、优化之后的MysqlDemo类
package com.mysql.demo;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.Properties;
import com.mysql.dbutil.ResultSetHandler;
public class MysqlDemo {
private static Properties properties = null;
private static Connection connection = null;
private static PreparedStatement statement = null;
private static ResultSet resultSet = null;
static {
try {
// 1.注册驱动
InputStream resourceAsStream = MysqlDemo.class.getClassLoader().getResourceAsStream("jdbc.properties");
properties = new Properties();
properties.load(resourceAsStream);
String property = properties.getProperty("className");
Class.forName(property);
} catch (Exception e) {
e.printStackTrace();
}
}
// 获取与mysql数据库的连接
public static Connection getConnection() {
try {
// 2.获取连接
String url = properties.getProperty("url");
String user = properties.getProperty("user");
String password = properties.getProperty("password");
return DriverManager.getConnection(url, user, password);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/*
* 查询方法优化 返回值使用Object,来解决返回值不同的问题
* 参数:
* sql:Mysql数据库查询语句
* handler:resultSet结果集处理接口
* array:可变参数
*/
public static Object Query(String sql, ResultSetHandler handler, Object... array) {
try {
connection = MysqlDemo.getConnection();
statement = connection.prepareStatement(sql);
for (int i = 0; i < array.length; i++) {
statement.setObject(i + 1, array[i]);
}
resultSet = statement.executeQuery();
return handler.Handler(resultSet);
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
closeAll(resultSet, statement, connection);
}
}
// 关闭资源
public static void closeAll(ResultSet resultSet, PreparedStatement statement, Connection connection) {
// 关闭resultSet
if (resultSet != null) {
try {
resultSet.close();
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
resultSet = null;
}
}
// 关闭statement
if (statement != null) {
try {
statement.close();
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
statement = null;
}
}
// 关闭connection
if (connection != null) {
try {
connection.close();
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
connection = null;
}
}
}
}
4.2.3、resultSet结果集处理接口类
package com.mysql.dbutil;
import java.sql.ResultSet;
public interface ResultSetHandler {
// 处理resultSet结果集抽象方法
public abstract Object Handler(ResultSet resultSet);
}
4.2.4、处理对象的ResultSetHandler接口实现类 --- BeanResultSetHandler
package com.mysql.dbutil;
import java.lang.reflect.Field;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
public class BeanResultSetHandler implements ResultSetHandler {
//字节码文件对象字段
public Class<?> clazz;
public BeanResultSetHandler(Class<?> clazz) {
this.clazz = clazz;
}
public Object Handler(ResultSet resultSet) {
try {
//通过反射创建实体类对象
Object object = clazz.newInstance();
//获取此 ResultSet 对象的列的编号、类型和属性。
ResultSetMetaData metaData = (ResultSetMetaData) resultSet.getMetaData();
//获取此 ResultSet 对象中的列数
int Columncount = metaData.getColumnCount();
if (resultSet.next()) {
for (int i = 0; i < Columncount; i++) {
//获取指定列的名称
String name = metaData.getColumnName(i + 1);
//通过反射获取字段
Field field = clazz.getDeclaredField(name);
field.setAccessible(true);
//设置字段值
field.set(object, resultSet.getObject(name));
}
}
return object;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
4.2.5、处理集合的ResultSetHandler接口实现类 --- ListResultSetHandler
package com.mysql.dbutil;
import java.lang.reflect.Field;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.util.ArrayList;
import java.util.List;
public class ListResultSetHandler implements ResultSetHandler {
// 字节码文件对象字段
public Class<?> clazz;
public ListResultSetHandler(Class<?> clazz) {
this.clazz = clazz;
}
public Object Handler(ResultSet resultSet) {
try {
List<Object> list = new ArrayList<Object>();
// 获取此 ResultSet 对象的列的编号、类型和属性。
ResultSetMetaData metaData = (ResultSetMetaData) resultSet.getMetaData();
// 获取此 ResultSet 对象中的列数
int Columncount = metaData.getColumnCount();
Object object = null;
while (resultSet.next()) {
// 通过反射创建实体类对象
object = clazz.newInstance();
for (int i = 0; i < Columncount; i++) {
// 获取指定列的名称
String name = metaData.getColumnName(i + 1);
// 通过反射获取字段
Field field = clazz.getDeclaredField(name);
field.setAccessible(true);
// 设置字段值
field.set(object, resultSet.getObject(i + 1));
}
list.add(object);
}
return list;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
4.2.6、处理字段集合的ResultSetHandler接口实现类 --- ColumnResultSetHandler
package com.mysql.dbutil;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;
public class ColumnResultSetHandler implements ResultSetHandler {
// 要查询的字段
public String str;
public ColumnResultSetHandler(String str) {
this.str = str;
}
public Object Handler(ResultSet resultSet) {
try {
List<Object> list = new ArrayList<Object>();
while (resultSet.next()) {
Object object = resultSet.getObject(str);
list.add(object);
}
return list;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
4.2.7、使用方式如下:
public static void main(String[] args) {
// ------------查询数据,并返回一个对象集合------------
String sqlForBean = "select * from student where id=?";
ResultSetHandler handlerForBean = new BeanResultSetHandler(Student.class);
Student student = (Student) MysqlDemo.Query(sqlForBean, handlerForBean, 1);
// ------------查询数据,并返回一个对象集合------------
String sqlForList = "select * from student where sex=?";
ResultSetHandler handlerForList = new ListResultSetHandler(Student.class);
List<Student> list = (List<Student>) MysqlDemo.Query(sqlForList, handlerForList, "男");
// ------------查询数据,并返回一个字段集合------------
String sqlForColumn = "select name from student where sex=?";
ResultSetHandler handlerForColumn = new ColumnResultSetHandler("name");
List<String> listForColumn = (List<String>) MysqlDemo.Query(sqlForColumn, handlerForColumn, "男");
// ------------查询数据,并返回一个字段------------
String sqlForField = "select count(*) from student";
ResultSetHandler handlerForField = new ColumnResultSetHandler("count(*)");
List<Integer> listForField = (List<Integer>) MysqlDemo.Query(sqlForField, handlerForField);
Integer count = listForField.get(0);
}