javaweb阶段问题
秋水 Lv4

JAVAWEB阶段

在字符串判定相等的时候,equals写法以及为什么要这样写

1
if("aaa".equals(code))

这样写的好处,首先这样可以防止如果code为空的话,提示空指针异常错误

关于重定向与请求转发的区别

重定向

1
response.sendRedirect("这里写重定向的URL或者Servlet")

请求转发

1
2
RequestDispatcher dispatcher = request.getRequestDispatcher("页面的相对路径");
dispatcher.include(request, response);

区别:

  1. 重定向是客户端发起的,而请求转发是服务端发起的
  2. 重定向会改变URL地址,而请求转发不会改变URL地址
  3. 重定向中,服务器会在响应头中添加一个新的URL地址,然后通知客户端发送请求到这个地址,这个过程中,产生了两个请求,一个是来自客户端的原始请求,另一个是来自客户端的新请求,因此,原始的请求的数据无法在重定向的过程中传递到新的请求,所以每次重定向,都会产生一个新的请求,每个请求都有独立的数据
  4. 请求转发,由于在同一个服务器内部进行,所以整个过程中只发送一次请求,这意味着所有请求的数据都在同一个请求对象中,可以共享数据。因此,原始请求的所有数据都可以在转发过程中被传递到新的目标资源中

什么是批处理 帮我写一个简单代码看看,他和循环有什么区别

批处理(Batch processing)在编程和信息技术中通常指的是自动处理一批数据或任务的过程。在Java中,这通常涉及到处理一组数据,而不是单独处理每个元素。批处理常用于数据库操作、文件处理和自动化脚本中。

批处理和循环的主要区别在于其处理方式和应用场景:

  • 循环(Loop)通常用于重复执行一段代码,直到满足某个条件。循环可以用于批处理,但它们不是同一个概念。
  • 批处理则侧重于一次性处理一大批数据或任务,通常是自动化的,而且可能不需要实时用户交互。

下面是一个简单的Java批处理示例,用于演示如何在数据库操作中使用批处理。这个例子展示了如何使用JDBC(Java Database Connectivity)批量插入数据到数据库中。请注意,这只是一个示例,你需要根据自己的数据库配置和需求进行调整。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;

