MapApp 地图应用

1. 简述

  1.1 重点

    1)更好地理解 MVVM 架构

    2)更轻松地使用 SwiftUI 框架、对齐、动画和转换

  1.2 资源下载地址:

Swiftful-Thinking:icon-default.png?t=N7T8https://www.swiftful-thinking.com/downloads

  1.3 项目结构图:

  1.4 图片、颜色资源文件图:

  1.5 启动图片配置图:

2. Model 层

  2.1 创建模拟位置文件 Location.swift

import Foundation
import MapKit

struct Location: Identifiable, Equatable{
    let name: String
    let cityName: String
    let coordinates: CLLocationCoordinate2D
    let description: String
    let imageNames: [String]
    let link: String
    
    // UUID().uuidString,生产的每个ID都不一样,为了保证有相同可识别的相同模型,使用名称加城市名称
    var id: String {
        name + cityName
    }
    
    // Equatable 判断 id 是否一样
    static func == (lhs: Location, rhs: Location) -> Bool {
       return lhs.id == rhs.id
    }
}

3. 数据服务层

  3.1 创建模拟位置数据信息服务 LocationsDataSerVice.swift

import Foundation
import MapKit

class LocationsDataService {
    
    static let locations: [Location] = [
        Location(
            name: "Colosseum",
            cityName: "Rome",
            coordinates: CLLocationCoordinate2D(latitude: 41.8902, longitude: 12.4922),
            description: "The Colosseum is an oval amphitheatre in the centre of the city of Rome, Italy, just east of the Roman Forum. It is the largest ancient amphitheatre ever built, and is still the largest standing amphitheatre in the world today, despite its age.",
            imageNames: [
                "rome-colosseum-1",
                "rome-colosseum-2",
                "rome-colosseum-3",
            ],
            link: "https://en.wikipedia.org/wiki/Colosseum"),
        Location(
            name: "Pantheon",
            cityName: "Rome",
            coordinates: CLLocationCoordinate2D(latitude: 41.8986, longitude: 12.4769),
            description: "The Pantheon is a former Roman temple and since the year 609 a Catholic church, in Rome, Italy, on the site of an earlier temple commissioned by Marcus Agrippa during the reign of Augustus.",
            imageNames: [
                "rome-pantheon-1",
                "rome-pantheon-2",
                "rome-pantheon-3",
            ],
            link: "https://en.wikipedia.org/wiki/Pantheon,_Rome"),
        Location(
            name: "Trevi Fountain",
            cityName: "Rome",
            coordinates: CLLocationCoordinate2D(latitude: 41.9009, longitude: 12.4833),
            description: "The Trevi Fountain is a fountain in the Trevi district in Rome, Italy, designed by Italian architect Nicola Salvi and completed by Giuseppe Pannini and several others. Standing 26.3 metres high and 49.15 metres wide, it is the largest Baroque fountain in the city and one of the most famous fountains in the world.",
            imageNames: [
                "rome-trevifountain-1",
                "rome-trevifountain-2",
                "rome-trevifountain-3",
            ],
            link: "https://en.wikipedia.org/wiki/Trevi_Fountain"),
        Location(
            name: "Eiffel Tower",
            cityName: "Paris",
            coordinates: CLLocationCoordinate2D(latitude: 48.8584, longitude: 2.2945),
            description: "The Eiffel Tower is a wrought-iron lattice tower on the Champ de Mars in Paris, France. It is named after the engineer Gustave Eiffel, whose company designed and built the tower. Locally nicknamed 'La dame de fer', it was constructed from 1887 to 1889 as the centerpiece of the 1889 World's Fair and was initially criticized by some of France's leading artists and intellectuals for its design, but it has become a global cultural icon of France and one of the most recognizable structures in the world.",
            imageNames: [
                "paris-eiffeltower-1",
                "paris-eiffeltower-2",
            ],
            link: "https://en.wikipedia.org/wiki/Eiffel_Tower"),
        Location(
            name: "Louvre Museum",
            cityName: "Paris",
            coordinates: CLLocationCoordinate2D(latitude: 48.8606, longitude: 2.3376),
            description: "The Louvre, or the Louvre Museum, is the world's most-visited museum and a historic monument in Paris, France. It is the home of some of the best-known works of art, including the Mona Lisa and the Venus de Milo. A central landmark of the city, it is located on the Right Bank of the Seine in the city's 1st arrondissement.",
            imageNames: [
                "paris-louvre-1",
                "paris-louvre-2",
                "paris-louvre-3",
            ],
            link: "https://en.wikipedia.org/wiki/Louvre"),
    ]
}

