基于SpringBoot框架对接的公寓管理系统的实现

一、前言

背景:公司新建了写字楼、公寓,买了一家公司的门锁,门锁自带有一套公寓系统。需要与本公司HR系统打通。但是后面对接发现他们系统没有暴露写入人员的接口、并且也没有读取房客的接口,所以解决办法只能是从公寓系统取到所有房间,然后再一个个房间去获取到所有人,写入到HR表中。
技术分析:该系统采用了Sqlserver数据库,Java语言,Spring Boot框架等技术进行编程实现。代码要是存在欠缺考虑,还请各位大佬不吝指教,本人不胜感激。

二、实体类Entity

1、RoomEntity实体类

//房间实体类
@Data
public class RoomEntity {
	//主键
    private int id;
	//房间ID
    private String roomId;
	//房间名称
    private String roomName;
	//房间楼层
    private String floorName;
}

2、RoomPeople实体类

@Data
public class HxPeople implements Serializable {
    //ID
    private Integer id;

    //状态:1:正常,2:到期
    private String phoneNo;

    //状态:1:正常,2:到期
    private Integer status;
    
    private Long endTime;

    /房间号
    private String roomId;

    private static final long serialVersionUID = 1L;
}

三、控制器类Controller与定时器HxScheduledTask

1、Controller控制器类


/**
 * @Author :XieStrong
 * @Description : 门锁工具类
 * @Date :2024-02-27 13:58
 */
@RestController
@RequestMapping("/time")
public class HxLockTimngClient {
    @Autowired
    HttpClient httpClient;
    @Autowired
    HxRoomService hxRoomService;
    @Autowired
    HxPeopleService hxPeopleService;
    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    ThreadPoolExecutor executor = new ThreadPoolExecutor(3, 10, 60L, TimeUnit.SECONDS, new LinkedBlockingDeque<>(10), new ThreadPoolExecutor.CallerRunsPolicy());


    @PostMapping("/getToken")
    public String getToken() {
        String token = redisTemplate.opsForValue().get("lock_token");
        if(StringUtils.isBlank(token)){
            JSONObject obj = new JSONObject();
            JSONObject data = new JSONObject();
            data.put("accountName", "15641545geg2");
            data.put("password", "gewgewgwhwehb8d2ed616675");
            obj.put("method", "apartmentLogin");
            obj.put("data", data);
            JSONObject jsonObject = httpClient.hXHttpClient(obj, "1.3");
            token = JSONObject.parseObject(jsonObject.get("data").toString()).get("tokenId").toString();
            redisTemplate.opsForValue().set("lock_token", token, 3600, TimeUnit.SECONDS);
        }
        return token;
    }


    /***
     *
     * 多线程方法,每次查十条数据,开启最大线程10进行查询,查询全部数据保存在数据库中
     * @param
     * @author: XieStrong
     * @Date: 2024-02-28
     * @return: com.alibaba.fastjson2.JSONObject
     */
    @PostMapping("/saveRoomList")
    public JSONObject ThreadSaveRoomList() throws ExecutionException, InterruptedException {
        //通过接口获取最新的token
        String token = getToken();
        List<RoomEntity> roomEntities = new ArrayList<>();
        for (int i = 0; i < 100; i += 10) {
            //开始节点
            int start = i;
            Future<List<RoomEntity>> submit = executor.submit(() -> getRoomEntity(token, start));
            roomEntities.addAll(submit.get());
        }
        System.out.println(roomEntities);
        //将房间数据存到数据库中
        hxRoomService.addRoomData(roomEntities);
        executor.shutdown();
        return new JSONObject();
    }


    /***
     * 获取所有房间数据
     * @param token TokenId
     * @param start 查询开始节点
     * @author: XieStrong
     * @Date: 2024-02-28
     * @return: java.util.List<com.ruoyi.system.domain.hx.RoomEntity>
     */
    private List<RoomEntity> getRoomEntity(String token, int start) {
        //构造请求参数
        JSONObject obj = new JSONObject();
        JSONObject data = new JSONObject();
        data.put("startNum", start);
        //每次取10笔数据
        data.put("getNum", 10);

        obj.put("method", "apartmentRoomList");
        obj.put("tokenId", token);
        obj.put("data", data);

        JSONObject jsonObject = httpClient.hXHttpClient(obj, "1.2");

        JSONObject jsonObject1 = jsonObject.getJSONObject("data");
        List<RoomEntity> roomEntities = JSONArray.parseArray(jsonObject1.getString("list"), RoomEntity.class);

        return roomEntities;
    }




    /***
     *
     * 根据房间ID找到所有房间里面的人保存到数据库中后面进行对比
     * @param token 秘钥
     * @param roomid 房间
     * @author: XieStrong
     * @Date: 2024-02-28
     * @return: ArrayList<HxPeople>
     */

