在线预约系统
数据管理=>数据字典
医院管理=》医院设置、医院列表
会员管理=》会员列表、认证审批列表
订单管理=》订单列表
首页数据展示
预约挂号
支付挂号订单
登录:手机号登录、微信登录
前后端分离
1、SpringBoot:2.2.1
2、SpringCloud:
包括:SpringCloudGateway、SpringColud Alibaba Nacos、Spring Cloud Alibaba Sentinel、SpringCloud Task、SpringCloudFeign
3、MyBatis-Plus:持久层
4、Redis:内存缓存
5、Rabbit MQ:消息中间件
6、HTTPClient:http协议客户端
7、Swagger2
8、Nginx:负载均衡
9、Lombok
10、MySQL
11、MongoDB:面向文档的NoSQL数据库
12、Vue.js:
13、Node.js:JavaScript运行环境
14、Axios:是一个基于promise的HTTP库
15、NPM:包管理器
16、Babel:转码器
17、webpack:打包工具
Docker:容器技术
Git:代码管理工具
DockerFile:管理Docker镜像命令文本
Jenkins:持续化集成工具
简称:mp
是mybatis的增强工具。
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.3.1</version>
</dependency>
mapper.java
@Repository // 防止@Autowird下面的代码报错,虽然不影响代码的正常运行
public interface UserMapper extends BaseMapper<User>{
}
@Autowird
UserMapper userMapper;
public void test(){
List<User> users =userMapper.selectList(null);
system.out.println(users);
}
可以发现:不用写xml文件 也不用定义接口
# mybatis的配置
# 下划线命名方式转为驼峰
mybatis-plus.configuration.map-underscore-to-camel-case=true
mybatis-plus.mapper-locations=classpath:mapper/*.xml
mybatis-plus.type-aliases-package=com.sinux.rock.entity
# 枚举自动转换
mybatis-plus.configuration.default-enum-type-handler=org.apache.ibatis.type.EnumOrdinalTypeHandler
mybatis-plus.configuration.call-setters-on-nulls=true
#查看sql输出日志
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
@Autowird
UserMapper userMapper;
public void test(){
User user = new User();
user.setName("sunshine");
user.setAge(26);
int count=userMapper.insert(user);
system.out.println(count);
}
主键策略:如果数据库的id值没有自增长,mp会使用自己的主键策略生成一个id值;
ASSIGN_ID(雪花算法生成19为值,效率高)、AUTO、TYPE(手动输入)、NONE
默认:ASSIGN_ID
@TableId(type=IdType.ASSIGN_ID)
private Long id;
挥着全局配置IdType.AUTO
mybatis-plus.global-config.db-config.id-type=auto
例子:
@Autowird
UserMapper userMapper;
public void test(){
User user = new User();
user.setId(1);
user.setName("sunshine2");
int count=userMapper.updateById(user);
system.out.println(count);
}
自动填充:每次都使用相同的方式填充。例如:记录的创建时间,更新时间等。就可以使用到mp
数据库字段:create_time、update_time
实体类
@TableField(fill=FieldFill.INSERT)
private Date createTime;//create_time
@TableField(fill=FieldFill.INSERT_UPDATE)
private Date updateTime;//update_time
handle
@Componet //交给spring管理
public MyMetaObjectHandler implements MetaObjectHandler{
//mp执行添加操作,这个方法执行
@Override
public void insertFill(MetaObject metaObject){
this.setFieldValByName("createTime",new Date(),metaObject);
this.setFieldValByName("updateTime",new Date(),metaObject);
}
//mp执行修改操作,这个方法执行
@Override
public void updateFill(MetaObject metaObject){
this.setFieldValByName("updateTime",new Date(),metaObject);
}
}
抢票
当要更新一条记录的时候,希望这条记录没有被别人更新。
(并发操作中产生的问题)
比如我和张三同事提交数据 我先更新了数据库里面user的名字 张三后面又去改了名字。我去数据库查询的时候,就会疑惑为什么数据不是我之前修改的数据。 这个就叫做丢失更新问题。
给数据库表添加version字段。我提交了 版本就变了 张三拿着原来的版本去更新是无法更新的。
@Version
private Integer version;
//乐观锁插件
@Configuration
@MapperScan("com.**.mapper")
public class MybatisPlusConfig{
@Bean
public OptimisticLockerInterceptor optimisticLockerInterceptor(){
return new OptimisticLockerInterceptor();
}
}
@Version
@TableField(fill=FieldFill.INSERT)
private Integer version;
@Override
public void insertFill(MetaObject metaObject){
this.setFieldValByName("createTime",new Date(),metaObject);
this.setFieldValByName("updateTime",new Date(),metaObject);
this.setFieldValByName("version",1,metaObject);
}
List<User> user = userMapper.selectBatchIds(Arrays.asList(1,2,3))
1、配置分页插件
@Bean
public PaginationInterceptor paginationInterceptor(){
return new PaginationInterceptor();
}
2、编写分页代码
public void test(){
Page<User> page = new Page(1,3);
Page<User> pageUser =userMapper.selectPAge(page,null);
//返回对象得到分页所有数据
long pages=userPage.getPages();//总页数
long current=userPage.getCurrent();//查询数据集合
List<User> records=userPage.getRecords();//总记录数
long total =userPage.hasNext();//下一页
boolean hasPrevious=userPage.hasPrevious().//上一页
}
int row =userMapper.deleteById(1);
int row =userMapper.deleteBatchIds(1);
int row =userMapper.deleteByMap(map);
但是由于默认填充了 在执行selectList的时候,查询出来的是delete=0的数据
ALTER TABLE `user` ADD COLUMN `deleted` boolean
@TableLogic
@TableField(fill = FieldFill.INSERT)
private Integer deleted;
@Override
public void insertFill(MetaObject metaObject) {
......
this.setFieldValByName("deleted", 0, metaObject);
}
此为默认值,如果你的默认值和mp默认的一样,该配置可无
mybatis-plus.global-config.db-config.logic-delete-value=1
mybatis-plus.global-config.db-config.logic-not-delete-value=0
@Bean
public ISqlInjector sqlInjector() {
return new LogicSqlInjector();
}
public void testLogicDelete() {
int result = userMapper.deleteById(1);
}
Wrapper : 条件构造抽象类,最顶端父类
AbstractWrapper : 用于查询条件封装,生成 sql 的 where 条件
QueryWrapper : Entity 对象封装操作类,不是用lambda语法
UpdateWrapper : Update 条件封装,用于Entity对象更新操作
AbstractLambdaWrapper : Lambda 语法使用 Wrapper统一处理解析 lambda 获取 column。
LambdaQueryWrapper :看名称也能明白就是用于Lambda语法使用的查询Wrapper
LambdaUpdateWrapper : Lambda 更新封装Wrapper
QueryWrapper 比wapper 更强大
ge(大于等于)、gt(大于)、le(小于等于)、lt(小于)、isNull、isNotNull
eq、ne 、allEq
between、notBetween
like(%xx%)、notLike、likeLeft(%xx)、likeRight(xx%)
in、notIn、inSql、notinSql、exists、notExists //inSql、notinSql:可以实现子查询
or、and //UpdateWrapper
嵌套or、嵌套and
orderBy、orderByDesc、orderByAsc
last
指定要查询的列
QueryWrapper<User> queryWapper = new QueryWrapper<>();
queryWapper.ge("age",12);
//
wrapper.eq("name","东方不败").ne("age",28);
List<User> users = userMapper.selectList(wrapper);
//
Map<String, Object> map = new HashMap<>();
map.put("id", 10);
map.put("name", "东方不败");
map.put("age", 50);
queryWrapper.allEq(map);
//
queryWrapper.between("age", 10, 40);
Integer count = userMapper.selectCount(queryWrapper);
//
queryWrapper
.notLike("name", "武大郎")
.likeRight("email", "xxx@qq.com");
List<Map<String, Object>> maps = userMapper.selectMaps(queryWrapper);//返回值是Map列表
maps.forEach(System.out::println);
//
queryWrapper.notIn(“age”,{1,2,3})—>age not in (1,2,3)
//
queryWrapper.inSql("id", "select id from user where id < 3");
List<Object> objects = userMapper.selectObjs(queryWrapper);//返回值是Object列表
objects.forEach(System.out::println);
//
UpdateWrapper<User> userUpdateWrapper = new UpdateWrapper<>();
userUpdateWrapper
.like("name", "h")
.or()
.between("age", 20, 30);
int result = userMapper.update(user, userUpdateWrapper);
//
//修改条件
UpdateWrapper<User> userUpdateWrapper = new UpdateWrapper<>();
userUpdateWrapper
.like("name", "h")
.or(i -> i.eq("name", "李白").ne("age", 20));
int result = userMapper.update(user, userUpdateWrapper);
//
queryWrapper.orderByDesc("id");
// 直接拼接到 sql 的最后 ;只能调用一次,多次调用以最后一次为准 有sql注入的风险,请谨慎使用
queryWrapper.last("limit 1");
//指定要查询的列
queryWrapper.select("id", "name", "age");
//
userUpdateWrapper
.like("name", "h")//where语句后的条件
.set("name", "老李头")//除了可以查询还可以使用set设置修改的字段
.setSql(" email = '123@qq.com'");//可以有子查询
int result = userMapper.update(user, userUpdateWrapper);
public enum PartEnum {
CONTROL_SYSTEM(32, "控制系统"),
POWER_SYSTEM(64, "动力系统"),
PUSH_SYSTEM(128, "推利系统"),
MEASURE_SYSTEM_EXTERNAL_SECURITY(256, "测量系统-外安"),
MEASURE_SYSTEM_TELEMETRY(512, "测量系统-遥测"),
COMMON(992, "通用"),
;
private Integer code;
private String describe;
PartEnum(Integer code, String describe) {
this.code = code;
this.describe = describe;
}
@JsonValue
public Integer getCode() {
return code;
}
public String getDescribe() {
return describe;
}
@JsonCreator
public static PartEnum fromCode(Integer code) {
return mapCode.get(code);
}
private static Map<Integer, PartEnum> mapCode;
static {
mapCode = Arrays.stream(values()).collect(Collectors.toMap(PartEnum::getCode, obj -> obj));
}
}
枚举会自动进行转换
public List<KeyParamPO> findKeyParamPOList(PartEnum part, GroupPartEnum groupPart) {
LambdaQueryWrapper<KeyParamPO> wrapper = Wrappers.<KeyParamPO>lambdaQuery()
.eq(KeyParamPO::getPart, part.getCode())
.eq(KeyParamPO::getGroupPart, groupPart.getCode());
wrapper.orderByAsc(KeyParamPO::getTableNumber, KeyParamPO::getParamId);
// wrapper.orderByAsc(KeyParamPO::getParamId);
return keyParamDO.selectList(wrapper);
}