首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >OpenHarmony父子组件单项同步使用:@Prop装饰器

OpenHarmony父子组件单项同步使用:@Prop装饰器

原创
作者头像
小帅聊鸿蒙
发布于 2025-05-14 08:09:21
发布于 2025-05-14 08:09:21
940
举报
文章被收录于专栏:鸿蒙开发笔记鸿蒙开发笔记

@Prop装饰的变量可以和父组件建立单向的同步关系。@Prop装饰的变量是可变的,但是变化不会同步回其父组件。

说明:API version 9开始,该装饰器支持在ArkTS卡片中使用。

概述

@Prop装饰的变量和父组件建立单向的同步关系:

● @Prop变量允许在本地修改,但修改后的变化不会同步回父组件。

● 当数据源更改时,@Prop装饰的变量都会更新,并且会覆盖本地所有更改。因此,数值的同步是父组件到子组件(所属组件),子组件数值的变化不会同步到父组件。

装饰器使用规则说明

@Prop变量装饰器

说明

装饰器参数

同步类型

单向同步:对父组件状态变量值的修改,将同步给子组件@Prop装饰的变量,子组件@Prop变量的修改不会同步到父组件的状态变量上。嵌套类型的场景请参考 观察变化 。

允许装饰的变量类型

Object、class、string、number、boolean、enum类型,以及这些类型的数组。 不支持any,不支持简单类型和复杂类型的联合类型,不允许使用undefined和null。 支持Date类型。 支持类型的场景请参考观察变化。 必须指定类型。 说明 : 不支持Length、ResourceStr、ResourceColor类型,Length,ResourceStr、ResourceColor为简单类型和复杂类型的联合类型。在父组件中,传递给@Prop装饰的值不能为undefined或者null,反例如下所示。 CompA ({ aProp: undefined }); CompA ({ aProp: null }) @Prop和数据源类型需要相同,有以下三种情况: - @Prop装饰的变量和@State以及其他装饰器同步时双方的类型必须相同,示例请参考父组件@State到子组件@Prop简单数据类型同步。 - @Prop装饰的变量和@State以及其他装饰器装饰的数组的项同步时 ,@Prop的类型需要和@State装饰的数组的数组项相同,比如@Prop : T和@State : Array<T>,示例请参考 父组件@State数组中的项到子组件@Prop简单数据类型同步; - 当父组件状态变量为Object或者class时,@Prop装饰的变量和父组件状态变量的属性类型相同,示例请参考 从父组件中的@State类对象属性到@Prop简单类型的同步 。

嵌套传递层数

在组件复用场景,建议@Prop深度嵌套数据不要超过5层,嵌套太多会导致深拷贝占用的空间过大以及GarbageCollection(垃圾回收),引起性能问题,此时更建议使用 @ObjectLink 。如果子组件的数据不想同步回父组件,建议采用@Reusable中的aboutToReuse,实现父组件向子组件传递数据,具体用例请参考 组件复用场景。

被装饰变量的初始值

允许本地初始化。

变量的传递/访问规则说明

传递/访问

说明

从父组件初始化

如果本地有初始化,则是可选的。没有的话,则必选,支持父组件中的常规变量(常规变量对@Prop赋值,只是数值的初始化,常规变量的变化不会触发UI刷新。只有状态变量才能触发UI刷新)、@State、@Link、@Prop、@Provide、@Consume、@ObjectLink、@StorageLink、@StorageProp、@LocalStorageLink和@LocalStorageProp去初始化子组件中的@Prop变量。

用于初始化子组件

@Prop支持去初始化子组件中的常规变量、@State、@Link、@Prop、@Provide。

是否支持组件外访问

@Prop装饰的变量是私有的,只能在组件内访问。

图1 初始化规则图示  

观察变化和行为表现

观察变化

@Prop装饰的数据可以观察到以下变化。

● 当装饰的类型是允许的类型,即Object、class、string、number、boolean、enum类型都可以观察到赋值的变化。

代码语言:ts
AI代码解释
复制
// 简单类型
@Prop count: number;
// 赋值的变化可以被观察到
this.count = 1;
// 复杂类型
@Prop count: Model;
// 可以观察到赋值的变化
this.title = new Model('Hi');

当装饰的类型是Object或者class复杂类型时,可以观察到第一层的属性的变化,属性即Object.keys(observedObject)返回的所有属性;