4. ViewModel 层

  4.1 创建位置信息的 ViewModel LocationsViewModel.swift

import Foundation
import MapKit
import SwiftUI

class LocationsViewModel: ObservableObject{
    
    /// All loaded locations Published
    @Published var locationes: [Location] = []
    
    /// Current location on map
    @Published var mapLocation: Location {
        didSet {
            // 设置地图位置,然后更新地图区域
            updateMapRegion(location: mapLocation)
        }
    }
    
    /// Current region on map :  这是地图上的当前区域
    @Published var mapRegion: MKCoordinateRegion = MKCoordinateRegion()
    /// 坐标跨度
    let mapSpan = MKCoordinateSpan(latitudeDelta: 0.1, longitudeDelta: 0.1)
    
    /// Show list of locations : 显示位置列表
    @Published var showLocationsList: Bool = false
    /// Show location detail via sheet : 显示位置详情信息页面
    @Published var sheetLocation: Location? = nil
    
    init() {
        let locations = LocationsDataService.locations
        self.locationes = locations
        self.mapLocation = locations.first!
        self.updateMapRegion(location: locations.first!)
    }
    
    
    /// 更新地图区域
    private func updateMapRegion(location: Location){
        withAnimation(.easeInOut) {
            mapRegion = MKCoordinateRegion(
                // 中心点: 经纬度 latitude: 纬度  longitude: 经度
                center: location.coordinates,
                // 坐标跨度:
                span: mapSpan)
        }
    }
    
    /// 位置列表开关
    func toggleLocationsList(){
        withAnimation(.easeInOut) {
            // showLocationsList = !showLocationsList
            showLocationsList.toggle()
        }
    }
    
    /// 显示下一个位置
    func showNextLocation(location: Location){
        withAnimation(.easeInOut) {
            mapLocation = location
            showLocationsList = false
        }
    }
    
    /// 下一个按钮处理事件
    func nextButtonPressed(){
        // Get the current index
        guard let currentIndex = locationes.firstIndex(where: { $0 == mapLocation }) else {
            print("Could not find current index in locations array! Should naver happen.")
            return
        }
        
        // check if the nextIndex is valid: 检查下一个索引是否有校
        let nextIndex = currentIndex + 1
        guard locationes.indices.contains(nextIndex) else {
            // Next index is NOT avlid
            // Restart from 0
            guard let firstLocation = locationes.first else { return }
            showNextLocation(location: firstLocation)
            return
        }
        
        // Next index IS valid
        let nextLocation = locationes[nextIndex]
        showNextLocation(location: nextLocation)
    }
}

5. 创建 View 层

  5.1 位置列表 View

    1) 创建实现文件 LocationsListView.swift
import SwiftUI

/// 位置列表
struct LocationsListView: View {
    /// 环境变量中的 ViewModel
    @EnvironmentObject private var viewMode: LocationsViewModel
    
    var body: some View {
        List {
            ForEach(viewMode.locationes) { location in
                Button {
                    viewMode.showNextLocation(location: location)
                } label: {
                    listRowView(location: location)
                }
                .padding(.vertical, 4)
                .listRowBackground(Color.clear)
            }
        }
        .listStyle(.plain)
    }
}

extension LocationsListView {
    /// 列表行
    private func listRowView(location: Location) -> some View{
        HStack {
            if let imageName = location.imageNames.first {
                Image(imageName)
                    .resizable()
                    .scaledToFill()
                    .frame(width: 45, height: 45)
                    .cornerRadius(10)
            }
            
            VStack(alignment: .leading) {
                Text(location.name)
                    .font(.headline)
                
                Text(location.cityName)
                    .font(.headline)
            }
            .frame(maxWidth: .infinity, alignment: .leading)
        }
    }
}

struct LocationsListView_Previews: PreviewProvider {
    static var previews: some View {
        LocationsListView()
            .environmentObject(LocationsViewModel())
    }
}
    2) 效果图:

  5.2 位置预览 View

    1) 创建实现文件 LocationPreviewView.swift
import SwiftUI

