【Java链接MySQL】
1、搭建环境,按照使用的数据库,去下载对应的 jdbc驱动包(jar文件),必须对应好数据库的版本。
2、在项目中,根目录下,创建文件夹 /lib
3、将驱动jar文件放入其中
4、将第三方受信或不受信的jar加入到当前项目中
数据库对象:
链接数据库操作,有五大对象:
Connection: 数据库链接对象
DirverManager: 驱动管理对象
Statement: sql语句的执行对象
ResultSet: DQL返回的查询结果集对象
SQLExctption: 数据库异常处理对象
所有的jdbc操作,都属于:
import java.sql.*;
反射机制,注册驱动程序:
Class.forName("com.mysql.jdbc.Driver");
实例:
1、执行DML
import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import java.sql.Statement; public class _01_执行DML { public static void main(String[] args) { // 执行DML:insert, update, delete // 语句执行完毕,返回的是:int 受影响的行数 try { //【第一步:注册驱动】 // 为项目注册加载链接数据库的驱动代码 Class.forName("com.mysql.jdbc.Driver"); //【第二步:从驱动管理中心,获取一个链接对象】 // (url, user, pass) // url:链接的协议及服务器端口和库 // user:用户名(root) // pass:密码(123456) Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/web05?characterEncoding=utf-8","root","123456"); //【第三步:基于这个链接对象conn,创建一个语句执行对象】 Statement stat = conn.createStatement(); //【第四步:调用方法,执行t-sql语句】 // executeUpdate() // 这个方法,统一执行所有的DML(insetr, update, delete) // 执行完毕,返回int,受影响的行数 int rows = stat.executeUpdate("INSERT INTO `users` VALUES (null, 'a张三', '123456', null, '保密', '88', default);"); //【第五步:及时关闭链接】 stat.close(); conn.close(); //判断结果 if(rows > 0) { System.out.println("数据添加成功!"); } else { System.out.println("语句已经执行,但是没有数据变动!"); } } catch (ClassNotFoundException e) { System.out.println("找不到驱动程序!"); } catch (SQLException e) { System.out.println("数据库无法链接!"); } } }
2、执行DQL
import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; public class _02_执行DQL { public static void main(String[] args) { // 执行DQL:select // 返回的是一个查询结果集合 //【第一步:独立声明对象】 Connection conn = null; //链接对象 Statement stat = null; //语句执行对象 ResultSet rs = null; //查询结果集对象 try { //【第二步:注册驱动程序】 Class.forName("com.mysql.jdbc.Driver"); //【第三步:获取链接对象】 conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/web05?characterEncoding=utf-8","root","123456"); //【第四步:语句执行对象】 stat = conn.createStatement(); //【第五步:调用方法,执行t-sql语句】 // executeQuery("") // 返回查询结果集 ResultSet rs = stat.executeQuery("select * from `users`;"); //【第六步:操作结果集】 // ResultSet rs对象,有一个方法:.next() // 它有一个指针,默认指向开始的位置 // .next() 会自动往下移动一行,返回true // 如果返回了false,就表示结束了 if(rs != null) { //有结果,利用无限循环,调用next方法, //一行行往下移动 while(rs.next()) { //提取数据,按照列的序号提取的,从第1列开始 //也可以直接指定列名 //提取的时候,可以直接使用对应方法获取对应类型 int id = rs.getInt(1);//序号 System.out.print(id); String username = rs.getString("username");//列名 System.out.println(username); } } else { System.out.println("没有查询结果!"); } } catch (ClassNotFoundException e) { System.out.println("找不到驱动程序!"); } catch (SQLException e) { System.out.println("数据库链接失败,协议,用户名,密码,端口中有错误!"); } finally { try { rs.close(); } catch (SQLException e) { System.out.println("结果集对象有操作,无法关闭!"); } try { stat.close(); } catch (SQLException e) { System.out.println("正在执行语句操作,无法关闭!"); } try { conn.close(); } catch (SQLException e) { System.out.println("数据库链接对象挂起了,无法关闭!"); } } } }
关于实行语句参数的优化:
当我们执行sql语句的时候,都会去组合语句中需要的各种参数。
可以使用字符串组合的方式,
但是更推荐使用参数化操作的方式,
不要创建Statement,它只支持字符串自定义组合。
推荐:
PreparedStatement 参数化语句执行对象.
它利用问号表示占位,替换内容更好。
参数化实例:
import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.Scanner; public class _03_参数化操作 { public static void main(String[] args) { //提示获取用户输入信息 Scanner scan = new Scanner(System.in); System.out.print("用户名:"); String username = scan.next(); System.out.print("密码:"); String userpass = scan.next(); //------------------------------------ try { //注册驱动 Class.forName("com.mysql.jdbc.Driver"); //链接对象 Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/web05?characterEncoding=utf-8","root","123456"); //语句执行对象 //Statement stat = conn.createStatement(); //组合字符串执行,得到结果 //ResultSet rs = stat.executeQuery("select * from `users` where `username`='"+username+"' and `userpass`='"+userpass+"';"); //【推荐】 // 使用 PreparedStatement 对象,先编译好语句, // 然后代入参数,更安全 // 要代入参数的地方,直接一个问号 PreparedStatement pstat = conn.prepareStatement("select * from `users` where `username`=? and `userpass`=?;"); //添加参数 //数值表示第几个问号,后面提供数据 //什么类型的值,就点set什么类型 pstat.setString(1, username); pstat.setString(2, userpass); //执行 ResultSet rs = pstat.executeQuery(); if( rs.next() ) { System.out.println("登录成功!欢迎您:" + rs.getString("username")); } else { System.out.println("用户名或密码错误!"); } rs.close(); pstat.close(); conn.close(); } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
事务机制:
JDBC链接数据库操作,提供了事务机制。
把多个独立操作,变成一个整体的,这些操作,要么都做,要么都不做。
默认操作数据库的语句,都是自动提交数据库的commit,
开发者可以通过代码,关闭自动提交功能:
Connection.setAutoCommit(false);
insert, update, delete这三种操作,语句执行完毕,
必须手工定义代码,执行提交:
Connection.commit();
这样才会更新数据库原始表,否则原始表是不变动的。
如果中途出现了未知问题,可以回滚之前做的所有操作:
Connection.rollback();
实例:
import java.sql.*; public class _04_事务机制 { public static void main(String[] args){ //默认jdbc执行操作,是直接更新原始表的 //应为数据库mysql是打开 自动提交功能的 autocommit=true //可以更改数据配置文件,关闭自动提交。 //通过jdbc也可以操作, //将多个独立执行,作为一个整体,要么全部执行,要么都不执行 //链接对象 Connection conn = null; //参数化执行对象 PreparedStatement pstat = null; try { //注册驱动 Class.forName("com.mysql.jdbc.Driver"); //链接对象 conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/web05?characterEncoding=utf-8","root","123456"); //【设置自动提交:关闭】 conn.setAutoCommit(false); //张三转出:300元 pstat = conn.prepareStatement("update `yonghu` set `money`=`money`-300 where `id`=1;"); //执行 pstat.executeUpdate(); //测试,强制抛出异常,终止操作 if(true) { throw new SQLException("测试异常!"); } //李四转入:300元 pstat = conn.prepareStatement("update `yonghu` set `money`=`money`+300 where `id`=2;"); //执行 pstat.executeUpdate(); //【如果执行到这里,说明没有问题,提交所有操作】 conn.commit(); //提示 System.out.println("操作已成功!"); } catch(Exception ex) { try { //出现运行时的异常,所有操作回滚 conn.rollback(); //提示 System.out.println("转账失败!"); } catch (SQLException e) { e.printStackTrace(); } } finally { try { pstat.close();//关闭 } catch (SQLException e) { e.printStackTrace(); } try { conn.close();//关闭 } catch (SQLException e) { e.printStackTrace(); } } } }