    public  ArrayList<HxPeople> saveKeyList(String token, String roomid) {
        //构造请求参数
        JSONObject obj = new JSONObject();
        JSONObject data = new JSONObject();
        data.put("roomId", roomid);
        data.put("startNum", 0);
        data.put("getNum", 50);

        obj.put("method", "apartmentKeyList");
        obj.put("tokenId", token);
        obj.put("data", data);

        JSONObject jsonObject = httpClient.hXHttpClient(obj, "1.1");

        JSONObject jsonObject1 = jsonObject.getJSONObject("data");
        //将接口返回的数据通过JSONArray,字段自动匹配转成对应实体类,收集成实体类的List
        List<HxPeople> peopleEntities = JSONArray.parseArray(jsonObject1.getString("list"), HxPeople.class);
        if (peopleEntities != null) {
            //通过HashSet将房间的钥匙进行去重过滤,钥匙存在重复的
            Set<HxPeople> hxPeople = new HashSet<>(peopleEntities);
            //获取当前时间时间戳
            Long timestamp = System.currentTimeMillis() / 1000;
            //将对象的getEndTime属性与当前时间戳进行对比
            hxPeople.stream().forEach(peo -> {
                //小于的话说明钥匙已经到期,更改状态
                if (Long.compare(peo.getEndTime(), timestamp) <= 0) {
                    peo.setStatus(2); //到期状态
                    peo.setRoomId(roomid);//房间ID
                } else {
                    //大于的话说明钥匙正常
                    peo.setStatus(1);//正常状态
                    peo.setRoomId(roomid);
                }
            });
            //将处理过的hxPeople对象转成ArrayList
            ArrayList<HxPeople> list = new ArrayList<>(hxPeople);
            //保存到数据库中
            hxPeopleService.addPeopleData(list);
            //有就返回
            return list;
        }
        //没有的话返回空的ArrayList
        return new ArrayList<>();
    }

    @PostMapping("/getPhone")
    public List findPeolplebyPhone(){
        List list = hxPeopleService.selectPeoplePhone();
        return list;
    }

    @PostMapping("/delPhoneList")
    public void delbyPhone(@RequestBody  List<String> phoneList){
        hxPeopleService.deleteByPhone(phoneList);
    }


}

2、定时器HxScheduledTask

@Component
public class HxScheduledTask {
    @Autowired
    HxLockTimngClient hxLockTimngClient;
    @Autowired
    HxRoomService hxRoomService;
    @Autowired
    HxPeopleService hxPeopleService;