代码语言:ts
AI代码解释
复制
class ClassA {
  public value: string;
  constructor(value: string) {
    this.value = value;
  }
}
class Model {
  public value: string;
  public a: ClassA;
  constructor(value: string, a: ClassA) {
    this.value = value;
    this.a = a;
  }
}
 
@Prop title: Model;
// 可以观察到第一层的变化
this.title.value = 'Hi'
// 观察不到第二层的变化
this.title.a.value = 'ArkUi'

对于嵌套场景,如果class是被@Observed装饰的,可以观察到class属性的变化,示例请参考 @Prop嵌套场景 。

当装饰的类型是数组的时候,可以观察到数组本身的赋值、添加、删除和更新。

代码语言:ts
AI代码解释
复制
// @State装饰的对象为数组时
@Prop title: string[]
// 数组自身的赋值可以观察到
this.title = ['1']
// 数组项的赋值可以观察到
this.title[0] = '2'
// 删除数组项可以观察到
this.title.pop()
// 新增数组项可以观察到
this.title.push('3')

对于@State和@Prop的同步场景:

● 使用父组件中@State变量的值初始化子组件中的@Prop变量。当@State变量变化时,该变量值也会同步更新至@Prop变量。

● @Prop装饰的变量的修改不会影响其数据源@State装饰变量的值。

● 除了@State,数据源也可以用@Link或@Prop装饰,对@Prop的同步机制是相同的。

● 数据源和@Prop变量的类型需要相同,@Prop允许简单类型和class类型。

● 当装饰的对象是Date时,可以观察到Date整体的赋值,同时可通过调用Date的接口setFullYear, setMonth, setDate, setHours, setMinutes, setSeconds, setMilliseconds, setTime, setUTCFullYear, setUTCMonth, setUTCDate, setUTCHours, setUTCMinutes, setUTCSeconds, setUTCMilliseconds 更新Date的属性。

代码语言:ts
AI代码解释
复制
@Component
struct DateComponent {
  @Prop selectedDate: Date = new Date('');
 
  build() {
    Column() {
      Button('child update the new date')
        .margin(10)
        .onClick(() => {
          this.selectedDate = new Date('2023-09-09')
        })
      Button(`child increase the year by 1`).onClick(() => {
        this.selectedDate.setFullYear(this.selectedDate.getFullYear() + 1)
      })
      DatePicker({
        start: new Date('1970-1-1'),
        end: new Date('2100-1-1'),
        selected: this.selectedDate
      })
    }
  }
}
 
@Entry
@Component
struct ParentComponent {
  @State parentSelectedDate: Date = new Date('2021-08-08');
 
  build() {
    Column() {
      Button('parent update the new date')
        .margin(10)
        .onClick(() => {
          this.parentSelectedDate = new Date('2023-07-07')
        })
      Button('parent increase the day by 1')
        .margin(10)
        .onClick(() => {
          this.parentSelectedDate.setDate(this.parentSelectedDate.getDate() + 1)
        })
      DatePicker({
        start: new Date('1970-1-1'),
        end: new Date('2100-1-1'),
        selected: this.parentSelectedDate
      })
 
      DateComponent({selectedDate:this.parentSelectedDate})
    }
 
  }
}

框架行为

要理解@Prop变量值初始化和更新机制,有必要了解父组件和拥有@Prop变量的子组件初始渲染和更新流程。

1.  初始渲染:

a.  执行父组件的build()函数将创建子组件的新实例,将数据源传递给子组件;

b.  初始化子组件@Prop装饰的变量。

2.  更新:

a.  子组件@Prop更新时,更新仅停留在当前子组件,不会同步回父组件;

b.  当父组件的数据源更新时,子组件的@Prop装饰的变量将被来自父组件的数据源重置,所有@Prop装饰的本地的修改将被父组件的更新覆盖。

使用场景

父组件@State到子组件@Prop简单数据类型同步

以下示例是@State到子组件@Prop简单数据同步,父组件ParentComponent的状态变量countDownStartValue初始化子组件CountDownComponent中@Prop装饰的count,点击“Try again”,count的修改仅保留在CountDownComponent 不会同步给父组件ParentComponent。

ParentComponent的状态变量countDownStartValue的变化将重置CountDownComponent的count。

代码语言:ts
AI代码解释
复制
@Component
struct CountDownComponent {
  @Prop count: number = 0;
  costOfOneAttempt: number = 1;
 