/// 位置预览视图
struct LocationPreviewView: View {
    /// 环境变量中配置的 viewModel
    @EnvironmentObject private var viewModel: LocationsViewModel
    let location: Location
    
    var body: some View {
        HStack(alignment:.bottom, spacing: 0) {
            VStack(alignment: .leading, spacing: 16) {
                imageSection
                titleSection
            }
            
            VStack(spacing: 8) {
                learnMoreButton
                nextButton
            }
        }
        .padding(20)
        .background(
            RoundedRectangle(cornerRadius: 10)
                .fill(.ultraThinMaterial.opacity(0.7))
                .offset(y: 65)
        )
        .cornerRadius(10)
    }
}

extension LocationPreviewView {
    /// 图片部分
    private var imageSection: some View{
        ZStack {
            if let imageImage = location.imageNames.first{
                Image(imageImage)
                    .resizable()
                    .scaledToFill()
                    .frame(width: 100, height: 100)
                    .cornerRadius(10)
            }
        }
        .padding(6)
        .background(Color.white)
        .cornerRadius(10)
    }
    
    /// 标题部分
    private var titleSection: some View{
        VStack(alignment: .leading, spacing: 4) {
            Text(location.name)
                .font(.title2)
                .fontWeight(.bold)
            
            Text(location.cityName)
                .font(.subheadline)
        }
        .frame(maxWidth: .infinity, alignment: .leading)
    }
    
    /// 了解更多按钮
    private var learnMoreButton: some View{
        Button {
            viewModel.sheetLocation = location
        } label: {
            Text("Learn more")
                .font(.headline)
                .frame(width: 125, height: 35)
        }
        .buttonStyle(.borderedProminent)
    }
    
    /// 下一个按钮
    private var nextButton: some View{
        Button {
            viewModel.nextButtonPressed()
        } label: {
            Text("Next")
                .font(.headline)
                .frame(width: 125, height: 35)
        }
        .buttonStyle(.bordered)
    }
}

struct LocationPreviewView_Previews: PreviewProvider {
    static var previews: some View {
        ZStack {
            Color.black.ignoresSafeArea()
            LocationPreviewView(location: LocationsDataService.locations.first!)
                .padding()
        }
        .environmentObject(LocationsViewModel())
    }
}
    2) 效果图:

  5.3 位置注释 View

    1) 创建实现文件 LocationMapAnnotationView.swift
import SwiftUI

/// 位置注释视图
struct LocationMapAnnotationView: View {
    let accentColor = Color("AccentColor")
    
    var body: some View {
        VStack(spacing: 0) {
            Image(systemName: "map.circle.fill")
                .resizable()
                .scaledToFill()
                .frame(width: 30, height: 30)
                .font(.headline)
                .foregroundColor(.white)
                .padding(6)
                .background(accentColor)
            //.cornerRadius(36)
                .clipShape(Circle())
            
            Image(systemName: "triangle.fill")
                .resizable()
                .scaledToFill()
                .foregroundColor(accentColor)
                .frame(width: 10, height: 10)
                .rotationEffect(Angle(degrees: 180))
                .offset(y: -3)
                .padding(.bottom, 35)
        }
    }
}

#Preview {
    ZStack{
        Color.black.ignoresSafeArea()
        LocationMapAnnotationView()
    }
}
    2) 效果图:

  5.4 主页 View

    1) 创建实现文件 LocationsView.swift
import SwiftUI
import MapKit

/// 主页 View
struct LocationsView: View {
    @EnvironmentObject private var viewModel: LocationsViewModel
    let maxWidthForIpad: CGFloat = 700
    
    var body: some View {
        ZStack {
            mapLayer
                .ignoresSafeArea()
            
            VStack(spacing: 0) {
                header
                    .padding()
                    .frame(maxWidth: maxWidthForIpad)
                Spacer()
                locationsPreviewStack
            }
        }
        // .fullScreenCover 全屏显示
        .sheet(item: $viewModel.sheetLocation) { location in
            LocationDetailView(location: location)
        }
    }
}