    /***
     *
     * 定时执行任务:每5分钟执行,保存房间里面所有的钥匙
     * @param
     * @author: XieStrong
     * @Date: 2024-02-29
     * @return: void @Scheduled(cron = "0 0/5 * * * ?")
     */
    // 这个方法将在项目启动时立即执行,然后每隔10秒执行一次
    @Scheduled(cron = "0 0/5 * * * ?")
    public void getKey() {
        //创建线程
        ThreadPoolExecutor executor = new ThreadPoolExecutor(3, 10, 60L, TimeUnit.SECONDS, new LinkedBlockingDeque<>(10), new ThreadPoolExecutor.CallerRunsPolicy());
        //获取请求的token
        String token = hxLockTimngClient.getToken();
        //查询所有房间
        List<RoomEntity> list = hxRoomService.list();
        //AtomicInteger的作用:就是让程序在不加锁的时候也能保障线程安全,确保自增运算的时候是线程安全的
        AtomicInteger integer = new AtomicInteger(0);
        //ArrayList 作为共享变量的话,是线程不安全的,所以这里我们使用一种线程安全的 List,叫做 CopyOnWriteArrayList
        CopyOnWriteArrayList<HxPeople> arrayList = new CopyOnWriteArrayList();
        list.stream(). forEach(room -> {
            //请求接口次数限制10秒20次,这里我们请求了15次的话沉睡10秒
            if (integer.get() == 15) {
                try {
                    //沉睡10秒
                    Thread.sleep(10100);
                    //确保自增运算的时候是线程安全的
                    integer.set(0);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
            确保自增运算的时候是线程安全的
            integer.incrementAndGet();
            //executor.submit()有返回值的,executor.execute()是没有返回值的
            Future<ArrayList<HxPeople>> submit = executor.submit(() ->
                    hxLockTimngClient.saveKeyList(token, room.getRoomId()));
            try {
                //submit.get()拿到 executor.submit()的返回值
                ArrayList<HxPeople> hxPeople = submit.get();
                if (hxPeople != null) {
                    //不等于空的话存到CopyOnWriteArrayList中
                    arrayList.addAll(hxPeople);
                }

            }catch (Exception e){
            }

        });
        //关闭线程
        executor.shutdown();
        //将arrayList对象抽取PhoneNo属性,并收集成List集合
        List<String> collect = arrayList.stream().map(HxPeople::getPhoneNo).collect(Collectors.toList());
        //查询数据存储的所有钥匙
        List<String> peolplebyPhoneList = hxLockTimngClient.findPeolplebyPhone();
        //通过stream操作,将上方两个钥匙集合进行对比。本地数据库没有,接口钥匙集合存在,说明需要将这个删掉
        List<String> people = peolplebyPhoneList.stream()
                .filter(peo -> !collect.contains(peo)).collect(Collectors.toList());
        if (!people.isEmpty()) {
            //执行删除对应的钥匙
            hxLockTimngClient.delbyPhone(people);
        }
    }
}

四、Service接口

1、HxRoomService

public interface HxRoomService {

    void addRoomData(List<RoomEntity> roomEntity);

    List<RoomEntity> list();
}

2、HxPeopleService

public interface HxPeopleService{
    void addPeopleData(List<HxPeople> hxPeople);

    List selectPeoplePhone();

    void deleteByPhone(List<String> phoneList);
}

五、ServiceImpl实现类

1、HxRoomServiceImpl

@Service
public class HxRoomServiceImpl implements HxRoomService {
    @Resource
    HxRoomMapper hxRoomMapper;

    @Override
    public void addRoomData(List<RoomEntity> roomEntity) {
        hxRoomMapper.insertHxRoom(roomEntity);
    }

    @Override
    public List<RoomEntity> list() {
        return hxRoomMapper.selectList();
    }
}

2、HxPeopleServiceImpl

@Service
public class HxPeopleServiceImpl implements HxPeopleService{


    @Resource
    HxPeopleMapper hxPeopleMapper;

    @Override
    public void addPeopleData(List<HxPeople> hxPeople) {
        hxPeopleMapper.insertOrUpdateHxPeople(hxPeople);
    }

    @Override
    public List selectPeoplePhone() {
        List<String> list = hxPeopleMapper.selectAllPhone();
        return list;
    }

    @Override
    public void deleteByPhone(List<String> phoneList) {
        hxPeopleMapper.delByPhoneList(phoneList);

    }

}

六、Mapper接口

1、HxRoomMapper

@Mapper
public interface HxRoomMapper {
    public void insertHxRoom(@Param("roomEntity") List<RoomEntity> roomEntity);


    List<RoomEntity> selectList();
}

2、HxPeopleMapper

public interface HxPeopleMapper{
    public void insertOrUpdateHxPeople(@Param("People") List<HxPeople> hxPeople);

    @Select("select phone_no from hx_people")
    List<String> selectAllPhone();


    void delByPhoneList(@Param("PhoneList") List<String> phoneList);
}

七、Mapper.xml文件

1、HxRoomMapper

<?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="com.ruoyi.system.mapper.hx.HxRoomMapper">

    <resultMap type="roomEntity" id="RoomEntityResult">
        <id     property="id"         column="id"/>
        <result property="roomId"       column="room_id"/>
        <result property="roomName"       column="room_name"/>
        <result property="floorName"       column="floor_name"/>

    </resultMap>



    <insert id="insertHxRoom" parameterType="RoomEntity" useGeneratedKeys="true">
        insert into hx_room(room_id,room_name,floor_name) values
        <foreach collection="roomEntity" item="item" separator=",">
            (
            #{item.roomId},#{item.roomName},#{item.floorName}
            )
        </foreach>
    </insert>

    <select id="selectList" parameterType="roomEntity" resultType="roomEntity" resultMap="RoomEntityResult" >
        select * from hx_room
    </select>
</mapper>

2、HxPeopleMapper

<?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="com.ruoyi.system.mapper.hx.HxPeopleMapper">

    <resultMap id="BaseResultMap" type="com.ruoyi.system.domain.hx.HxPeople">
            <id property="id" column="id" jdbcType="INTEGER"/>
            <result property="phone_no" column="phoneNo" jdbcType="VARCHAR"/>
            <result property="status" column="status" jdbcType="INTEGER"/>
            <result property="room_id" column="roomId" jdbcType="VARCHAR"/>
    </resultMap>

    <insert id="insertHxPeople">
        insert into hx_people(phone_no,status,room_id) values
        <foreach collection="People" item="item" separator=",">
            (
            #{item.phoneNo},#{item.status},#{item.roomId}
            )
        </foreach>
    </insert>

    <insert id="insertOrUpdateHxPeople" parameterType="java.util.List">
        MERGE INTO hx_people AS target
        USING (
        VALUES
        <foreach collection="People" item="item" separator=",">
            (#{item.phoneNo}, #{item.status}, #{item.roomId})
        </foreach>
        ) AS source (phone_no, status, room_id)
        ON target.phone_no = source.phone_no
        WHEN MATCHED THEN
        UPDATE SET
        status = source.status,
        room_id = source.room_id
        WHEN NOT MATCHED THEN
        INSERT (phone_no, status, room_id)
        VALUES (source.phone_no, source.status, source.room_id);
    </insert>

    <delete id="delByPhoneList" parameterType="java.util.List">
        DELETE hx_people WHERE phone_no IN
        <foreach collection="PhoneList" item="item" open="(" close=")" separator="," >
            #{item}
        </foreach>

    </delete>


</mapper>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值