  build() {
    Column() {
      if (this.count > 0) {
        Text(`You have ${this.count} Nuggets left`)
      } else {
        Text('Game over!')
      }
      // @Prop装饰的变量不会同步给父组件
      Button(`Try again`).onClick(() => {
        this.count -= this.costOfOneAttempt;
      })
    }
  }
}
 
@Entry
@Component
struct ParentComponent {
  @State countDownStartValue: number = 10;
 
  build() {
    Column() {
      Text(`Grant ${this.countDownStartValue} nuggets to play.`)
      // 父组件的数据源的修改会同步给子组件
      Button(`+1 - Nuggets in New Game`).onClick(() => {
        this.countDownStartValue += 1;
      })
      // 父组件的修改会同步给子组件
      Button(`-1  - Nuggets in New Game`).onClick(() => {
        this.countDownStartValue -= 1;
      })
 
      CountDownComponent({ count: this.countDownStartValue, costOfOneAttempt: 2 })
    }
  }
}

在上面的示例中:

1.  CountDownComponent子组件首次创建时其@Prop装饰的count变量将从父组件@State装饰的countDownStartValue变量初始化;

2.  按“+1”或“-1”按钮时,父组件的@State装饰的countDownStartValue值会变化,这将触发父组件重新渲染,在父组件重新渲染过程中会刷新使用countDownStartValue状态变量的UI组件并单向同步更新CountDownComponent子组件中的count值;

3.  更新count状态变量值也会触发CountDownComponent的重新渲染,在重新渲染过程中,评估使用count状态变量的if语句条件(this.count > 0),并执行true分支中的使用count状态变量的UI组件相关描述来更新Text组件的UI显示;

4.  当按下子组件CountDownComponent的“Try again”按钮时,其@Prop变量count将被更改,但是count值的更改不会影响父组件的countDownStartValue值;

5.  父组件的countDownStartValue值会变化时,父组件的修改将覆盖掉子组件CountDownComponent中count本地的修改。

父组件@State数组项到子组件@Prop简单数据类型同步

父组件中@State如果装饰的数组,其数组项也可以初始化@Prop。以下示例中父组件Index中@State装饰的数组arr,将其数组项初始化子组件Child中@Prop装饰的value。

代码语言:ts
AI代码解释
复制
@Component
struct Child {
  @Prop value: number = 0;
 
  build() {
    Text(`${this.value}`)
      .fontSize(50)
      .onClick(()=>{this.value++})
  }
}
 
@Entry
@Component
struct Index {
  @State arr: number[] = [1,2,3];
 
  build() {
    Row() {
      Column() {
        Child({value: this.arr[0]})
        Child({value: this.arr[1]})
        Child({value: this.arr[2]})
 
        Divider().height(5)
 
        ForEach(this.arr,
          (item: void) => {
            Child({value: item})
          },
          (item: string) => item.toString()
        )
        Text('replace entire arr')
        .fontSize(50)
        .onClick(()=>{
          // 两个数组都包含项“3”。
          this.arr = this.arr[0] == 1 ? [3,4,5] : [1,2,3];
        })
      }
    }
  }
}

初始渲染创建6个子组件实例,每个@Prop装饰的变量初始化都在本地拷贝了一份数组项。子组件onclick事件处理程序会更改局部变量值。

假设我们点击了多次,所有变量的本地取值都是“7”。

代码语言:shell
AI代码解释
复制
7
7
7
----
7
7
7

单击replace entire arr后,屏幕将显示以下信息。

代码语言:shell
AI代码解释
复制
3
4
5
----
7
4
5

● 在子组件Child中做的所有的修改都不会同步回父组件Index组件,所以即使6个组件显示都为7,但在父组件Index中,this.arr保存的值依旧是1,2,3。

● 点击replace entire arr,this.arr0 == 1成立,将this.arr赋值为3, 4, 5;

● 因为this.arr0已更改,Child({value: this.arr0})组件将this.arr0更新同步到实例@Prop装饰的变量。Child({value: this.arr1})和Child({value: this.arr2})的情况也类似。

● this.arr的更改触发ForEach更新,this.arr更新的前后都有数值为3的数组项:3, 4, 5 和1, 2, 3。根据diff机制,数组项“3”将被保留,删除“1”和“2”的数组项,添加为“4”和“5”的数组项。这就意味着,数组项“3”的组件不会重新生成,而是将其移动到第一位。所以“3”对应的组件不会更新,此时“3”对应的组件数值为“7”,ForEach最终的渲染结果是“7”,“4”,“5”。