public class BatchProcessingExample {
public static void main(String[] args) {
String url = "jdbc:mysql://localhost:3306/your_database";
String username = "your_username";
String password = "your_password";

try (Connection connection = DriverManager.getConnection(url, username, password)) {
connection.setAutoCommit(false);
String sql = "INSERT INTO your_table (column1, column2) VALUES (?, ?)";
try (PreparedStatement statement = connection.prepareStatement(sql)) {
for (int i = 1; i <= 10; i++) {
statement.setString(1, "Value1_" + i);
statement.setString(2, "Value2_" + i);
statement.addBatch();

if (i % 5 == 0) {
statement.executeBatch(); // 执行批处理
connection.commit(); // 提交更改
}
}
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}

在这个例子中,我们创建了一个预备语句,然后循环添加了多个数据集到这个语句中。当累积到一定数量的数据后,我们执行批处理来将这些数据一次性插入到数据库中。这比单次插入每条数据更有效率,尤其是在处理大量数据时。这里用到了循环来构建批处理,但循环本身不是批处理的全部,批处理的关键在于一次性处理多个任务或数据。

我做了一个项目,前端用了vue ,交互用了thymleaf ,那么我想知道的就是,我什么时候用thymeleaf,什么时候又该用vue呢,我有点被他俩搞混了

Vue.js 和 Thymeleaf 在前端开发中扮演着不同的角色,理解它们的基本用途和优势可以帮助你决定在什么情况下使用它们。

  1. Vue.js 是一个现代的JavaScript框架,用于构建交互式和动态的单页应用(SPA)。Vue.js的主要优势在于它的响应式和组件化特性,这让开发复杂的动态界面变得简单。当你需要构建高度交互性的前端,需要与后端API进行大量交互时,Vue.js是一个很好的选择。

  2. Thymeleaf 是一个Java服务器端的模板引擎,用于渲染HTML。Thymeleaf通常在服务器端生成HTML页面,然后将这些页面发送到客户端。它适用于更传统的网页应用,其中页面在服务器端渲染,并且页面的动态性较低。

根据这些特点,你可以这样决定:

  • 当你需要高度动态的、与用户交互密集的界面时,使用Vue.js。Vue.js适合那些需要频繁更新和更改的部分,特别是那些需要与用户进行大量交互的元素。

  • 当你的应用需要在服务器端生成HTML内容,或者对SEO(搜索引擎优化)有较高要求时,使用Thymeleaf。例如,对于那些内容静态、不需要频繁更新的页面,Thymeleaf可能是更好的选择。

在一些项目中,Vue.js和Thymeleaf可以同时使用,但通常需要清晰地区分它们的职责,以避免混淆和潜在的性能问题。例如,你可以在服务器端用Thymeleaf生成页面的初始状态,然后用Vue.js来处理更复杂的交互和动态内容更新。

那比如我出现的一个数据,我是不是可以交给thymleaf去渲染,我是不是也可以给vue去渲染

是的,你可以选择用Thymeleaf或Vue.js来渲染数据,这取决于你的具体需求和应用场景。下面是两种情况的对比:

  1. 使用Thymeleaf渲染数据

    • 场景:适用于服务器端渲染。如果你的数据在页面加载时就已经可用,并且不需要在用户与页面交互时动态更新,那么使用Thymeleaf是合适的。
    • 优势:对搜索引擎优化(SEO)友好,因为内容是在服务器端生成的,易于搜索引擎抓取。适用于内容静态、更新频率不高的页面。
    • 限制:不适合需要频繁更新或与用户交互的动态内容。每次数据更新都可能需要重新加载页面或部分页面。
  2. 使用Vue.js渲染数据

    • 场景:适用于客户端渲染。如果你需要构建一个交互性强的应用,或者数据需要在用户与应用交互时动态更新,Vue.js是更好的选择。
    • 优势:能够创建更丰富的用户界面和更平滑的用户体验。支持数据的实时更新,不需要重新加载整个页面。
    • 限制:对SEO不如服务器端渲染友好。需要额外的JavaScript支持和可能的初始加载时间较长。

综合来看,如果你的应用侧重于用户交互和实时数据更新,Vue.js会是更好的选择。如果你的应用主要展示静态内容,或者需要优化SEO,那么使用Thymeleaf可能更适合。在实际开发过程中,你也可以根据页面的不同部分和功能,灵活选择使用Thymeleaf和Vue.js。例如,对于静态内容部分使用Thymeleaf,而对于需要动态交互的部分使用Vue.js。

如果解决double问题的精度丢失问题呢

使用BigDecimalBigDecimal类提供了精确的浮点数运算。它非常适合需要高精度计算的场景,比如金融计算。使用BigDecimal可以避免常见的浮点数精度问题,但代价是性能和复杂性可能会增加。

示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import java.math.BigDecimal;

public class BigDecimalExample {
public static void main(String[] args) {
// 创建两个BigDecimal对象
BigDecimal value1 = new BigDecimal("123.4567");
BigDecimal value2 = new BigDecimal("89.12345");

// 将两个值相加
BigDecimal sum = value1.add(value2);

// 输出结果
System.out.println("Sum of " + value1 + " and " + value2 + " is: " + sum);
}
}

为什么框架阶段不使用select * 而用具体的列名呢

数据库查询中,尤其是在实际项目开发中,通常不建议使用 SELECT * FROM,而是建议使用具体的列名来代替。这种做法有几个重要原因:

  1. 性能优化:使用 SELECT * 会检索表中的所有列,这可能包含你不需要的数据。这样会增加数据库的负担,减慢查询速度,尤其是当表中有很多列或者包含大型数据类型(如BLOB、CLOB)时。明确指定所需的列可以减少数据传输量,提高查询效率。
  2. 维护性和可读性:当你明确指定列名时,其他开发人员或未来的你可以更容易地理解这个查询的目的。SELECT * 可能会使得理解查询返回的数据变得更加困难,尤其是当表结构变更时。
  3. 兼容性和稳定性:如果数据库表的结构发生变化(如添加、删除或重新排序列),使用 SELECT * 的查询可能会意外地中断或返回不正确的数据。指定列名可以确保即使表结构发生变化,查询也能返回正确的数据。
  4. 安全性:在涉及安全性的上下文中,例如在开发Web应用时,SELECT * 可能会不经意地暴露敏感数据。明确选择所需的列可以帮助确保只有必要的数据被检索和显示。
  5. 与ORM工具的兼容性:在使用对象关系映射(ORM)工具时,通常需要明确指定列名以确保正确的数据映射。

基础阶段

为什么用Integer而不用int呢

  1. 对象而不是原始类型Integerint的包装类,意味着它是一个对象。这允许Integer具有方法和属性,而原始类型int不具备这些特性。
  2. 空值处理Integer可以为null,而int不能。这在某些情况下非常有用,比如在数据库交互中,可以表示一个值是未定义的或缺失的。
  3. 泛型中的使用:Java的泛型不支持原始类型。例如,在使用集合类如ArrayList时,你不能使用原始类型(如int),而必须使用其包装类(如Integer)。
  4. 自动装箱和拆箱:Java 5及更高版本提供了自动装箱(将int转换为Integer)和自动拆箱(将Integer转换为int)的功能。这使得在使用原始类型和包装类型之间进行转换变得简单。
  5. 标准方法和额外功能:由于Integer是一个类,它提供了许多有用的标准方法,比如compareTo, toString, equals等,以及静态方法,如parseInt,这些在原始类型int中是不可用的。
  6. 缺点: 使用Integer也有缺点,比如额外的内存消耗和可能更慢的性能,因为它涉及到对象的创建和管理,而不是直接操作原始类型。

什么时候用抽象类,什么时候用接口

1 共享代码 如果你想要共享多个密切相关的类别,那么抽象类是一个好选择。

2 公共状态:如果多个类有共同的状态(属性) ,那么抽象类可以用来封装

3 控制构造过程 : 当你的类属于一个继承层次结构的,并且共享一个基本形式时,是用抽象类有意义

使用接口

1 多重继承 一个类可以实现多个接口

2 规范行为 接口时定义一些方法规范的理想选择。

3 松耦合 当你希望分离接口和实现以确保编码的灵活性和可维护性时,可以使用接口

4 版本兼容性 使用接口可以帮你创建可扩展的APIs,可以在不影响既有现实的情况下,想接口添加新的默认方法

Mybaits遇到的问题

关于ResultMap级联属性赋值解决多对一映射问题

实体类中除了要有有参构造模式,还要再加一个无参构造模式,不然一直报错

员工表

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
public class Employee {
private Integer id; //员工id
private String lastName; //员工姓名
private String email; //员工邮箱
private Double salary; //员工薪资

private Dept dept;

public Employee(Integer id, String lastName, String email, Double salary, Dept dept) {
this.id = id;
this.lastName = lastName;
this.email = email;
this.salary = salary;
this.dept = dept;
}

public Dept getDept() {
return dept;
}

public void setDept(Dept dept) {
this.dept = dept;
}

public Employee() {
}

public Employee(Integer id, String lastName, String email, Double salary) {
this.id = id;
this.lastName = lastName;
this.email = email;
this.salary = salary;
}

public Integer getId() {
return id;
}

public void setId(Integer id) {
this.id = id;
}

public String getLastName() {
return lastName;
}

public void setLastName(String lastName) {
this.lastName = lastName;
}

public String getEmail() {
return email;
}

public void setEmail(String email) {
this.email = email;
}

public Double getSalary() {
return salary;
}

public void setSalary(Double salary) {
this.salary = salary;
}

@Override
public String toString() {
return "Employee{" +
"id=" + id +
", lastName='" + lastName + '\'' +
", email='" + email + '\'' +
", salary=" + salary +
", dept=" + dept +
'}';
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
public class Dept {
private Integer deptId;
private String deptName;


public Dept() {
}

public Dept(Integer deptId, String deptName) {
this.deptId = deptId;
this.deptName = deptName;
}

public Integer getDeptId() {
return deptId;
}

public void setDeptId(Integer deptId) {
this.deptId = deptId;
}

public String getDeptName() {
return deptName;
}

public void setDeptName(String deptName) {
this.deptName = deptName;
}

@Override
public String toString() {
return "Dept{" +
"deptId=" + deptId +
", deptName='" + deptName + '\'' +
'}';
}
}
1
2
3
4
5
6
7
8
9
10
11
12
 <!-- 自定义映射    -->
<resultMap id="empAndDeptResultMap" type="employee">
<!-- 定义主键字段和 属性的关联关系-->
<id column="id" property="id"></id>
<!-- 定义非主键字段与属性关联关系 -->
<result column="last_name" property="lastName"></result>
<result column="email" property="email"></result>
<result column="salary" property="salary"></result>
<!-- 为员工部门增加属性 -->
<result column="dept_id" property="dept.deptId"></result>
<result column="dept_name" property="dept.deptName"></result>
</resultMap>

错误代码: Cannot set value of property ‘dept.did’ because ‘dept.did’ is null and cannot be instantiated on instance of com.jxxy.mybatis.pojo.Dept. Cause:org.apache.ibatis.reflection.ReflectionException: Error instantiating class com.jxxy.mybatis.pojo.Dept with invalid types () or values (). Cause: java.lang.NoSuchMethodException: com.jxxy.mybatis.pojo.Dept

解决办法: 要在实体类中加入无参构造,然后测试通过。

关于一些不懂的问题的集合

关于System.out.println的区别

Logger类 :提供了各种方法来记录不同级别的信息,比如错误,警示,信息等,开发者可以通过这些方法将重要的信息输出到控制台。

 1. System.out.println:是一个基础的方法,可以用在控制台输出信息,通过用语调试
 1. looger是一个复杂的工具,用于记录日志,不仅可以输出信息到控制台,还可以输出文件,网络。用来记录日志
 1. system.out.println对性能影响比较大,占用系统资源,Logger更加考虑性能
 1. Logger更易于维护和拓展
 1. 
  • Post title:javaweb阶段问题
  • Post author:秋水
  • Create time:2023-11-09 23:40:12
  • Post link:tai769.github.io2023/11/09/codeIssue/
  • Copyright Notice:All articles in this blog are licensed under BY-NC-SA unless stating additionally.