extension LocationsView {
    /// 头View
    private var header: some View{
        VStack {
            Button {
                viewModel.toggleLocationsList()
            } label: {
                Text(viewModel.mapLocation.name + ", " + viewModel.mapLocation.cityName)
                    .font(.title2)
                    .fontWeight(.black)
                    .foregroundColor(.primary)
                    .frame(height: 55)
                    .frame(maxWidth: .infinity)
                    .animation(.none, value: viewModel.mapLocation)
                    .overlay(alignment: .leading) {
                        Image(systemName: "arrow.down")
                            .font(.headline)
                            .foregroundColor(.primary)
                            .padding()
                            .rotationEffect(Angle(degrees: viewModel.showLocationsList ? 180 : 0))
                    }
            }
            // 列表
            if viewModel.showLocationsList{
                LocationsListView()
            }
        }
        .background(.thickMaterial.opacity(0.7))
        .cornerRadius(10)
        .shadow(color: Color.black.opacity(0.3), radius: 20, x: 0, y: 15)
    }
    
    /// 地图 View
    private var mapLayer: some View{
        Map(coordinateRegion: $viewModel.mapRegion,
            annotationItems: viewModel.locationes,
            annotationContent: { location in
            // 地图标识颜色
            // MapMarker(coordinate: location.coordinates, tint: .blue)
            // 自定义标识
            MapAnnotation(coordinate: location.coordinates) {
                LocationMapAnnotationView()
                    .scaleEffect(viewModel.mapLocation == location ? 1 : 0.7)
                    .shadow(radius: 10)
                    .onTapGesture {
                        viewModel.showNextLocation(location: location)
                    }
            }
        })
    }
    
    /// 地址预览堆栈
    private var locationsPreviewStack: some View{
        ZStack {
            ForEach(viewModel.locationes) { location in
                // 显示当前地址
                if viewModel.mapLocation == location {
                    LocationPreviewView(location: location)
                        .shadow(color: Color.black.opacity(0.3), radius: 20)
                        .padding()
                        .frame(maxWidth: maxWidthForIpad)
                        .frame(maxWidth: .infinity)
                    // .opacity
                    // .transition(AnyTransition.scale.animation(.easeInOut))
                    // 添加动画
                        .transition(.asymmetric(
                            insertion: .move(edge: .trailing),
                            removal: .move(edge: .leading)))
                }
            }
        }
    }
}

struct LocationsView_Previews: PreviewProvider {
    static var previews: some View {
        LocationsView()
            .environmentObject(LocationsViewModel())
    }
}
    2) 效果图:

  5.5 位置详情页 View

    1) 创建实现文件 LocationDetailView.swift
import SwiftUI
import MapKit

/// 位置详情页视图
struct LocationDetailView: View {
    // @Environment(\.presentationMode) var presentationMode
    // @Environment(\.dismiss) var dismiss
    @EnvironmentObject private var viewModel: LocationsViewModel
    let location: Location
    
    var body: some View {
        ScrollView {
            VStack {
                imageSection
                VStack(alignment: .leading, spacing: 16){
                    titleSection
                    Divider()
                    descriptionSection
                    Divider()
                    mapLayer
                }
                .frame(maxWidth: .infinity, alignment: .leading)
                .padding()
            }
        }
        // 安全区
        .ignoresSafeArea()
        // 超薄材质,灰白色
        .background(.ultraThinMaterial)
        // 添加返回按钮
        .overlay(alignment: .topLeading) {
            backButton
        }
    }
}

extension LocationDetailView{
    /// 滑动切换图
    private var imageSection: some View{
        TabView {
            ForEach(location.imageNames, id: \.self) {
                Image($0)
                    .resizable()
                    .scaledToFill()
                    .frame(width: UIDevice.current.userInterfaceIdiom == .pad  ? nil : UIScreen.main.bounds.width)
                    .clipped()
            }
        }
        .frame(height: 500)
        .tabViewStyle(.page)
        .shadow(color: .black.opacity(0.3), radius: 20, y: 10)
    }
    
    /// 标题视图
    private var titleSection: some View{
        VStack(alignment: .leading, spacing: 8){
            Text(location.name)
                .font(.largeTitle)
                .fontWeight(.semibold)
                .foregroundStyle(.primary)
            Text(location.cityName)
                .font(.title3)
                .foregroundStyle(.secondary)
        }
    }
    
    /// 描述视图
    private var descriptionSection: some View{
        VStack(alignment: .leading, spacing: 16){
            Text(location.description)
                .font(.subheadline)
                .foregroundStyle(.secondary)
            
            if let url = URL(string: location.link) {
                Link("Read more on Wikipedia", destination: url)
                    .font(.headline)
                    .tint(.blue)
            }
        }
    }
    