DD一下:欢迎大家关注工粽号<程序猿百晓生>,可以了解到以下知识点。
代码语言:erlang
AI代码解释
复制
`欢迎大家关注工粽号<程序猿百晓生>,可以了解到以下知识点。`
1.OpenHarmony开发基础
2.OpenHarmony北向开发环境搭建
3.鸿蒙南向开发环境的搭建
4.鸿蒙生态应用开发白皮书V2.0 & V3.0
5.鸿蒙开发面试真题(含参考答案) 
6.TypeScript入门学习手册
7.OpenHarmony 经典面试题(含参考答案)
8.OpenHarmony设备开发入门【最新版】
9.沉浸式剖析OpenHarmony源代码
10.系统定制指南
11.OpenHarmonyUboot 驱动加载流程
12.OpenHarmony构建系统--GN与子系统、部件、模块详解
13.ohos开机init启动流程
14.鸿蒙版性能优化指南
.......

从父组件中的@State类对象属性到@Prop简单类型的同步

如果图书馆有一本图书和两位用户,每位用户都可以将图书标记为已读,此标记行为不会影响其它读者用户。从代码角度讲,对@Prop图书对象的本地更改不会同步给图书馆组件中的@State图书对象。

在此示例中,图书类可以使用@Observed装饰器,但不是必须的,只有在嵌套结构时需要此装饰器。这一点我们会在 从父组件中的@State数组项到@Prop class类型的同步 说明。

代码语言:ts
AI代码解释
复制
class Book {
  public title: string;
  public pages: number;
  public readIt: boolean = false;
 
  constructor(title: string, pages: number) {
    this.title = title;
    this.pages = pages;
  }
}
 
@Component
struct ReaderComp {
  @Prop book: Book = new Book("", 0);
 
  build() {
    Row() {
      Text(this.book.title)
      Text(`...has${this.book.pages} pages!`)
      Text(`...${this.book.readIt ? "I have read" : 'I have not read it'}`)
        .onClick(() => this.book.readIt = true)
    }
  }
}
 
@Entry
@Component
struct Library {
  @State book: Book = new Book('100 secrets of C++', 765);
 
  build() {
    Column() {
      ReaderComp({ book: this.book })
      ReaderComp({ book: this.book })
    }
  }
}

从父组件中的@State数组项到@Prop class类型的同步

在下面的示例中,更改了@State 修饰的allBooks数组中Book对象上的属性,但点击“Mark read for everyone”无反应。这是因为该属性是第二层的嵌套属性,@State装饰器只能观察到第一层属性,不会观察到此属性更改,所以框架不会更新ReaderComp。

代码语言:ts
AI代码解释
复制
let nextId: number = 1;
 
// @Observed
class Book {
  public id: number;
  public title: string;
  public pages: number;
  public readIt: boolean = false;
 
  constructor(title: string, pages: number) {
    this.id = nextId++;
    this.title = title;
    this.pages = pages;
  }
}
 
@Component
struct ReaderComp {
  @Prop book: Book = new Book("", 1);
 
  build() {
    Row() {
      Text(this.book.title)
      Text(`...has${this.book.pages} pages!`)
      Text(`...${this.book.readIt ? "I have read" : 'I have not read it'}`)
        .onClick(() => this.book.readIt = true)
    }
  }
}
 
@Entry
@Component
struct Library {
  @State allBooks: Book[] = [new Book("100 secrets of C++", 765), new Book("Effective C++", 651), new Book("The C++ programming language", 1765)];
 
  build() {
    Column() {
      Text('library`s all time favorite')
      ReaderComp({ book: this.allBooks[2] })
      Divider()
      Text('Books on loaan to a reader')
      ForEach(this.allBooks, (book: Book) => {
        ReaderComp({ book: book })
      },
        (book: Book) => book.id.toString())
      Button('Add new')
        .onClick(() => {
          this.allBooks.push(new Book("The C++ Standard Library", 512));
        })
      Button('Remove first book')
        .onClick(() => {
          this.allBooks.shift();
        })
      Button("Mark read for everyone")
        .onClick(() => {
          this.allBooks.forEach((book) => book.readIt = true)
        })
    }
  }
}

