通过JDBC可以实现Java程序对后端数据库的访问。一般分为建立连接、操作、断开连接三步。
JDBC是java定义的一组访问数据库的接口,使得程序员可以把数据库当做抽象工具来使用。各个数据库厂商去实现这套接口,提供数据库驱动jar包(接口实现类)。
使用JDBC进行增删改查(6步,DJ666)
- 导 jar 包(钱包里装钱)
- 注册驱动(老司机 Driver 心动)
JDBC中的Driver接口是驱动程序的抽象,是每个驱动程序类必须实现的接口。
Class.forName(“com.mysql.jdbc.Driver");
类一加载,就会把自己注册到 DriverManager 类中:static { try { java.sql.DriverManager.registerDriver(new Driver()); //真的有老司机哦 } catch (SQLException E) { throw new RuntimeException("Can't register driver!"); } }
- 连接数据库(要联系方式)
JDBC中的 DriverManager 类(并不是接口)用于管理驱动,从而连接数据库。
Connection conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/数据库名","root","root");
选中数据库即可,SQL语句中的 from 会选中表名。
Connection是数据库连接对象,类似于网络编程中的socket类、IO流中的File类,都是用地址建立连接。
有了连接之后就可以:获取语句对象、管理事务。 - 获得语句对象,执行SQL(撩妹)
Statement stmt = conn.createStatement();
增删改:int count = stmt.executeUpdate("update account set balance = 500 where id = 1");
查询:ResultSet rs = stmt.executeQuery("select * from account");
注意:此处的SQL语句并不加分号!
解决SQL注入问题(向DB注入SQL语句)
PreparedStatement pstmt = conn.prepareStatement(String sql);
传参传的早,因为要拿去做预处理。执行查询的时候不用再传参了。
需要给SQL语句中的占位符?
赋值:
pstmt.setXxx(参数编号,参数值)
,Xxx表示参数的类型。
-
处理结果(一起去看电影)
结果集有next方法,用于遍历,每次一行。遍历的实现类似于迭代器,毕竟没有index。while(rs.next()){ //获取数据,一次获取一个字段,并不是一行数据。与Scanner的next方法类似。 //代码是写死的,不用的表具有不同的字段 int id = rs.getInt(1); String name = rs.getString("name"); double balance = rs.getDouble(3); System.out.println(id + "---" + name + "---" + balance); }
把表映射为类,把查询结果装到集合里面:
Emp emp = null; list = new ArrayList<Emp>(); while(rs.next()){ //获取数据 int id = rs.getInt("id"); String ename = rs.getString("ename"); int job_id = rs.getInt("job_id"); // 创建emp对象,并赋值 emp = new Emp(); emp.setId(id); emp.setEname(ename); emp.setJob_id(job_id); //装载集合 list.add(emp); }
缺点:代码是写死的(不同表,字段不同),仍然有简化空间。
-
关闭资源(防止营养跟不上)
并不是那么容易关闭的,用finally保证一定关闭资源,但是对象不一定存在。finally{ try{ if(rs != null) rs.close(); if(stmt != null) stmt.close(); if(conn != null) conn.close(); }catch(SQLException){ //ignore } }
JDBCUtils
以上6步中除操作SQL的2步外都是固定的,所以抽取成为一个工具类。
很有趣:设计模式里面,为了应对变化,所以把变化的代码封装成一个类,以便替换。在继承里面,是把不变的东西做抽取,然后封装,避免代码重复,工具类同理。
-
导包、注册驱动
注册驱动放在静态代码块儿中,保证只执行一次。(有点像单例模式)
为了代码的灵活性,利用 ClassLoader 获取配置文件路径,然后利用 Properties 进行读取,从而注册驱动。//ClassLoader 类加载器获取src路径下的文件的路径 ClassLoader classLoader = JDBCUtils.class.getClassLoader(); URL res = classLoader.getResource("jdbc.properties"); String path = res.getPath();
为什么要获取文件路径,直接利用类加载器获得流不完了么。
利用properties读取文件不会了?Java IO流 -
获得连接
-
释放资源
释放资源的方法是重载的,因为增删改 和 查的返回值不一样。
JDBC控制事务
使用 Connection 对象管理事务。在上面的代码中,添加以下代码:
- 开启事务(也就是关闭自动提交):
connection.setAutoCommit(false);
- 提交事务:SQL语句之后。
connection.commit();
- 回滚事务:catch中进行回滚。先检查非空,
conn.rollback();
网友评论