1. DO、DTO、VO、POJO

  • DO( Data Object):与数据库表结构一一对应,通过 DAO 层向上传输数据源对象。
  • PO(Persistant Object):持久对象,一个 PO 的数据结构对应着库中表的结构,表中的一条记录就是一个 PO 对象。
  • DTO( Data Transfer Object):数据传输对象,Service 或 Manager 向外传输的对象。
  • BO( Business Object):业务对象。由 Service 层输出的封装业务逻辑的对象。
  • AO( Application Object):应用对象。在 Web 层与 Service 层之间抽象的复用对象模型,极为贴近展示层,复用度不高。
  • VO( View Object):显示层对象,通常是 Web 向模板渲染引擎层传输的对象。
  • POJO( Plain Ordinary Java Object):POJO 专指只有 setter/getter/toString 的简单类,包括 DO/DTO/BO/VO 等。
  • DAO(Data Access Objects):数据访问对象,和上面那些 O 不同的是,其功能是用于进行数据操作的。通常不会用于描述数据实体。

Web 开发基础 - 图1
我们知道,一般情况下,前端是不会凭空造出数据的,因此最后前端展示的数据一定是从数据库中来的,数据的流向通常也是从数据库流向页面。我将其分成三个部分:数据访问业务处理业务解释

  1. 数据访问:这一部分是用于从数据库中读取数据,将数据记录转换成数据实体也就是 Java 对象,便于操作。
  2. 业务处理:这一部分是数据流的核心,几乎所有数据的操作都是在这一部分完成的。
  3. 业务解释:这一部分是用于展示给前端的数据,解释业务体现在某些字段/值是需要经过处理的才会呈现的。
  • DAO,是用于操作数据而不是描述数据的。
  • PO/DO/Entity,其数据结构对应数据表中的一条记录,因此是同一类别的。
  • BO,可以理解为 PO 的组合,举个简单的例子,假设 PO 是一条交易记录,BO 就可以是一个人全部的交易记录集合对象。
  • DTO,用于传输数据,可能传递给前端,也有可能传递给其他系统。用于承载数据
  • VO,这个最好理解,前端最后需要的数据长什么样,对应的对象就是 VO。

    2. JDBC的连接过程

    1. Class.forName("com.mysql.jdbc.Driver"); // 使用反射加载MYSQL JDBC驱动程序
    2. Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/tuke","root","123456");//创建连接对象con
    3. Statement stmt = con.createStatement();
    4. // 声明statement对象
    5. ResultSet rs = stmt.executeQuery("SELECT a, b, c FROM Table1");
    6. // 查询
    7. while (rs.next()) {
    8. int x = rs.getInt("a");
    9. String s = rs.getString("b");
    10. float f = rs.getFloat("c");
    11. }

    3. 拦截器和过滤器的区别

  1. 拦截器是基于 Java 的反射机制的,而过滤器是基于函数回调。
  2. 拦截器不依赖 servlet 容器,过滤器依赖 servlet 容器。
  3. 拦截器只能对 action 请求起作用,而过滤器则可以对几乎所有的请求起作用。
  4. 拦截器可以访问 action上下文、值栈里的对象,而过滤器不能访问。
  5. 在 action 的生命周期中,拦截器可以多次被调用,而过滤器只能在容器初始化时被调用一次。
  6. 拦截器可以获取 IOC 容器中的各个 bean,而过滤器就不行,这点很重要,在拦截器里注入一个service,可以调用业务逻辑。

    4. 多线程中的 i++ 安全吗?为什么

    不安全。i++ 不是原子操作,i++ 分为读取 i 值,对 i 值加一,再赋值给 i,在这三步的任何一步都是有可能被其他线程抢占的。

    5. #{} 和 ${} 的区别是什么

  • ${}是 Properties 文件中的变量占位符,它可以用于标签属性值和 sql 内部,属于静态文本替换,比如${driver}会被静态替换为com.mysql.jdbc.Driver
  • #{}是 sql 的参数占位符,Mybatis 会将 sql 中的#{}替换为?号,在 sql 执行前会使用 PreparedStatement 的参数设置方法,按序给 sql 的?号占位符设置参数值,比如 ps.setInt(0, parameterValue),#{item.name}的取值方式为使用反射从参数对象中获取 item 对象的 name 属性值,相当于param.getItem().getName()

#{} 这种取值是编译好SQL语句再取值,而且可以防止 SQL 注入, ${} 这种是取值以后再去变异 SQL 语句,不能防止 SQL 注入。一般来说,如果可以使用 # 就不要使用 $。


参考

  1. 18道终极Mybatis面试题