idea接口开发的基本步骤
1.用DataGrip连接MySQL数据库(我这里演示的是DataGrip连接的虚拟机centos7.9中的MySQL数据库)
# 做一个手机商城数据表
create table shop(
id int primary key auto_increment, # 手机编号
name varchar(20), # 手机名称
price int, # 手机价格
country varchar(20) # 生产国家
);
insert into shop(id, name, price, country) VALUES (1,'小米4',1599,'中国');
insert into shop(id, name, price, country) VALUES (2,'小米5',1899,'中国');
insert into shop(id, name, price, country) VALUES (3,'小米6',2799,'中国');
insert into shop(id, name, price, country) VALUES (4,'小米7',2999,'中国');
insert into shop(id, name, price, country) VALUES (5,'小米8',4599,'中国');
insert into shop(id, name, price, country) VALUES (6,'华为1',1589,'中国');
insert into shop(id, name, price, country) VALUES (7,'华为2',3789,'中国');
insert into shop(id, name, price, country) VALUES (8,'华为3',4399,'中国');
insert into shop(id, name, price, country) VALUES (9,'华为4',6189,'中国');
insert into shop(id, name, price, country) VALUES (10,'华为5',7889,'中国');
insert into shop(id, name, price, country) VALUES (11,'华为6',9899,'中国');
insert into shop(id, name, price, country) VALUES (12,'三星1',2599,'韩国');
insert into shop(id, name, price, country) VALUES (13,'三星2',3189,'韩国');
insert into shop(id, name, price, country) VALUES (14,'三星3',4789,'韩国');
insert into shop(id, name, price, country) VALUES (15,'三星4',7689,'韩国');
insert into shop(id, name, price, country) VALUES (16,'苹果x',2789,'美国');
insert into shop(id, name, price, country) VALUES (17,'苹果11',5189,'美国');
insert into shop(id, name, price, country) VALUES (18,'苹果12',6599,'美国');
select *
from shop;
2.用idea连接上虚拟机中的MySQL数据库
方法一:
直接在application.yml中配置数据库的配置
spring:
datasource:
url: ${DB_URL}
username: ${DB_USERNAME}
password: ${DB_PASSWORD}
driver-class-name: ${DB_DRIVER_CLASS_NAME}
方法二:
写配置数据库的配置文件加载进idea中使用
里面的配置如下:
# db
DB_URL=jdbc:mysql://192.168.174.129:3306/mineboot_sql?useUnicode=true&characterEncoding=utf-8&useSSL=false&useOldAliasMetadataBehavior=true
DB_USERNAME=root
DB_PASSWORD=123456
DB_DRIVER_CLASS_NAME=com.mysql.cj.jdbc.Driver
# redis
# REDIS_HOST=192.168.174.129
# REDIS_PORT=16379
# REDIS_PASSWORD
然后在idea中加载进去:
到这里已经准备好配置了,可以连接上MySQL了
3.接下来就是写接口了
(1)首先在entity/pojo中创建与数据库中字段一致的实体类---xxx
@Data
public class TbShop implements Serializable {
private static final long serialVersionUID = 1L;
private Integer id;//手机编号
private String name;//手机名称
private Integer price;//手机价格
private String country;//生产国家
}
代码中的@Data解释:
@Data :注解在类上;提供类所有属性的 getting 和 setting 方法,此外还提供了equals、canEqual、hashCode、toString 方法
@Setter:注解在属性上;为属性提供 setting 方法
@Getter:注解在属性上;为属性提供 getting 方法
@Log4j :注解在类上;为类提供一个 属性名为log 的 log4j 日志对象
@NoArgsConstructor:注解在类上;为类提供一个无参的构造方法
@AllArgsConstructor:注解在类上;为类提供一个全参的构造方法
Serializable解释:
百度上是这么讲的:
Serializable接口是启用其序列化功能的接口。实现java.io.Serializable 接口的类是可序列化的。没有实现此接口的类将不能使它们的任意状态被序列化或逆序列化。
这个介绍非常的不接地气,于是我与去看了几篇博客,有一个小姐姐的博客引起了我的注意,她是这样理解的:
序列化的过程,就是一个“freeze”的过程,它将一个对象freeze(冷冻)住,然后进行存储,等到再次需要的时候,再将这个对象de-freeze就可以立即使用。
我们以为的没有进行序列化,其实是在声明的各个不同变量的时候,由具体的数据类型帮助我们实现了序列化操作。
如果有人打开过Serializable接口的源码,就会发现,这个接口其实是个空接口,那么这个序列化操作,到底是由谁去实现了呢?其实,看一下接口的注释说明就知道,当我们让实体类实现Serializable接口时,其实是在告诉JVM此类可被序列化,可被默认的序列化机制序列化。
为什么需要序列化
1,存储对象在存储介质中,以便在下次使用的时候,可以很快捷的重建一个副本。也就是When the resulting series of bits is reread according to the serialization format, it can be used to create a semantically identical clone of the original object.
问题:我没有实现序列化的时候,我一样可以存入到我的sqlserver或者MySQL、Oracle数据库中啊,为什么一定要序列化才能存储呢????
2,便于数据传输,尤其是在远程调用的时候!
其实说了这么多,想表达的意思就是:
Serializable接口是一个里面什么都没有的接口
它的源代码是public interface Serializable{},即什么都没有。
如果一个接口里面什么内容都没有,那么这个接口是一个标识接口,比如,一个学生遇到一个问题,排错排了几天也没解决,此时,她举手了(示意我去帮他解决),然后我过去,帮他解决了,那么这个举手其实就是一个标识,自己不能解决的问题标示我去帮他解决,在Java中的这个Serializable接口是给JVM看的,告诉JVM,我不做这个类的序列化了,你(JVM)给我序列化,序列化就是变成二进制流,比如云计算、Hadoop,特别是Hadoop完全就是分布式环境,那么就要涉及到对象要在网络中传输,里面的全是二进制流,当然你来做这个序列化操作也可以,但是这个类里面可能还有一个类,如果你把外面的类对象Person变成二进制,那么里面也要序列化(这要用到深度遍历,很麻烦),干脆告诉JVM,让他来帮你做。
serializable接口就是Java提供用来进行高效率的异地共享实例对象的机制,实现这个接口即可。
*序列化是将对象状态转换为可保持或传输的格式的过程。与序列化相对的是反序列化,它将流转换为对象。这两个过程结合起来,可以轻松地存储和传输数据。
*JVM是Java Virtual Machine(Java虚拟机)的缩写,JVM是一种用于计算设备的规范,它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的。
private static final long serialVersionUID = 1L;解释:
serialVersionUID 称为序列化版本号,这个多用于实现了Serializable的类中,适用场景是类的序列化,当我们没有定义这个值得时候虚拟机会根据类的属性生成一个独一无二的序列化版本号。
在反序列化时,虚拟机会根据该变量值去寻找,如果找的到该值反序列化成功,找不到该值反序列化失败。
但是这样有一个劣势,类一旦序列化后我们就不能再修改该类的属性,一旦修改,序列化ID会变化,这会导致后续的反序列化失败。
如果我们手动定义一个序列化ID的话,虚拟机就不会进行计算了。
(2)然后写映射接口---/mapper/xxxMapper
@Mapper
public interface TbShopMapper {
List<TbShop> selectShop(Map param);
List<TbShop> selectLike(@Param("name")String name);
void insert(TbShop shop);
void insertSelective(TbShop shop);
void insertList(List<TbShop> shopList);
void insertWithReturnId(TbShop shop);
void enable(String code,String enable);
void updateSelective(TbShop shop);
}
(3)然后写对应的映射配置文件--/mybatis/xxxMapper.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="mine.boot.mapper.TbShopMapper">
<select id="selectShop" resultType="mine.boot.entity.TbShop" parameterType="map">
SELECT * FROM shop t
<where>
<if test="name != null and name !='' ">
and name=#{name}
</if>
</where>
</select>
<select id="selectLike" resultType="mine.boot.entity.TbShop">
SELECT * FROM shop t
<where>
<if test="name != null and name !='' ">
and name like CONCAT('%', #{name}, '%')
</if>
</where>
</select>
<update id="enable">
update shop set enable=#{enable} where code=#{code}
</update>
<insert id="insert" parameterType="mine.boot.entity.TbShop">
insert into shop(id, name, price, country)
value(null,#{name},#{price},#{country})
</insert>
<insert id="insertSelective" parameterType="mine.boot.entity.TbShop">
insert into shop
<trim prefix="(" suffix=")" suffixOverrides="," >
<if test="name != null" >
name,
</if>
<if test="price != null" >
price,
</if>
<if test="country != null" >
country,
</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides="," >
<if test="name != null" >
#{name},
</if>
<if test="price != null" >
#{price},
</if>
<if test="country != null" >
#{country},
</if>
</trim>
</insert>
<insert id="insertList" parameterType="mine.boot.entity.TbShop">
insert into shop(id, name, price, country)
values
<foreach collection="list" item="it" index="index" separator=",">
(null, #{it.name}, #{it.price}, #{it.country})
</foreach>
</insert>
<insert id="insertWithReturnId" useGeneratedKeys="true" keyProperty="id" keyColumn="id" parameterType="mine.boot.entity.TbShop">
insert into shop(id, name, price, country)
value(null,#{name},#{price},#{country})
</insert>
<update id="updateSelective" parameterType="mine.boot.entity.TbShop">
update shop
<set>
<if test="name != null and name != '' ">
name = #{name},
</if>
<if test="price != null and price != '' ">
price = #{price},
</if>
</set>
where id = #{id}
</update>
</mapper>
(4)然后写服务层的接口---/service/xxxService
public interface TbShopService{
//分页查询
PageBean<TbShop> selectByPage(String name,PageBean pageBean);
//like查询(模糊查询)
List<TbShop> selectLike(String name);
//插入写法
void insert(TbShop shop);
//条件插入
void insertSelective(TbShop shop);
//批量插入
void insertList(List<TbShop> shopList);
//插入后返回id
TbShop insertWithReturnId(TbShop shop);
//update写法
void disable(String code);
//条件更新
void updateSelective(TbShop shop);
}
(5)服务层实现重写刚才的接口方法---/service/impl/xxxServiceImpl
@Service
@RequiredArgsConstructor
public class TbShopServiceImpl implements TbShopService {
private final TbShopMapper shopMapper;
@Override
public PageBean<TbShop> selectByPage(String name, Pagination pagination) {
PageHelper.startPage(pagination.getPageNum(),pagination.getPageSize());
Map map = Maps.newHashMap();
map.put("name",name);
List<TbShop> shopList = shopMapper.selectShop(map);
PageInfo pageInfo = new PageInfo(shopList);
PageBean pageBean = PageBeanFactory.create(pageInfo);
return pageBean;
}
@Override
public List<TbShop> selectLike(String name) {
List<TbShop> shopList = shopMapper.selectLike(name);
return shopList;
}
@Override
public void insert(TbShop shop) {
shop.setName("苹果13");
shop.setPrice(9999);
shop.setCountry("美国");
shopMapper.insert(shop);
}
@Override
public void insertSelective(TbShop shop) {
shopMapper.insertSelective(shop);
}
@Override
public void insertList(List<TbShop> shopList) {
for (TbShop shop:shopList){
shop.setName("小米13");
shop.setPrice(8999);
shop.setCountry("中国");
}
shopMapper.insertList(shopList);
}
@Override
public TbShop insertWithReturnId(TbShop shop) {
shopMapper.insertWithReturnId(shop);
return null;
}
@Override
public void disable(String code) {
shopMapper.enable(code,"0");
}
@Override
public void updateSelective(TbShop shop) {
shopMapper.updateSelective(shop);
}
}
(6)最后一层就是controller层了---/controller/xxxController
@RestController
@RequestMapping(value = "/tbShop")
@RequiredArgsConstructor
public class TbShopController {
private final TbShopService shopService;
/**
* 演示分页查询写法
* */
@RequestMapping(value = "/selectByPage",method=RequestMethod.GET)
public JsonResult selectByPage(String name,Pagination pagination){
PageBean pageBean=shopService.selectByPage(name,pagination);
return JsonResultUtil.createSuccessResult(pageBean);
}
/**
* 演示 like 查询
* */
@RequestMapping(value = "/selectLike",method=RequestMethod.GET)
public JsonResult selectLike(String name){
List list=shopService.selectLike(name);
return JsonResultUtil.createSuccessResult(list);
}
/**
* 演示插入写法
* */
@RequestMapping(value = "/insert",method=RequestMethod.POST)
public JsonResult insert(@RequestBody TbShop shop) {
shopService.insert(shop);
return JsonResultUtil.createSuccessResult("ok");
}
/**
* 演示批量插入写法
* */
@RequestMapping(value = "/insertList",method=RequestMethod.POST)
public JsonResult insertList(@RequestBody List<TbShop> shopList) {
shopService.insertList(shopList);
return JsonResultUtil.createSuccessResult("ok");
}
/**
* 演示条件插入
* */
@RequestMapping(value = "/insertSelective",method = RequestMethod.POST)
public JsonResult insertSelective(@RequestBody TbShop shop) {
shopService.insertSelective(shop);
return JsonResultUtil.createSuccessResult("ok");
}
/**
* 演示插入后返回id
* */
@RequestMapping(value = "/insertWithReturnId",method=RequestMethod.POST)
public JsonResult insertWithReturnId(@RequestBody TbShop shop) {
TbShop savedUser=shopService.insertWithReturnId(shop);
return JsonResultUtil.createSuccessResult(savedUser);
}
/**
* 演示条件更新
* */
@RequestMapping(value = "/updateSelective",method = RequestMethod.POST)
public JsonResult updateSelective(@RequestBody TbShop shop) {
shopService.updateSelective(shop);
return JsonResultUtil.createSuccessResult("ok");
}
/**
* 演示update写法
* */
@RequestMapping(value = "/disable",method=RequestMethod.POST)
public JsonResult disable(String code){
shopService.disable(code);
return JsonResultUtil.createSuccessResult("ok");
}
}
4.然后进行将修改后的项目发送到远程gitlab自己的分支上
(1)进入项目的文件中,带有.git初始化的地方
打开git bash
(2)查看状态
git status
Untracked: 未跟踪,一般为新增文件,此文件在文件夹中, 但并没有加入到git库, 不参与版本控制. 通过git add 状态变为Staged
Modified: 文件已修改, 仅仅是修改, 并没有进行其他的操作
deleted: 文件已删除,本地删除,服务器上还没有删除
renamed:文件重命名
(3)提交工作区文件至暂存区并查看状态
将状态改变的代码提交至缓存
git add . #将当前目录下修改的所有代码从工作区添加到暂存区 . 代表当前目录
git add <file> #将指定文件从工作区添加到暂存区
git status
(4)提交暂存区的文件到本地库
git commit -m 'commit message(描述)' 将缓存区内容添加到本地库
(5)上传本地库到远程库
git push #上传本地库代码
git push origin <branch> #将本地仓库的内容上传到指定远程分支并快速合并
(6)进入到gitlab就会看到自己的项目
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!