    /// 地图 View
    private var mapLayer: some View{
        Map(coordinateRegion: .constant(MKCoordinateRegion(
            center: location.coordinates,
            span: MKCoordinateSpan(latitudeDelta: 0.01, longitudeDelta: 0.01))),
            annotationItems: [location]) { location in
            MapAnnotation(coordinate: location.coordinates){
                // 自定义标识
                LocationMapAnnotationView()
                    .shadow(radius: 10)
            }
        }
            .allowsHitTesting(false) // 禁止点击
            .aspectRatio(1, contentMode: .fit) // 纵横比
            .cornerRadius(30)
    }
    
    /// 返回按钮
    private var backButton: some View{
        Button{
           // dismiss.callAsFunction()
            viewModel.sheetLocation = nil
        } label: {
            Image(systemName: "xmark")
                .font(.headline)
                .padding(16)
                .foregroundColor(.primary)
                .background(.thickMaterial)
                .cornerRadius(10)
                .shadow(radius: 4)
                .padding()
        }
    }
}

#Preview {
    LocationDetailView(location: LocationsDataService.locations.first!)
        .environmentObject(LocationsViewModel())
}
    2) 效果图:

  5.6 启动结构体文件 SwiftfulMapAppApp.swift

import SwiftUI

@main
struct SwiftfulMapAppApp: App {
    @StateObject private var viewModel = LocationsViewModel()
    
    var body: some Scene {
        WindowGroup {
            LocationsView()
                .environmentObject(viewModel)
        }
    }
}

6. 整体效果:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/152799.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

(Matalb时序预测)WOA-BP鲸鱼算法优化BP神经网络的多维时序回归预测

目录 一、程序及算法内容介绍: 基本内容: 亮点与优势: 二、实际运行效果: 三、部分代码: 四、完整代码数据说明手册: 一、程序及算法内容介绍: 基本内容: 本代码基于Matalb平台…

微服务测试怎么做

开发团队越来越多地选择微服务架构而不是单体结构,以提高应用程序的敏捷性、可扩展性和可维护性。随着决定切换到模块化软件架构——其中每个服务都是一个独立的单元,具有自己的逻辑和数据库,通过 API 与其他单元通信——需要新的测试策略和新…

python 基础语法学习 (二)

多变量赋值 当你在Python中进行多变量赋值时,你可以在一行代码中同时为多个变量分配值。这种方法可以简化代码并提高可读性。下面是一些关于Python多变量赋值的基本知识: 基本赋值:你可以使用等号()将一个值分配给一…

SimaPro生命周期评估建模与碳足迹分析流程

SimaPro以系统和透明的方式轻松建模和分析复杂的生命周期,通过确定供应链中每个环节的热点,从原材料的提取到制造,分销,使用和处置,衡量所有生命周期阶段的产品和服务对环境的影响。SimaPro是过去25年评估生命周期的最…

容联云发布生成式应用,让每个企业都拥有大模型沟通能力

基于容联云自主研发的赤兔大模型能力,容联云容犀机器人真正将大模型强大的理解能力、知识学习能力、总结能力、挖掘能力、推理能力融入于实际落地应用中。 开创性的打造生成式场景化智能问答、生成式智能辅助、AI运营话术库,帮助企业洞悉更精准的客户真…

【游戏开发】嘿!要听听我与口袋方舟的故事嘛

目录 写在前面 我与口袋方舟的邂逅 口袋方舟编辑器 027版本正式公测 更新亮点 粉丝福利 写在后面 写在前面 哈喽小伙伴们下午好呀,这里是一只有趣的兔子。最近博主在到处整活给大家谋福利,这次兔哥打听到了一个劲爆的消息,口袋方舟正…

加密数字货币:机遇与风险并存

随着区块链技术的发展和普及,加密数字货币逐渐走入人们的视线。作为一种以数字形式存在的资产,加密数字货币具有去中心化、匿名性和安全性高等特点,为人们提供了一种全新的支付方式和投资选择。然而,加密数字货币市场也存在着较高…

跨界融合 开放共享∣2023中国林草经济发展博鳌大会即将开启

2023第二届中国林草经济发展博鳌大会(以下简称“2023 林草大会”)将于11月19-20日在海南博鳌亚洲论坛国际会议中心盛大开幕。本次活动由海南省商务厅、海南省林业局支持,中国林业产业联合会、中国林产工业协会、华侨茶业发展研究基金会、北京…

