JDBC(Java DataBase Connectivity)
jdbc概念:简而言之就是定义了一套操作所有关系型数据库的规则(接口)
JDBC基本使用
流程:
-->1. 注册驱动
-->2. 获取数据库连接对象
-->3. 定义SQL
-->4. 定义获取执行SQL的对象
-->5. 执行SQL,返回结果集resultSet
-->6. 遍历结果集,封装对象,装载集合
-->7. 释放资源
package com.meng.jdbc; import com.meng.entity.User; import java.sql.*; import java.util.ArrayList; import java.util.List; public class JDBCDemo1 { public static void main(String[] args) { List<User> list = new JDBCDemo1().findAll(); System.out.println(list); } /*** * 查询所有user * @return */ public List<User> findAll() { Connection conn = null; Statement statement = null; ResultSet resultSet = null; List<User> list = null; try { //1.注册驱动 Class.forName("com.mysql.jdbc.Driver"); //2.获取连接 conn = DriverManager.getConnection("jdbc:mysql://localhost/test2", "root", "123456"); //3.定义SQL String sql = "select * from user"; //4.获取执行SQL对象 statement = conn.createStatement(); //5.执行SQL resultSet = statement.executeQuery(sql); //遍历结果集,封装对象,装载集合 User user =null; list =new ArrayList<User>(); while(resultSet.next()){ int id = resultSet.getInt("id"); String name = resultSet.getString("name"); int age = resultSet.getInt("age"); //创建user对象,并赋值 user = new User(); user.setId(id); user.setName(name); user.setAge(age); //装载集合 list.add(user); } } catch (ClassNotFoundException | SQLException e) { e.printStackTrace(); }finally { //释放资源 if(resultSet != null){ try { resultSet.close(); } catch (SQLException e) { e.printStackTrace(); } } if(statement != null){ try { statement.close(); } catch (SQLException e) { e.printStackTrace(); } } if(conn != null){ try { conn.close(); } catch (SQLException e) { e.printStackTrace(); } } } return list; } }
上面这个方案在每次做crud的时候都要重新获取数据库连接对象,我们将封装成一个工具类来简化操作。
JDBCUtils工具类抽取
分析:
1、抽取注册驱动;
2、抽取一个获取数据库连接对象的方法;
*需求:不想在getConnection中传递参数,保证工具类的通用性。
*解决方案: 配置文件方式 jdbc.properties
3、抽取一个释放资源的方法
package com.meng.utils; import java.io.FileReader; import java.io.IOException; import java.net.URL; import java.sql.*; import java.util.Properties; public class JDBCUtils { //静态变量只能被静态方法所访问 private static String url; private static String user; private static String password; private static String driver; /*** * 文件读取只需要执行一次,所以使用静态代码块(随类的加载而加载,在执行构造器之前,并且只执行一次) */ static { /** * 获取静态资源文件 * 使用properties集合类比较方便 */ try { //创建Properties集合类(当使用该集合类时,路径下的任何文件夹名称都不能有中文字符,否则会报FileNotFoundException) Properties properties = new Properties(); //获取src路径下的文件方式 -->ClassLoader(类加载器) ClassLoader classLoader = JDBCUtils.class.getClassLoader(); URL resource = classLoader.getResource("jdbc.properties"); String path = resource.getPath(); System.out.println(path); //加载文件 properties.load(new FileReader(path)); //3. 获取数据,赋值 url = properties.getProperty("url"); user = properties.getProperty("user"); password = properties.getProperty("password"); driver = properties.getProperty("driver"); //注册驱动 Class.forName(driver); } catch (IOException | ClassNotFoundException e) { e.printStackTrace(); } } /*** * 获取连接 * @return */ public static Connection getConnection() throws SQLException { return DriverManager.getConnection(url,user,password); } /*** * 释放资源 * @param statement * @param connection */ public static void close(ResultSet resultSet, Statement statement, Connection connection){ //释放resultSet if(resultSet != null){ try { resultSet.close(); } catch (SQLException e) { e.printStackTrace(); } } //释放statement if(statement != null){ try { statement.close(); } catch (SQLException e) { e.printStackTrace(); } } //释放connection if(connection != null){ try { connection.close(); } catch (SQLException e) { e.printStackTrace(); } } } }
登录小案例(PrepareStatement)
package com.meng.jdbc; import com.meng.utils.JDBCUtils; import java.sql.*; import java.util.Scanner; public class JDBCDemo5 { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); System.out.println("请输入用户名:"); String name = scanner.nextLine(); System.out.println("请输入密码:"); String password = scanner.nextLine(); boolean login = new JDBCDemo4().login(name, password); if (login){ System.out.println("登录成功"); }else{ System.out.println("用户名或密码错误"); } } /** * 登录方法 */ public boolean login(String name,String password){ if(name ==null || password ==null){ return false; } Connection connection = null; PreparedStatement preparedStatement = null; ResultSet resultSet = null; try { connection = JDBCUtils.getConnection(); String sql = "select * from user where name = ? and password = ?"; //通过preparedStatement获取数据库执行对象 preparedStatement = connection.prepareStatement(sql); //给 ? 赋值 preparedStatement.setString(1,name); preparedStatement.setString(2,password); //执行SQL resultSet = preparedStatement.executeQuery(); return resultSet.next(); } catch (SQLException e) { e.printStackTrace(); } finally { JDBCUtils.close(resultSet,preparedStatement,connection); } return false; } }
JDBC事务
1.操作
开启事务:setAutoCommit(boolean autoCommit); //调用该方法设置参数为false,即开启事务
提交事务:commit();
回滚事务:rollback();
2.使用connection来管理事务
package com.meng.jdbc; import com.meng.utils.JDBCUtils; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; public class JDBCDemo6 { public static void main(String[] args) throws SQLException { Connection connection =null; PreparedStatement preparedStatement1 = null; PreparedStatement preparedStatement2 = null; try { connection = JDBCUtils.getConnection(); //开启事务 connection.setAutoCommit(false); String sql1 = "update acount set bonus= bonus-? where id = 1"; String sql2 = "update acount set bonus= bonus+? where id = 2"; preparedStatement1 = connection.prepareStatement(sql1); preparedStatement2 = connection.prepareStatement(sql2); preparedStatement1.setString(1,"500"); preparedStatement2.setString(1,"500"); preparedStatement1.executeUpdate(); // int a = 3/0;如果打开这个地方,出现异常,执行不了第二条SQL语句,执行事务回滚 preparedStatement2.executeUpdate(); //提交事务 connection.commit(); } catch (SQLException e) { try { //事务回滚 connection.rollback(); } catch (SQLException ex) { ex.printStackTrace(); } e.printStackTrace(); }finally { JDBCUtils.close(preparedStatement1,connection); } } }