需要使用@Observed装饰class Book,Book的属性将被观察。 需要注意的是,@Prop在子组件装饰的状态变量和父组件的数据源是单向同步关系,即ReaderComp中的@Prop book的修改不会同步给父组件Library。而父组件只会在数值有更新的时候(和上一次状态的对比),才会触发UI的重新渲染。

代码语言:ts
AI代码解释
复制
@Observed
class Book {
  public id: number;
  public title: string;
  public pages: number;
  public readIt: boolean = false;
 
  constructor(title: string, pages: number) {
    this.id = nextId++;
    this.title = title;
    this.pages = pages;
  }
}

@Observed装饰的类的实例会被不透明的代理对象包装,此代理可以检测到包装对象内的所有属性更改。如果发生这种情况,此时,代理通知@Prop,@Prop对象值被更新。

@Prop本地初始化不和父组件同步

为了支持@Component装饰的组件复用场景,@Prop支持本地初始化,这样可以让@Prop是否与父组件建立同步关系变得可选。当且仅当@Prop有本地初始化时,从父组件向子组件传递@Prop的数据源才是可选的。

下面的示例中,子组件包含两个@Prop变量:

● @Prop customCounter没有本地初始化,所以需要父组件提供数据源去初始化@Prop,并当父组件的数据源变化时,@Prop也将被更新;

● @Prop customCounter2有本地初始化,在这种情况下,@Prop依旧允许但非强制父组件同步数据源给@Prop。

代码语言:ts
AI代码解释
复制
@Component
struct MyComponent {
  @Prop customCounter: number = 0;
  @Prop customCounter2: number = 5;
 
  build() {
    Column() {
      Row() {
        Text(`From Main: ${this.customCounter}`).width(90).height(40).fontColor('#FF0010')
      }
 
      Row() {
        Button('Click to change locally !').width(180).height(60).margin({ top: 10 })
          .onClick(() => {
            this.customCounter2++
          })
      }.height(100).width(180)
 
      Row() {
        Text(`Custom Local: ${this.customCounter2}`).width(90).height(40).fontColor('#FF0010')
      }
    }
  }
}
 
@Entry
@Component
struct MainProgram {
  @State mainCounter: number = 10;
 
  build() {
    Column() {
      Row() {
        Column() {
          Button('Click to change number').width(480).height(60).margin({ top: 10, bottom: 10 })
            .onClick(() => {
              this.mainCounter++
            })
        }
      }
 
      Row() {
        Column() {
          // customCounter必须从父组件初始化,因为MyComponent的customCounter成员变量缺少本地初始化;此处,customCounter2可以不做初始化。
          MyComponent({ customCounter: this.mainCounter })
          // customCounter2也可以从父组件初始化,父组件初始化的值会覆盖子组件customCounter2的本地初始化的值
          MyComponent({ customCounter: this.mainCounter, customCounter2: this.mainCounter })
        }
      }
    }
  }
}

@Prop嵌套场景

在嵌套场景下,每一层都要用@Observed装饰,且每一层都要被@Prop接收,这样才能观察到嵌套场景。

代码语言:ts
AI代码解释
复制
// 以下是嵌套类对象的数据结构。
@Observed
class ClassA {
  public title: string;
 
  constructor(title: string) {
    this.title = title;
  }
}
 
@Observed
class ClassB {
  public name: string;
  public a: ClassA;
 
  constructor(name: string, a: ClassA) {
    this.name = name;
    this.a = a;
  }
}

以下组件层次结构呈现的是@Prop嵌套场景的数据结构

代码语言:ts
AI代码解释
复制
@Entry
@Component
struct Parent {
  @State votes: ClassB = new ClassB('Hello', new ClassA('world'))
 
  build() {
    Column() {
      Button('change')
        .onClick(() => {
          this.votes.name = "aaaaa"
          this.votes.a.title = "wwwww"
        })
      Child({ vote: this.votes })
    }
 
  }
}
 
@Component
struct Child {
  @Prop vote: ClassB = new ClassB('', new ClassA(''));
  build() {
    Column() {
 
      Text(this.vote.name).fontSize(36).fontColor(Color.Red).margin(50)
        .onClick(() => {
          this.vote.name = 'Bye'
        })
      Text(this.vote.a.title).fontSize(36).fontColor(Color.Blue)
        .onClick(() => {
          this.vote.a.title = "openHarmony"
        })
      Child1({vote1:this.vote.a})
 
    }
  }
}
 
