java项目开发必备知识(一)

学习目标:

掌握实战项目各种开发过程


学习内容:

某某项目的源码实操,记录常用的“姿势”,

例如:

  1. 架构设计
  2. 掌握 Java 基本语法
  3. 分析各种常用的类以及方法
  4. 掌握开发必备技巧
  5. 分析源码

学习时间:

`7.13


项目涉及的注解类

@EqualsAndHashCode(callSuper = true)

Lombok 提供的一个注解,用于自动生成 Java 类的 equals() 和 hashCode() 方法。它的作用是在生成的方法中,包含父类中的属性。
子类需要使用父类的 equals() 和 hashCode() 方法,那么就可以使用 @EqualsAndHashCode(callSuper = true) 注解。
这样,子类的 equals() 和 hashCode() 方法就会包含父类的属性,从而正确地比较两个对象是否相等。

import lombok.EqualsAndHashCode;

public class Person {
    private String name;
    private int age;

}

@EqualsAndHashCode(callSuper = true)
public class Student extends Person {
    private String id;

}

@Accessors(chain = true):

Lombok的注解,为类字段生成流畅的setter方法,允许多个setter调用在单个语句中连接在一起。

import lombok.Data;
import lombok.experimental.Accessors;

@Data
@Accessors(chain = true)
public class Person {
    private String firstName;
    private String lastName;
    private int age;
}

使用 @Accessors(chain = true)
我们可以链式调用 setter 方法,如下所示:
Person person = new Person()
    .setFirstName("John")
    .setLastName("Doe")
    .setAge(30);

@ApiModelProperty(hidden = true)

@ApiModelProperty(hidden = true) 是 Swagger 注解中的一种,用于在文档中隐藏 API 的某些属性。

 @ApiModelProperty(value = "Password.", example = "password123", required = true, hidden = true)
    private String password;

@RestController

它用于指示一个类是一个 RESTful web 服务控制器。

当一个类被注解为 @RestController,它告诉 Spring 这个类将处理传入的 HTTP 请求并生成 HTTP 响应。响应通常是 JSON 或 XML 格式,尽管它可以是由 Spring 支持的任何格式。
@RestController 是两个其他注解的组合:@Controller 和 @ResponseBody。@Controller 用于指示一个类是一个控制器,而 @ResponseBody 用于指示方法的返回值应该被序列化并作为响应主体发送回去。

Dao层中常用注解(xxDao)

@Repository

@Repository 是 Spring 框架中的注解,用于标识一个类是数据访问层(DAO 层)的组件,可以让Spring自动扫描并创建它的实例

@Resource (@Resource 注解有两种用法,分别为名称匹配和类型匹配。)

@Resource是 Java 中的注解,用于在代码中引用外部资源或依赖。
需要注意的是,@Resource 注解不是 Spring 框架中的注解,它是 Java EE 标准中的注解。
在 Spring 中,通常使用 @Autowired 或 @Inject 注解进行依赖注入。这两个注解与 @Resource 注解的作用类似,但具有更强的类型匹配能力和更多的选项。

例如:在xxDao中利用@Resource引入UserMapper
@Resource
    private UserMapper userMapper;

名称匹配(要配合配置文件):

@Resource(name = "myDataSource")
private DataSource dataSource;
指定了名称为 myDataSource 的资源,它将被注入到 dataSource 字段中。

在 Spring 配置文件中,可以通过 id 或者 name 属性为 Bean 指定一个名称
<bean id="userDaoImpl" class="com.example.dao.UserDaoImpl">
    <!-- ... -->
</bean>

类型匹配:

@Resource
private UserService userService;
如果没有指定名称,它将尝试根据类型进行匹配。如果存在类型为 UserServiceBean,则它将被注入到 userService 字段中。

接口实现类中常用到的注解

@Service

@Service 注解通常用于标识一个类是服务层的组件,它与 @Component 注解类似,但更加具体化,可以让Spring自动扫描并创建它的实例,然后可以使用@Autowired注解将它注入到需要它的地方

@Slf4j

Lombok库提供的注解,用于自动生成日志记录器,自动为类生成一个名为log的静态日志记录器,可以直接调用它的方法进行日志记录,比如log.info(xxx)

  log.info("开始执行方法");

@Autowired

Spring 框架中的注解,用于自动装配 Spring 容器中的 Bean。
Bean 是指通过 Spring 容器管理的对象实例。当一个 Bean 被创建时,它可以在 Spring 容器中注册和存储
另一个 Bean 中需要使用该 Bean 时,可以通过 @Autowired 注解将它注入到需要它的地方。

比如:
1.在Controller中注入需要用到的接口
2.在xxImpl(接口实现类)中注入需要使用的DAO 对象(DAO 层是指数据访问对象层Data Access Object)

Mapper接口常用注解

@Select

是 MyBatis 框架中的注解,用于声明一个查询语句。

@Select("select * from user where third_account_id = #{account_id} limit 1")
 UserDO getByThirdAccountId(@Param("account_id") String accountId);

定义了一个查询语句,它从 user 表中查询 third_account_id 字段等于 account_id 参数的记录,并返回查询结果中的第一条记录。#{account_id} 是 MyBatis 中的占位符,表示一个参数。
方法的参数 accountId 使用了 @Param 注解,指定了参数名称为 account_id。这个注解告诉 MyBatis 在生成 SQL 语句时使用这个名称作为参数名,从而与 SQL 语句中的占位符 #{account_id} 对应。

项目涉及的对象

HttpServletRequest request

HttpServletRequest 是客户端发送到服务器的HTTP请求,
里边包含了客户端请求的所有信息,如**请求的URL、请求方法、请求头、请求参数**等,一般用于读取客户端发送的数据,并根据请求内容生成响应
举例子:如果我们要验证用户的账号和密码,那么客户端发送到服务器的HTTP请求中一定要携带这两个参数,然后在服务器中,利用这个类的方法来获取客户端发送过来的参数,解析账号和密码,最后进行业务操作即可
以下这个接口内部的部分方法:
String getAuthType():获取请求的认证类型。

Cookie[] getCookies():获取请求中的所有 Cookielong getDateHeader(String name):获取请求头中指定名称的日期值。

String getHeader(String name):获取请求头中指定名称的值。

Enumeration<String> getHeaders(String name):获取请求头中指定名称的所有值。

Enumeration<String> getHeaderNames():获取请求头中所有名称的枚举。

int getIntHeader(String name):获取请求头中指定名称的整数值。

HttpServletMapping getHttpServletMapping():获取请求对应的 Servlet 映射信息。

String getMethod():获取请求的 HTTP 方法。

String getPathInfo():获取请求的路径信息。

HttpServletResponse

表示服务器返回客户端的HTTP响应,包含了服务器响应的所有信息,如响应状态码、响应头、响应正文等。常被开发人员用来设置响应状态码、响应头、响应正文等。

public void setHttpServletResponse(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    // 设置响应状态码为 200
    response.setStatus(HttpServletResponse.OK);
    // 设置响应头的 Content-Type 为 text/html
    response.setContentType("text/html");
    // 添加一个响应头
    response.addHeader("X-Header", "HeaderValue");
    // 获取写入响应正文的 PrintWriter 对象
    PrintWriter out = response.getWriter();
    // 写入响应正文
    out.println("xxx");
    // 关闭 PrintWriter 对象
    out.close();
}

Dao层的对象

举例子:

public UserDO getUserByUserName(String userName) {
        LambdaQueryWrapper<UserDO> queryUser = Wrappers.lambdaQuery();
        queryUser.eq(UserDO::getUserName, userName)
                .eq(UserDO::getDeleted, YesOrNoEnum.NO.getCode());
  //UserDO::getUserName 是 Java 8 中的方法引用语法,用于引用 UserDO 类中的 getUserName() 方法。
        return userMapper.selectOne(queryUser);
    }

用到了MyBatis-Plus 实现的查询用户信息的方法,MyBatis-Plus 是 MyBatis 的增强工具库,提供了更加便捷的数据访问操作和查询构建方式。

  1. 使用 Wrappers.lambdaQuery() 方法创建一个 LambdaQueryWrapper 对象
  2. eq() 方法用于设置等于条件
  3. userMapper.selectOne(queryUser) 方法查询符合条件的一条记录

项目涉及的技巧

写接口

接口定义了一组方法签名,但是不用提供方法的具体实现

一般搭配着接口实现类(xxxImpl),在接口实现类中需要使用@Override(在 Java 中,当一个类继承自另一个类或实现了一个接口时,它可以重写父类或接口的方法,以实现自己的行为。)

接口实现类的技巧

接口实现类通常要去调用Dao层,所以通常要 用@Autowired引入xxDao,然后再在xxDao里 用@Resource引入xxMapper(一般就是用来写sql语句的接口)

Mapper接口的方法

BaseMapper(一般我们自己写的mapper接口都要继承这个接口)

BaseMapper 是 MyBatis-Plus 框架中的一个接口,提供了一系列基本的数据访问操作,包括插入、删除、更新和查询等。
我们自己的Mapper接口一般要继承BaseMapper接口例如:

public interface UserMapper extends BaseMapper<UserDO>

然后BaseMapper接口内部如下:

public interface BaseMapper<T> extends Mapper<T>

原始的Mapper接口本身是为空的:


package com.baomidou.mybatisplus.core.mapper;

public interface Mapper<T> {
}

以下是 BaseMapper 中常用的方法:

insert(T entity):插入一条记录;
deleteById(Serializable id):根据 ID 删除一条记录;
deleteByMap(Map<String, Object> columnMap):根据指定的列名和值删除记录;
delete(Wrapper<T> wrapper):根据条件删除记录;
deleteBatchIds(Collection<? extends Serializable> idList):根据 ID 批量删除记录;
updateById(T entity):根据 ID 更新一条记录;
update(T entity, Wrapper<T> wrapper):根据条件更新记录;
selectById(Serializable id):根据 ID 查询一条记录;
selectBatchIds(Collection<? extends Serializable> idList):根据 ID 批量查询记录;
selectByMap(Map<String, Object> columnMap):根据指定的列名和值查询记录;
selectOne(Wrapper<T> wrapper):根据条件查询一条记录;
selectCount(Wrapper<T> wrapper):根据条件查询记录数;
selectList(Wrapper<T> wrapper):根据条件查询多条记录;
selectMaps(Wrapper<T> wrapper):根据条件查询多条记录,并将结果集封装成 MapselectObjs(Wrapper<T> wrapper):根据条件查询多条记录,并将结果集封装成 Object 列表;
selectPage(Page<T> page, Wrapper<T> wrapper):根据条件分页查询记录;
selectMapsPage(Page<T> page, Wrapper<T> wrapper):根据条件分页查询记录,并将结果集封装成 Map

注意:
Wrapper 是 MyBatis-Plus 框架中提供的一个查询条件构造器,用于构建复杂的查询条件。使用 Wrapper 可以在不编写 SQL 语句的情况下构建查询条件,提高查询的可读性和可维护性。
除了 Wrapper,MyBatis-Plus 还提供了其他的查询条件构造器,例如 QueryWrapperLambdaQueryWrapper 等,它们都可以用于构建查询条件。这些查询条件构造器具有不同的优点和用途,可以根据实际情况选择合适的方式来构建查询条件。

条件构造器

QueryWrapper

QueryWrapper:基于实体对象的属性进行查询,支持链式调用和条件组合。

QueryWrapper<UserDO> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("user_name", "admin")
            .ne("deleted", YesOrNoEnum.YES.getCode())
            .likeRight("email", "example.com")
            .orderByAsc("user_id")
            .last("limit 10");
List<UserDO> userList = userMapper.selectList(queryWrapper);
//构建了一个查询条件,包括用户名等于 admin、删除标记不等于 YES、邮箱以 example.com 结尾、按照 user_id 升序排序、限制查询结果为前 10 条记录等多个条件。使用 selectList() 方法执行查询,并返回符合条件的用户列表。

LambdaQueryWrapper

基于 Lambda 表达式进行查询,支持类型安全的属性引用和条件组合。

LambdaQueryWrapper<UserDO> lambdaQueryWrapper = Wrappers.lambdaQuery();
//这里需要传入要检测的对象UserDo,用来和数据库的数据进行对比
lambdaQueryWrapper.eq(UserDO::getUserName, "admin")
                 .ne(UserDO::getDeleted, YesOrNoEnum.YES.getCode())
                 .likeRight(UserDO::getEmail, "example.com")
                 .orderByAsc(UserDO::getUserId)
                 .last("limit 10");
List<UserDO> userList = userMapper.selectList(lambdaQueryWrapper);
//UserDO::getUserName 是 Java 8 中的方法引用语法,用于引用 UserDO 类中的 getUserName() 方法。
//将() -> userDO.getUserName()替换为UserDO::getUserName

在xxxImpl层(接口实现类)捕获异常的技巧

我们通常在进行Dao层操作后会得到一个数据对象,然后进行这个对象的判断,进行if语句后,可以调用一个通用的异常类的方法,比如

 if (user == null) {
            throw ExceptionUtil.of(StatusEnum.USER_NOT_EXISTS, "userName=" + username);
        }

这个异常工具类内部如下:

public class ExceptionUtil {

    public static ForumException of(StatusEnum status, Object... args) {
        return new ForumException(status, args);
    }

}
这个异常工具类会再次返回一个基础异常类

基础异常类如下:

public class ForumException extends RuntimeException
//继承自 RuntimeException,表示这是一个运行时异常。
与普通异常不同,运行时异常(例如空指针异常、数组越界异常等。)在代码中可以不被显式地捕获和处理。
可以使代码更加简洁,因为不需要对这些异常进行显式的捕获和处理。

这样,经过三层封装,就实现了从xxxImpl实现类->封装的异常工具类->自定义的异常类

项目必备方法

String.format()

String.format() 是 Java 中一个常用的字符串格式化方法,用于将指定字符串中的占位符替换为指定的值,生成新的字符串

String.format(String format, Object... args)
%s:表示字符串类型;
%d:表示整数类型;
%f:表示浮点数类型;
%c:表示字符类型;
%b:表示布尔类型;
%n:表示换行符。

String name = "Alice";
int age = 20;
String message = String.format("My name is %s and my age is %d", name, age);
System.out.println(message);

Objects.equals()

是一个条件表达式,用于比较两个值是否相等。

Objects.equals(encPwd(plainPwd), encPwd) 

encPwd(plainPwd) 表示将 plainPwd 明文密码加密后得到的密文密码,encPwd 表示从数据库中查询出来的已加密的密码。
这个表达式的含义是,将用户输入的明文密码加密后得到的密文密码(即 encPwd(plainPwd)),与从数据库中查询出来的已加密的密码(即 encPwd)进行比较,如果相等则返回 true,否则返回 false。

substring()

substring() 方法接收两个参数:第一个参数是一个整数 beginIndex,表示要截取的子串的起始位置(包含);第二个参数是一个整数 endIndex,表示要截取的子串的结束位置(不包含)。如果省略第二个参数,则默认截取到字符串的末尾。

String str = "Hello, world!";
String subStr1 = str.substring(0, 5);   // "Hello"
String subStr2 = str.substring(7, 12);  // "world"
String subStr3 = str.substring(7);      // "world!"

为什么要实现Serializable 接口

  1. Serializable 接口是 Java 中的一个标记接口,它没有任何方法或属性,只是用于标记一个类的实例可以被序列化和反序列化。
  2. 当一个类实现了 Serializable 接口后,这个类的实例就可以被序列化为字节流,从而方便地在网络中传输、存储到文件中或者在不同应用程序之间共享(存储在持久化存储中(如数据库、磁盘文件等)

为什么要重写父类的hashcode和equal

每个对象都有一个默认的 hashCode() 和 equals() 方法。hashCode() 方法根据对象的内部状态计算出一个 hash 值,用于在哈希表等数据结构中快速查找对象;equals() 方法用于比较两个对象是否相等。
默认的 hashCode() 和 equals() 方法是根据对象的内存地址来计算的,而不是根据对象的属性值。因此,如果我们需要根据对象的属性值来比较两个对象是否相等,就需要重写 hashCode() 和 equals() 方法。

重写 hashCode() 和 equals() 方法是为了比较对象是否相等,以及为了让对象能够被正确地存储在哈希表等数据结构中。在实现时需要遵循规范和注意一致性问题。

return a==b

经常用来判断某个条件是否等于某个条件。
如果相等,则返回 true,表示匹配成功;否则返回 false,表示匹配失败。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: Java开发必备知识框架包括Java语言基础、Java集合框架、Java设计模式、Java多线程、Java IO/NIO、Spring、Mybatis、Hibernate、Java Web编程、Java持久层技术、Java中间件等等。 ### 回答2: 当前Java开发必备知识框架有很多,以下是一些常见的框架: 1. Spring框架:Spring是一个轻量级的框架,提供了IoC(控制反转)和AOP(面向切面编程)等功能,可以帮助开发者构建松耦合、可维护和可测试的应用程序。 2. Spring Boot框架:Spring Boot是Spring框架的增强版,通过提供默认配置和快速启动能力,简化了Spring应用程序的开发和部署过程。 3. Hibernate框架:Hibernate是一个ORM(对象关系映射)框架,可以简化Java开发者与数据库之间的交互。它提供了面向对象的API,使得开发者可以使用Java对象进行数据库操作。 4. MyBatis框架:MyBatis是一个持久化框架,通过使用XML或注解配置SQL语句,将Java对象映射到数据库操作上。它提供了灵活性和高度可定制化的特点。 5. Spring MVC框架:Spring MVC是Spring框架的一部分,用于构建基于模型-视图-控制器(MVC)架构的Web应用程序。它提供了简单易用的API和强大的处理请求和响应的能力。 6. Apache Struts框架:Struts是一个基于MVC架构的Web应用程序框架。它通过将请求、响应和业务逻辑分离,可以使开发者更加关注业务实现。 7. Spring Cloud框架:Spring Cloud是一套开发微服务架构的工具集合,包括服务注册与发现、负载均衡、熔断器等组件,可以简化开发分布式系统的复杂性。 以上框架都是当前Java开发必备知识,根据项目需求和个人偏好,可以选择适合的框架来提升开发效率和项目质量。 ### 回答3: 当前Java开发必备知识框架有很多,以下是一些重要的框架: 1. Spring框架:Spring是目前最流行的Java开发框架之一,它提供了一个全面的解决方案,包括依赖注入、面向切面编程和以及集成其他框架的能力。 2. Hibernate框架:Hibernate是一个Java持久化框架,用于简化和优化与数据库的交互。它提供了一个面向对象的数据访问层,让开发人员能够使用面向对象的方式来操作关系型数据库。 3. Spring Boot框架:Spring Boot是一个简化了Spring应用开发的框架,它提供了自动化配置和默认配置,减少了开发人员的配置工作,同时还提供了快速的应用部署和开发体验。 4. MyBatis框架:MyBatis是一个基于Java的持久层框架,它通过XML或注解的方式将Java对象和SQL语句进行映射,提供了一种轻量级的数据库访问解决方案。 5. Spring MVC框架:Spring MVC是一种基于Java的Web应用开发框架,它遵循MVC(模型-视图-控制器)的架构模式,提供了路由、参数绑定、数据验证等功能,使得开发Web应用更加简单和高效。 6. Apache Kafka框架:Apache Kafka是一个分布式流处理平台,它提供了高性能、可扩展的消息传递系统,用于处理实时数据流,适用于构建大规模的实时数据处理和分析应用。 除了以上提到的框架外,还有很多其他的框架,如Spring Cloud、Netty、Elasticsearch、Dubbo等,根据具体的开发需求和项目情况,选择合适的框架对于提高开发效率和产品质量非常重要。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值