CPU版本的pytorch安装

1.安装:Anaconda3 2.安装:torch-2.0.1cpu-cp311 2.安装:torchvision-0.15.2cpu-cp311-cp311-win_amd64 测试是否安装成功 cmd 进入python import torch print(torch.__version__) print(torch.cuda.is_available())

Protobuf 语法

Protobuf语法 1.1.1. 基本规范 文件以.proto做为文件后缀,除结构定义外的语句以分号结尾 结构定义可以包含:message、service、enum rpc方法定义结尾的分号可有可无 Message命名采用驼峰命名方式,字段命名采用小写字母加下划线分隔方式 …

conda环境下Tesseract:Failed loading language ‘eng‘问题解决

1 问题描述 使用Tesseract进行ocr文字识别,运行识别代码,报错如下: C:\Users\lishu\anaconda3\envs\pt2\python.exe D:/code/ptcontainer/opencv/car_reg.py Traceback (most recent call last): File "D:\code\ptcontainer\opencv\…

《QT从基础到进阶·三十三》QT插件开发QtPlugin

插件和dll区别: 插件 插件主要面向接口编程,无需访问.lib文件,热插拔、利于团队开发。即使在程序运行时.dll不存在,也可以正常启动,只是相应插件功能无法正常使用而已; 调用插件中的方法只要dll即可&#x…

【软件测试】接口测试中Post方法怎么测?

GET方法和POST方法传递数据的异同 http请求方法get和post是最常被用到的两个方法,get常用于向服务器请求数据,post常用于提交数据给服务器处理。 GET方法其实也可以传递少量的数据。 但它存在以下问题: 1)GET 方法不包含body,因此…

新手买电视盒子哪个好?数码粉实测电视盒子排名

新手们在买电视盒子时面对众多的品牌和机型,往往不知道电视盒子哪个好,我作为资深数码粉,已经买过十来款电视盒子了,近来某数码论坛公布了最新的电视盒子排名,我购入后进行了一周的深度实测,结果如何&#…

Java-整合OSS

文章目录 前言一、OSS 简介二、OSS 的使用1. Bucket 的创建与文件上传2. 创建 RAM 与用户授权3. 图形化管理工具-ossbrowser 三、Java 整合 OSS1. 基本实现2. 客户端直传 前言 最近公司的技术负责人让我整合下 OSS 到项目中,所以花了一点时间研究了下 OSS&#xff…

Redis内存淘汰机制

Redis内存淘汰机制 引言 Redis 启动会加载一个配置&#xff1a; maxmemory <byte> //内存上限 默认值为 0 (window版的限制为100M)&#xff0c;表示默认设置Redis内存上限。但是真实开发还是需要提前评估key的体量&#xff0c;提前设置好内容上限。 此时思考一个问题…

高质量发展项目——党务工作者能力提升培训在京成功举办

2021年6月&#xff0c;国务院办公厅印发了《关于推动公立医院高质量发展的意见》。为认真贯彻落实公立医院党建工作重点任务&#xff0c;加强公立医院党建&#xff0c;健全现代医院管理制度&#xff0c;实行党委领导下的院长负责制。发挥院级党组织把方向、管大局、作决策、促改…

flutter仿支付宝余额宝年化收益折线图

绘制: 1.在pubspec.yaml中引入:fl_chart: 0.55.2 2.绘制: import package:jade/utils/JadeColors.dart; import package:util/easy_loading_util.dart; import package:fl_chart/fl_chart.dart; import package:flutter/material.dart; import package:flutter_screenutil/…

MySQL分页查询的工作原理

前言 MySQL 的分页查询在我们的开发过程中还是很常见的&#xff0c;比如一些后台管理系统&#xff0c;我们一般会有查询订单列表页、商品列表页等。 示例&#xff1a; SELECT * FROM goods order by create_time limit 0,10; 在了解order by和limit的工作原理之前&#xff0c…

[DB] (数据库工具) navicat 平替 jookdb

jookdb 官方下载 csdn下载(免积分) 解压后直接可以使用 测试数据库适配性. mysql.mariadb.oracle.sqlserver免费使用 除外的提供20天免费试用驱动添加是java的jdbc驱动,可以通过 https://developer.aliyun.com/mvn/view 进行下载数据库的基本操作.包含数据库的新增, 库表新增…