@Component
struct Child1 {
  @Prop vote1: ClassA = new ClassA('');
  build() {
    Column() {
      Text(this.vote1.title).fontSize(36).fontColor(Color.Red).margin(50)
        .onClick(() => {
          this.vote1.title = 'Bye Bye'
        })
    }
  }
}

写在最后

如果你觉得这篇内容对你还蛮有帮助,我想邀请你帮我三个小忙:

  • 点赞,转发,有你们的 『点赞和评论』,才是我创造的动力;
  • 关注小编,同时可以期待后续文章ing🚀,不定期分享原创知识;
  • 想要获取更多完整鸿蒙最新学习知识点,可关注B站:码牛课堂;

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
Mybatis报Invalid bound statement,终于被我找到原因了
SQL语句是写在XML里面的,ResultMap写了一百多行,整个文件上千行。代码混乱不好管理,就计划升级到MyBatis Plus。
大风写全栈
2024/11/29
1.7K0
Mybatis报Invalid bound statement,终于被我找到原因了
从零搭建SpringBoot+MyBatis+MySQL工程
使用依赖:web(前后端交互)、mybatis(持久层)、mysql(数据库驱动)
小锋学长生活大爆炸
2020/09/07
4240
从零搭建SpringBoot+MyBatis+MySQL工程
Mybatis mapper动态代理解决方案
我们在使用Mybatis的时候,获取需要执行的SQL语句的时候,都是通过调用xml文件来获取,例如:User user = (User) sqlSession.selectOne("cn.ddnd.www.Entity.User.getUser", "xue8@qq.com");。这种方式是通过字符串去调用标签定义的SQL语句,第一容易出错,第二是当xml当中的id修改过后你不知道在程序当中有多少个地方使用了这个id,需要手动一一修改。后来Mybatis推出了Mapper动态代理方式,只需要编写Mapper接口(相当于Dao层),由Mybatis框架根据接口定义创建接口的动态代理对象。
科技新语
2024/06/03
1520
Spring Boot整合MyBatis(保姆级教程)
本文通过 Spring Boot + MyBatis 实现一个用户管理的例子,来带大家入门 MyBatis。本教程适合小白入手,文中如有差错还请各位不吝赐教,大家一起学习,共同进步。
astonishqft
2023/03/08
9740
Spring Boot整合MyBatis(保姆级教程)
Mybatis的dao层实现 接口代理方式实现规范+plugins-PageHelper
Mapper接口开发只需要程序员编写Mapper接口而不用具体实现其代码(相当于我们写的Imp实现类)
一只胡说八道的猴子
2020/11/12
3540
Mybatis的dao层实现 接口代理方式实现规范+plugins-PageHelper
SpringBoot 整合mybatis操作数据库
MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJOs(Plain Ordinary Java Object,普通的 Java对象)映射成数据库中的记录。
jwangkun
2021/12/23
3450
【愚公系列】2023年03月 Java教学课程 116-Mybatis(动态代理和动态SQL)
Mybatis的动态代理是指在运行时动态生成DAO接口的实现类,这个实现类不需要手动编写,而是由Mybatis框架自动生成。
愚公搬代码
2023/04/03
3690
【愚公系列】2023年03月 Java教学课程 116-Mybatis(动态代理和动态SQL)
spring boot 整合mybatis 提示Invalid bound statement 解决记录
在spring boot 整合 mybatis 的时候提示。org.apache.ibatis.binding.BindingException: Invalid bound statement 。
凯哥Java
2019/06/28
2.7K0
「2020最新」Spring最易学习教程 4—整合Mybatis 事务控制
到目前为止web.xml中出现的标签:servlet filter listener context-param。
鹿老师的Java笔记
2020/08/06
3730
【框架】[MyBatis]DAO层只写接口,不用写实现类
团队开发一个项目,由老大架了一个框架,遇到了DAO层不用写接口了,我也是用了2次才记住这个事的,因为自己一直都是习惯于写DAO层的实现类,所以,习惯性的还是写了个实现类。于是遇到错误了。
谙忆
2021/01/21
6150
【框架】[MyBatis]DAO层只写接口,不用写实现类
Mybatis框架复习大纲【面试+提高】
Mybatis框架复习大纲【面试+提高】 1.MyBatis面试题汇总 1.1 JDBC编程有哪些不足之处,MyBatis是如何解决这些问题的? ① 数据库链接创建、释放频繁造成系统资源浪费从而影响系统性能,如果使用数据库链接池可解决此问题。 解决:在SqlMapConfig.xml中配置数据链接池,使用连接池管理数据库链接。 ② Sql语句写在代码中造成代码不易维护,实际应用sql变化的可能较大,sql变动需要改变java代码。 解决:将Sql语句配置在XXXXmapper.xml文件中与java代码分
Java帮帮
2018/03/30
1.2K0
Mybatis框架复习大纲【面试+提高】
MyBatis学习笔记(一) --- MyBatis入门
MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis 。2013年11月迁移到Github。 
挽风
2021/04/13
1.4K0
MyBatis学习笔记(一) --- MyBatis入门
MyBatis常见报错问题记录汇总(例:org. apache. ibatis.binding.BindingException_ Invalid bound statement (not found
最常见的报错就是这个了: org. apache. ibatis.binding.BindingException: Invalid bound statement (not found): 找不到绑定的statement。 简单说,就是接口与xml要么是找不到,要么是找到了却匹配不到对应的方法id。 请按照如下步骤检查:
共饮一杯无
2022/11/28
7.6K0
MyBatis常见报错问题记录汇总(例:org. apache. ibatis.binding.BindingException_ Invalid bound statement (not found
跟我一起学mybatis(2)
​ 采用 Mybatis 的代理开发方式实现 DAO 层的开发,这种方式是我们后面进入企业的主流。
楠羽
2022/11/18
4230
跟我一起学mybatis(2)
MyBatis常见面试题总结
(原创不易,你们对阿超的赞就是阿超持续更新的动力!) (以免丢失,建议收藏) (------------------------------------------------------------------------) 什么是MyBatis Mybatis是一个半ORM(对象关系映射)框架,它内部封装了JDBC,加载驱动、创建连接、创建statement等繁杂的过程,开发者开发时只需要关注如何编写SQL语句,可以严格控制sql执行性能,灵活度高。 作为一个半ORM框架,MyBatis 可以使用
是阿超
2021/10/21
2K0
浅谈Mybatis持久化框架在Spring、SSM、SpringBoot整合的演进及简化过程
最近开始了SpringBoot相关知识的学习,作为为目前比较流行、用的比较广的Spring框架,是每一个Java学习者及从业者都会接触到一个知识点。作为Spring框架项目,肯定少不了与数据库持久层的整合。我们在学习Java初始就被灌输SSM框架(Spring、SpringMVC、Mybatis),我们大概也只是知道Mybatis是与数据库打交道的,但这也只是名词上的理解。
Java_老男孩
2020/08/11
5730
Mybatis常见面试题总结
(1)Mybatis是一个半ORM(对象关系映射)框架,它内部封装了JDBC,加载驱动、创建连接、创建statement等繁杂的过程,开发者开发时只需要关注如何编写SQL语句,可以严格控制sql执行性能,灵活度高。
全栈程序员站长
2022/06/29
1K0
整合SSM框架应用
settings-build-compiler->勾选build project autoxxx选项
HUC思梦
2020/09/03
7110
整合SSM框架应用
SpringBoot 2.x 集成 Mybatis
首先, SpringBoot 版本是 2.3.0.RELEASE, 数据库用的是 MariaDB
北漂的我
2020/06/09
5850
mybatis-plus/mybatis 自定义 sql 语句、动态 sql
MyBatis-Plus(简称 MP)是一个 MyBatis 的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。在 Java 项目内,配置如下:
create17
2019/11/01
46.5K0
mybatis-plus/mybatis 自定义 sql 语句、动态 sql
推荐阅读
相关推荐
Mybatis报Invalid bound statement,终于被我找到原因了
更多 >
LV.0
这个人很懒,什么都没有留下~
目录
  • 概述
  • 装饰器使用规则说明
  • 变量的传递/访问规则说明
  • 观察变化和行为表现
    • 观察变化
    • 框架行为
  • 使用场景
    • 父组件@State到子组件@Prop简单数据类型同步
    • 父组件@State数组项到子组件@Prop简单数据类型同步
      • DD一下:欢迎大家关注工粽号<程序猿百晓生>,可以了解到以下知识点。
    • 从父组件中的@State类对象属性到@Prop简单类型的同步
    • 从父组件中的@State数组项到@Prop class类型的同步
    • @Prop本地初始化不和父组件同步
    • @Prop嵌套场景
  • 写在最后
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档