JAVA 连接 MySQL 步骤
JDBC实现步骤
1、导入驱动jar包
2、注册驱动
3、获取数据库的连接对象
4、定义sql语句
5、获取执行sql语句的对象
6、执行sql并接收返回结果
7、处理结果
8、释放资源
最简单的格式
public class JdbcDemo {
public static void main(String[] args) throws Exception {
//1、导入驱动jar包
//2、注册驱动
Class.forName("com.mysql.cj.jdbc.Driver");
//3、获取数据库的连接对象
Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "123456");
//4、定义sql语句
String sql = "select * from user ";
//5、获取执行sql语句的对象
Statement stat = con.createStatement();
//6、执行sql并接收返回结果
ResultSet resultSet = stat.executeQuery(sql);
//7、处理结果
while (resultSet.next()) {
System.out.println(resultSet.getString("username") + "\t" + resultSet.getString("email"));
}
//8、释放资源
stat.close();
con.close();
}
}
封装
package dao;
import com.mysql.cj.jdbc.Driver;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.sql.*;
import java.util.*;
/**
* @author 86175
*/
public class DBUtil {
// 数据库对象
private Connection conn = null;// 连接对象
private PreparedStatement pstmt = null;// 预编译
private ResultSet rs = null;// 结果集
private static Driver driver; // 注意是Mysql下的
private static Properties prop;
// 只需类第一次加载时执行的代码 -> 当使用JNDI连接数据库时 可以注释该静态加载
static {
// 新方案:模块化引入
// driver = new OracleDriver();
try {
driver = new Driver();
prop = new Properties();
prop.setProperty("user", "root");
prop.setProperty("password", "123456");
prop.setProperty("driverClassName", "com.mysql.cj.jdbc.Driver");
prop.setProperty("url", "jdbc:mysql://127.0.0.1:3306/test");
} catch (SQLException e) {
e.printStackTrace();
}
}
public Connection getConn() {
try {
conn = driver.connect(prop.getProperty("url"),prop);
} catch (SQLException e) {
e.printStackTrace();
}
return conn;
}
public int update(String sql, Object... params) {
int result = -1;
try {
conn = this.getConn();// 建立连接
pstmt = conn.prepareStatement(sql); // 预编译对象 装载SQL
// 如何给所有占位符 一一注值
setParams(pstmt, params);
result = pstmt.executeUpdate(); // 千万别重复加载SQL
} catch (SQLException e) {
e.printStackTrace();
} finally {
this.closes(null, pstmt, conn);
}
return result;
}
private void setParams(PreparedStatement pstmt, Object... params) {
// 如果没有参数传递 说明执行SQL语句 没有占位符 ?
if (null == params || params.length <= 0) {
return;
}
// 有参数才进行注值操作 循环参数给预编译语句中SQL 占位符注值
for (int i = 0, len = params.length; i < len; i++) {
// 不清楚参数的数据类型 万物皆对象
try {
pstmt.setObject(i + 1, params[i]); // + 1 代表第一个 ?
} catch (SQLException e) {
e.printStackTrace();
}
}
}
public Map<String, Object> findSingle(String sql, Object... params) {
Map<String, Object> map = null;
try {
conn = this.getConn();// 建立连接
pstmt = conn.prepareStatement(sql); // 预编译对象 装载SQL
// 如何给所有占位符 一一注值
setParams(pstmt, params);
rs = pstmt.executeQuery(); // 千万别重复加载SQL
List<String> columnNames = getAllColumnNames(rs);
// 处理结果集
if (rs.next()) {
map = new HashMap<String, Object>();
Object value = null;// 列对应的值
String type = null; // 列值对应类型
// 循环列名集合 获取对应的列名
for (String columnName : columnNames) {
// map.put( columnName, rs.getObject(columnName));
value = rs.getObject(columnName);
// 判空
if (null == value) {
map.put(columnName, value);
continue;
}
/*
* 问题1 不同类型如何兼容处理 BLOB java.math.BigDecimal 如果是Blob类型 该怎么办 ? 图片的处理???
* 想办法获取对应的数据类型?
*/
type = value.getClass().getName();// 列值的类型名称
// System.out.println( type );
}
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
this.closes(rs, pstmt, conn);
}
return map;
}
public List<Map<String, Object>> findMultiple(String sql, Object... params) {
List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
Map<String, Object> map = null;
try {
conn = this.getConn();// 建立连接
pstmt = conn.prepareStatement(sql); // 预编译对象 装载SQL
// 如何给所有占位符 一一注值
setParams(pstmt, params);
rs = pstmt.executeQuery(); // 千万别重复加载SQL
// 获取所有的列名
List<String> columnNames = getAllColumnNames(rs);
// 处理结果集
while (rs.next()) {
map = new HashMap<String, Object>();
Object value = null;// 列对应的值
String type = null; // 列值对应类型
// 循环列名集合 获取对应的列名
for (String columnName : columnNames) {
map.put(columnName, rs.getObject(columnName));
value = rs.getObject(columnName);
// 判空
if (null == value) {
map.put(columnName, value);
continue;
}
type = value.getClass().getName();// 列值的类型名称
}
// map存入list集合中
list.add(map);
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
this.closes(rs, pstmt, conn);
}
return list;
}
public List<String> getAllColumnNames(ResultSet rs) {
// 存储查询数据中的列名
List<String> list = new ArrayList<String>();
try {
// getMetaData() 检索此 ResultSet对象的列的数量,类型和属性
ResultSetMetaData rsmd = rs.getMetaData();
// ResultSetMetaData 可用于获取有关ResultSet对象中列的类型和属性的信息的对象
// 获取列的数量
int columnCount = rsmd.getColumnCount();
// 列的范围 确定
for (int i = 1; i <= columnCount; i++) {
// 获取对应顺序的列名 默认 列名大写 转化成小写
list.add(rsmd.getColumnName(i).toLowerCase());// 第一列
}
} catch (SQLException e) {
e.printStackTrace();
}
return list;
}
// 动态SQL查询语句 对应的动态参数 多条件查询 更新 新增代码
public Map<String, Object> findSingle(String sql, List<Object> params) {
// 如果没有参数传递 说明执行SQL语句 没有占位符 ?
if (null == params || params.size() <= 0) {
return this.findSingle(sql);
}
return this.findSingle(sql, params.toArray());
}
// 多条查询
public List<Map<String, Object>> findMultiple(String sql, List<Object> params) {
// 如果没有参数传递 说明执行SQL语句 没有占位符 ?
if (null == params || params.size() <= 0) {
return this.findMultiple(sql);
}
return this.findMultiple(sql, params.toArray());
}
// 动态更新
public int update(String sql, List<Object> params) {
// 如果没有参数传递 说明执行SQL语句 没有占位符 ?
if (null == params || params.size() <= 0) {
return this.update(sql);
}
return this.update(sql, params.toArray());
}
public int update(List<String> sqls, List<List<Object>> params) throws SQLException {
int result = -1;//定义默认的范围值
try {
conn = this.getConn();//获取连接
//将提交方式设置为手动提交 JDBC 默认自动提交 true
conn.setAutoCommit( false);
for(int i = 0, len = sqls.size(); i < len; i ++) {
pstmt = conn.prepareStatement(sqls.get(i));//预编译对象装载SQL -> list
this.setParams(pstmt, params.get(i).toArray());//需要给占位符注入参数
result = pstmt.executeUpdate();//执行更新语句
}
conn.commit();//事务提交
} catch (SQLException e) {
e.printStackTrace();
conn.rollback();//事务提交
} finally {
conn.setAutoCommit( true); //恢复提交方法是 -> 自动提交
this.closes(rs, pstmt, conn);
}
return result;
}
public int total(String sql, Object ... params){
int result = 0;
try {
conn = this.getConn();
pstmt = conn.prepareStatement(sql);
// 设置参数
setParams(pstmt, params);
// 执行语句块
rs = pstmt.executeQuery();
// 处理结果集
if(rs.next()){
result = rs.getInt(1);// 列索引 第一列
}
} catch (Exception e) {
e.printStackTrace();
} finally{
this.closes(rs, pstmt, conn);
}
return result;
}
// 动态SQL查询 句 对应的动态参数 多条件查询的更新或查询 新增的代码
public <T> List<T> findMultiple (Class<T> cls, String sql, List<Object> params) {
// 如果没有参数传递 说明执行SQL语句 没有占位符 ?
if( params == null || params.isEmpty() ) { // 参数列表无数据
return this.findMultiple(cls, sql, params);
}
return this.findMultiple(cls, sql, params.toArray());
}
// 单条动态查询
public <T> T findSingle(Class<T> cls ,String sql, List<Object> params) {
if (null == params || params.size() <= 0) {
return this.findSingle(cls, sql);
}
return this.findSingle(cls, sql, params.toArray());
}
// 新增动态SQL查询总数
public int total(String sql, List<Object > params) {
if( params == null || params.isEmpty() ) { // 参数列表无数据
return this.total(sql);
}
return this.total(sql, params.toArray() );
}
public <T> List<T> findMultiple( Class<T> cls ,String sql, Object ... params){
List<T> list = new ArrayList<T>();
try {
conn = this.getConn();//获取连接
pstmt = conn.prepareStatement(sql);//预编译对象装载SQL
this.setParams(pstmt, params);//需要给占位符注入参数
rs = pstmt.executeQuery();//执行更新语句
//现获取所有的列名
List<String> columnNames = this.getAllColumnNames(rs);
T t = null ; // 声明一个对象
Object value = null;// 列所对应的值
String typeName = "";// 列所对应的值的类型
// 同通过反射获取当前类中所有的方法methods
Method[] methods = cls.getDeclaredMethods();
while( rs.next()) { //处理结果集
// 调用无参数 的构造方法 AdminInfo admin = new AdminInfo();
t = cls.newInstance();
// 循环列名集合 获得对应的列名
for(String columnName : columnNames) {
//列对应的类型不确定
value = rs.getObject(columnName);
//判空
if( null == value) { // 数据库无数据
continue;
}
// 循环类中所有的方法
for (Method method : methods) {
// 是否有对应的 setXXX 方法名 set + columnName -> setAid method的名字
String name = "set" + columnName;
// 获取列对应值的类型
typeName = value.getClass().getName();
// System.out.println(typeName); //oracle.sql.BLOB java.math.BigDecimal
// 找到对应的方法名 并激活方法
if( name.equalsIgnoreCase( method.getName())) {
// 判断数据类型
if("java.math.BigDecimal".equals(typeName)) {
try {
method.invoke( t, rs.getDouble( columnName ));
}catch(Exception e) {
method.invoke( t, rs.getString( columnName ));
}
}else if("java.lang.String".equals(typeName)) {
method.invoke( t, rs.getString( columnName ));
}else if("java.lang.Double".equals(typeName)) {
method.invoke( t, rs.getDouble( columnName ));
}else if("java.lang.Integer".equals(typeName)) {
method.invoke( t, rs.getInt( columnName ));
}else if("java.lang.Date".equals(typeName)) {
// MySQL 中date 数据类型 转换成JavaBean 对象中使用String
method.invoke( t, rs.getString( columnName ));
}else if("oracle.sql.BLOB".equals(typeName)) {
// 获取对应类型数据
Blob blob = rs.getBlob(columnName);
// 获取对应二进制流操作
try(InputStream is = blob.getBinaryStream()){
byte [] bt = new byte[ (int)blob.length()];
is.read(bt);
method.invoke( t, bt);
}catch(IOException e) {
e.printStackTrace();
}
}else {
// TODO 后期需要 自行扩展
}
}
}
}
list.add(t);
}
} catch (InstantiationException | IllegalAccessException | IllegalArgumentException |
InvocationTargetException | SQLException e) {
e.printStackTrace();
}finally {
this.closes(rs, pstmt, conn);
}
return list;
}
public <T> T findSingle( Class<T> cls ,String sql, Object ... params){
T t = null ; // 声明一个对象
try {
conn = this.getConn();//获取连接
pstmt = conn.prepareStatement(sql);//预编译对象装载SQL
this.setParams(pstmt, params);//需要给占位符注入参数
rs = pstmt.executeQuery();//执行更新语句
//现获取所有的列名
List<String> columnNames = this.getAllColumnNames(rs);
Object value = null;// 列所对应的值
String typeName = "";// 列所对应的值的类型
// 同通过反射获取当前类中所有的方法methods
Method[] methods = cls.getDeclaredMethods();
if( rs.next()) { //处理结果集
// 调用无参数 的构造方法 AdminInfo admin = new AdminInfo();
t = cls.newInstance();
// 循环列名集合 获得对应的列名
for(String columnName : columnNames) {
//列对应的类型不确定
value = rs.getObject(columnName);
//判空
if( null == value) { // 数据库无数据
continue;
}
// 循环类中所有的方法
for (Method method : methods) {
// 是否有对应的 setXXX 方法名 set + columnName -> setAid method的名字
String name = "set" + columnName;
// 获取列对应值的类型
typeName = value.getClass().getName();
// 找到对应的方法名 并激活方法
if( name.equalsIgnoreCase( method.getName())) {
// 判断数据类型
if("java.math.BigDecimal".equals(typeName)) {
try {
method.invoke( t, rs.getDouble( columnName ));
}catch(Exception e) {
method.invoke( t, rs.getString( columnName ));
}
}else if("java.lang.String".equals(typeName)) {
method.invoke( t, rs.getString( columnName ));
}else if("java.lang.Double".equals(typeName)) {
method.invoke( t, rs.getDouble( columnName ));
}else if("java.lang.Integer".equals(typeName)) {
method.invoke( t, rs.getInt( columnName ));
}else if("java.sql.Date".equals(typeName)) {
// MySQL 中date 数据类型 转换成JavaBean 对象中使用String
method.invoke( t, rs.getString( columnName ));
}else {
// TODO 后期需要 自行扩展
}
}
}
}
}
} catch ( InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException | SQLException e) {
e.printStackTrace();
}finally {
this.closes(rs, pstmt, conn);
}
return t;
}
/**
* 多组sql语句执行
* @param sqls
* @param pramas
* @return
*/
public int update1(List<String> sqls, List<List<Object>> pramas) {
int result = -1;//定义失败的默认返回值
try {
conn = this.getConn();
// 事务原子性 要事务全部完成才能提交 所以提交改成手动提交
conn.setAutoCommit(false);
//循环处理SQL集合
for (int i = 0, len = sqls.size(); i < len; i++) {
pstmt = conn.prepareStatement(sqls.get(i));
this.setParams(sqls.get(i), pramas.get(i).toArray());
result = pstmt.executeUpdate();
}
conn.commit();// 事务提交
} catch (SQLException e) {
e.printStackTrace();
try {
result = -1;
conn.rollback();// 事务回滚
} catch (SQLException e1) {
e1.printStackTrace();
// ConstantValues.logger.info("多SQL事务更新回滚" + e1);
}
} finally {
try {
conn.setAutoCommit(true);// 回复事务自动提交
this.closes(null, pstmt,conn);
} catch (SQLException e) {
e.printStackTrace();
}
}
return result;
}
/**
* 插入参数到sql语句中
* @param sql
* @param pramas
*/
private void setParams(String sql, Object ...pramas) {
for (int i = 0, len = pramas.length; i < len; i++) {
try {
pstmt.setObject(i + 1, pramas[i]);
} catch (SQLException e) {
e.printStackTrace();
// ConstantValues.logger.info("第" + (i+1) + "个参数注入失败!" + e);
}
}
}
// 7、关闭资源 先开启的后关闭 后开启的先关闭 结果集 -> 语句块 -> 连接
public void closes(ResultSet rs, PreparedStatement pstmt, Connection conn) {
if (null != rs) {
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (null != pstmt) {
try {
pstmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (null != conn) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
// public static void main(String[] args) {
// DBUtil dbUtil = new DBUtil();
// List<Map<String, Object>> multiple = dbUtil.findMultiple("select * from user");
// System.out.println(multiple.size());
// }
}

浙公网安备 33010602011771号