先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7
深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年最新Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上Java开发知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新
如果你需要这些资料,可以添加V获取:vip1024b (备注Java)
正文
* 需要排除的属性名
*
* @since 3.3.1
*/
String[] excludeProperty() default {};
}
* @TableId 主键注解,看看其源码:
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.ANNOTATION_TYPE})
public @interface TableId {
/**
* 字段值(驼峰命名方式,该值可无)
*/
String value() default “”;
/**
* 主键ID
* {@link IdType}
*/
IdType type() default IdType.NONE;
}
其中IdType很重要:
| 名称 | 描述 |
| --- | --- |
| AUTO | 数据库自增ID |
| NONE | 该类型为未设置主键类型(注解里等于跟随全局,全局里约等于 INPUT) |
| INPUT | 用户自己设置的ID |
| ASSIGN\_ID | 当用户传入为空时,自动分配类型为Number或String的主键(雪花算法) |
| ASSIGN\_UUID | 当用户传入为空时,自动分配类型为String的主键 |
* @TableFiled 表字段标识,下面看看其主要常用属性:
| 名称 | 描述 |
| --- | --- |
| value | 数据库字段名 |
| condition | 字段 `where` 实体查询比较条件,通过`SqlCondition`设置 如果未设置条件,则按照正常相等来查询 若设置则按照以下规则: 等于:EQUAL = "%s=#{%s}"; 不等于:NOT\_EQUAL = "%s<>#{%s}"; 左右模糊:LIKE = "%s LIKE CONCAT('%%',#{%s},'%%')"; oracle左右模糊ORACLE\_LIKE = "%s LIKE CONCAT(CONCAT('%%',#{%s}),'%%')"; 左模糊:LIKE\_LEFT = "%s LIKE CONCAT('%%',#{%s})"; 右模糊:LIKE\_RIGHT = "%s LIKE CONCAT(#{%s},'%%')"; |
| fill | 自动填充策略,通过`FieldFill`设置 不处理:FieldFill.DEFAULT 插入时填充字段:FieldFill.INSERT 更新时填充字段:FieldFill.UPDATE 插入或新增时填充字段:FieldFill.INSERT\_UPDATE |
关于其他的属性,我不太推荐使用,用得越多,越容易蒙圈。可以通过wapper查询去设置。
### 2.2 CRUD
mybatis-plus封装好了一条接口供我们直接调用。关于内部的具体方法,在使用时候自己体会吧,此处不列举了。
2.2.1 Service层CRUD
我们使用的时候,需要在自己定义的service接口当中继承`IService`接口:
import com.baomidou.mybatisplus.extension.service.IService;
import com.wjbgn.user.entity.UserDO;
/**
* @description: 用户服务接口
* @author:weirx
* @date:2022/1/17 15:02
* @version:3.0
*/
public interface IUserService extends IService {
}
同时要在我们的接口实现impl当中继承`ServiceImpl`,实现自己的接口:
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wjbgn.user.entity.UserDO;
import com.wjbgn.user.mapper.UserMapper;
import com.wjbgn.user.service.IUserService;
/**
* @description: 用户接口实现
* @author:weirx
* @date:2022/1/17 15:03
* @version:3.0
*/
public class UserServiceImpl extends ServiceImpl<UserMapper, UserDO> implements IUserService {
}
2.2.2 Mapper层CRUD
mybatis-plus将常用的CRUD接口封装成了`BaseMapper`接口,我们只需要在自己的Mapper中继承它就可以了:
/**
* @description: 用户mapper
* @author:weirx
* @date:2022/1/17 14:55
* @version:3.0
*/
@Mapper
public interface UserMapper extends BaseMapper {
}
### 2.3 分页
使用分页话需要增加分页插件的配置:
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
@MapperScan(“com.wjbgn..mapper”)
public class MybatisPlusConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
return interceptor;
}
}
如上配置后,我们直接使用分页方法就行。
### 2.4 逻辑删除配置
很多情况下我们的系统都需要逻辑删除,方便恢复查找误删除的数据。
通过mybatis-plus可以通过全局配置的方式,而不需要再去手动处理。针对更新和查询操作有效,新增不做限制。
通常以我的习惯逻辑删除字段通常定义为`is_delete`,在实体类当中就是`isDelete`。那么在配置文件中就可以有如下的配置:
mybatis-plus:
global-config:
db-config:
logic-delete-field: isDelete # 全局逻辑删除的实体字段名(since 3.3.0,配置后可以忽略不配置步骤2)
logic-delete-value: 1 # 逻辑已删除值(默认为 1)
logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)
或者通过注解`@TableLogic`
@TableLogic
private Integer isDelete;
### 2.5 通用枚举配置
相信后端的同学都经历过一个情况,比如`性别`这个字段,分别值和名称对应`1男`、`2女`,这个字段在数据库时是数值类型,而前端展示则是展示字符串的名称。有几种常见实现方案呢?
* 数据库查询sql通过case判断,返回名称,以前oracle经常这么做
* 数据库返回的值,重新遍历赋值进去,这时候还需要判断这个值到底是男是女。
* 前端写死,返回1就是男,返回2就是女。
相信无论哪种方法都有其缺点,所以我们可以使用mybatis-plus提供的方式。我们在返回给前端时:
* 只需要在遍历时get这个枚举,直接赋值其名称,不需要再次判断。
* 直接返回给前端,让前端去去枚举的name
这样大家都不需要写死这个值。
下面看看如何实现这个功能:
* 性别枚举,实现IEnum接口:
import com.baomidou.mybatisplus.annotation.IEnum;
import com.fasterxml.jackson.annotation.JsonFormat;
/**
* @description: 性别枚举
* @author:weirx
* @date:2022/1/17 16:26
* @version:3.0
*/
@JsonFormat(shape = JsonFormat.Shape.OBJECT)
public enum SexEnum implements IEnum {
MAN(1, “男”),
WOMAN(2, “女”);
private Integer code;
private String name;
SexEnum(Integer code, String name) {
this.code = code;
this.name = name;
}
@Override
public Integer getValue() {
return code;
}
public String getName() {
return name;
}
}
@JsonFormat注解为了解决枚举类返回前端只展示构造器名称的问题。
* 实体类性别字段
@TableName(value = “user”)
public class UserDO {
/**
* 主键
*/
@TableId(value = “id”, type = IdType.AUTO)
private Long id;
/**
* 昵称
*/
@TableField(value = “nickname”,condition = SqlCondition.EQUAL)
private String nickname;
/**
* 性别
*/
@TableField(value = “sex”)
private SexEnum sex;
/**
* 版本
*/
@TableField(value = “version”,update = “%s+1”)
private Integer version;
/**
* 时间字段,自动添加
*/
@TableField(value = “create_time”,fill = FieldFill.INSERT)
private LocalDateTime createTime;
}
* 配置文件扫描枚举
mybatis-plus:
# 支持统配符 * 或者 ; 分割
typeEnumsPackage: com.wjbgn.*.enums
* 定义配置文件
@Bean
public MybatisPlusPropertiesCustomizer mybatisPlusPropertiesCustomizer() {
return properties -> {
GlobalConfig globalConfig = properties.getGlobalConfig();
globalConfig.setBanner(false);
MybatisConfiguration configuration = new MybatisConfiguration();
configuration.setDefaultEnumTypeHandler(MybatisEnumTypeHandler.class);
properties.setConfiguration(configuration);
};
}
* 序列化枚举值为数据库值,以下我是使用的fastjson,全局(添加在前面的配置文件中):
Bean
public MybatisPlusPropertiesCustomizer mybatisPlusPropertiesCustomizer() {
// 序列化枚举值为数据库存储值
FastJsonConfig config = new FastJsonConfig();
config.setSerializerFeatures(SerializerFeature.WriteEnumUsingToString);
return properties -> {
GlobalConfig globalConfig = properties.getGlobalConfig();
globalConfig.setBanner(false);
MybatisConfiguration configuration = new MybatisConfiguration();
configuration.setDefaultEnumTypeHandler(MybatisEnumTypeHandler.class);
properties.setConfiguration(configuration);
};
}
* 局部
JSONField(serialzeFeatures= SerializerFeature.WriteEnumUsingToString)
private SexEnum sex;
### 2.6 自动填充
还记得前面提到的实体类当中的注解`@TableFeild`吗?当中有个属性叫做fill,通过`FieldFill`设置属性,这个就是做自动填充用的。
public enum FieldFill {
/**
* 默认不处理
*/
DEFAULT,
/**
* 插入填充字段
*/
INSERT,
/**
* 更新填充字段
*/
UPDATE,
/**
* 插入和更新填充字段
*/
INSERT_UPDATE
}
但是这个直接是不能使用的,需要通过实现mybatis-plus提供的接口,增加如下配置:
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
/**
* description: 启动自动填充功能
* @return:
* @author: weirx
* @time: 2022/1/17 17:00
*/
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
@Override
public void insertFill(MetaObject metaObject) {
// 起始版本 3.3.0(推荐使用)
this.strictInsertFill(metaObject, “createTime”, LocalDateTime.class, LocalDateTime.now());
}
@Override
public void updateFill(MetaObject metaObject) {
// 起始版本 3.3.0(推荐)
this.strictUpdateFill(metaObject, “updateTime”, LocalDateTime.class, LocalDateTime.now());
}
}
字段如下:
/**
* 时间字段,自动添加
*/
@TableField(value = “create_time”,fill = FieldFill.INSERT)
private LocalDateTime createTime;
### 2.7 多数据源
前面提到过,配置文件当中配置了主从的方式,其实mybatis-plus还支持更多的方式:
* 多主多从
spring:
datasource:
dynamic:
primary: master #设置默认的数据源或者数据源组,默认值即为master
strict: false #严格匹配数据源,默认false. true未匹配到指定数据源时抛异常,false使用默认数据源
datasource:
master_1:
master_2:
slave_1:
slave_2:
slave_3:
* 多种数据库
spring:
datasource:
dynamic:
primary: mysql #设置默认的数据源或者数据源组,默认值即为master
strict: false #严格匹配数据源,默认false. true未匹配到指定数据源时抛异常,false使用默认数据源
datasource:
mysql:
oracle:
postgresql:
h2:
sqlserver:
* 混合配置
spring:
datasource:
dynamic:
primary: master #设置默认的数据源或者数据源组,默认值即为master
strict: false #严格匹配数据源,默认false. true未匹配到指定数据源时抛异常,false使用默认数据源
datasource:
master_1:
slave_1:
slave_2:
oracle_1:
oracle_2:
上面的三种方式,除了混合配置,我觉得都有肯能出现的吧。
* @DS注解
可以注解在方法上或类上,**同时存在就近原则 【方法上注解】 优先于 【类上注解】**:
@DS(“slave_1”)
public class UserServiceImpl extends ServiceImpl<UserMapper, UserDO> implements IUserService {
@DS(“salve_1”)
@Override
public List getList() {
return this.getList();
}
@DS(“master”)
@Override
public int saveUser(UserDO userDO) {
boolean save = this.save(userDO);
if (save){
return 1;
}else{
return 0;
}
}
}
三、测试
----
经过上面的配置,下面开始进入测试验证阶段。
建立一张表:
CREATE TABLE user
(
id
int(11) NOT NULL AUTO_INCREMENT,
nickname
varchar(255) NOT NULL COMMENT ‘昵称’,
sex
tinyint(1) NOT NULL COMMENT ‘性别,1男2女’,
create_time
datetime NOT NULL COMMENT ‘创建时间’,
is_delete
tinyint(1) NOT NULL DEFAULT ‘0’ COMMENT ‘是否删除 1是,0否’,
PRIMARY KEY (id
)
) ENGINE=InnoDB AUTO_INCREMENT=50 DEFAULT CHARSET=utf8mb4;
controller:
# 总结
对于面试还是要好好准备的,尤其是有些问题还是很容易挖坑的,例如你为什么离开现在的公司(你当然不应该抱怨现在的公司有哪些不好的地方,更多的应该表明自己想要寻找更好的发展机会,自己的一些现实因素,比如对于我而言是现在应聘的公司离自己的家更近,又或者是自己工作到达了迷茫期,想跳出迷茫期等等)
![image](https://img-blog.csdnimg.cn/img_convert/863aed16ccc84731d575ca1a0fd94163.webp?x-oss-process=image/format,png)
**Java面试精选题、架构实战文档**
**整理不易,觉得有帮助的朋友可以帮忙点赞分享支持一下小编~**
**你的支持,我的动力;祝各位前程似锦,offer不断!**
**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**
**需要这份系统化的资料的朋友,可以添加V获取:vip1024b (备注Java)**
![img](https://img-blog.csdnimg.cn/img_convert/0744bcc8c8a7fc57e753e23a50600e76.jpeg)
**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**
}
三、测试
经过上面的配置,下面开始进入测试验证阶段。
建立一张表:
CREATE TABLE `user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`nickname` varchar(255) NOT NULL COMMENT '昵称',
`sex` tinyint(1) NOT NULL COMMENT '性别,1男2女',
`create_time` datetime NOT NULL COMMENT '创建时间',
`is_delete` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否删除 1是,0否',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=50 DEFAULT CHARSET=utf8mb4;
controller:
总结
对于面试还是要好好准备的,尤其是有些问题还是很容易挖坑的,例如你为什么离开现在的公司(你当然不应该抱怨现在的公司有哪些不好的地方,更多的应该表明自己想要寻找更好的发展机会,自己的一些现实因素,比如对于我而言是现在应聘的公司离自己的家更近,又或者是自己工作到达了迷茫期,想跳出迷茫期等等)
[外链图片转存中…(img-8uSQrHXu-1713456234851)]
Java面试精选题、架构实战文档
整理不易,觉得有帮助的朋友可以帮忙点赞分享支持一下小编~
你的支持,我的动力;祝各位前程似锦,offer不断!
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
需要这份系统化的资料的朋友,可以添加V获取:vip1024b (备注Java)
[外链图片转存中…(img-KNKkoeHk-1713456234851)]
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!