Hibernate 和 Mongoose

# Hibernate 和 Mongoose

# Hibernate (中译:冬眠,开放源代码的对象关系映射框架)

Hibernate 是一个开放源代码的对象关系映射框架,它对 JDBC 进行了非常轻量级的对象封装,它将 POJO 与数据库表建立映射关系,是一个全自动的 orm 框架,hibernate 可以自动生成 SQL 语句,自动执行,使得 Java 程序员可以随心所欲的使用对象编程思维来操纵数据库。 Hibernate 可以应用在任何使用 JDBC 的场合,既可以在 Java 的客户端程序使用,也可以在 Servlet/JSP 的 Web 应用中使用,最具革命意义的是,Hibernate 可以在应用 EJB 的 JavaEE 架构中取代 CMP,完成数据持久化的重任。

# Mongoose (中译:猫鼬)

是配合 MongoDB 使用的 ORM(Object Relationship Map: 对象关系映射)库。一句话,就是让我们可以用面向对象的思维操作数据库,换句话来讲就是根本不需要考虑数据的持久化,对象改变了,数据自动改变。也就是数据会被 Mongoose 自动持久化。

# Mongoose hello-world

const mongoose = require("mongoose");
mongoose.connect("mongodb://localhost/test");

const Student = mongoose.model("Student", {
  name: String,
  sex: String,
  age: Number,
});

const zhangsan = new Student({
  name: "张三",
  sex: "男",
  age: 18,
});

zhangsan.save();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

# Schema

const { Schema } = mongoose;
const personSchema = new Schema({
  name: String, // String is shorthand for {type: String}
  sex: String,
  age: Number,
  date: { type: Date, default: Date.now },
  hobby: [String],
  scores: [
    {
      subject: String,
      score: Number,
    },
  ],
});

const Person = mongoose.model("Person", personSchema);

const xiaoming = new Person({
  name: "小明",
  sex: "男",
  age: 15,
  hobby: ["篮球", "游泳"],
  scores: [
    { subject: "语文", score: 99 },
    { subject: "数学", score: 100 },
    { subject: "英语", score: 99 },
    { subject: "体育", score: 99 },
  ],
  nationality: { type: Sting, default: "汉族" },
});

xiaoming.save();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32

一旦设置了 schema 就要严格按照 schema 使用,schema 是可以随时增加、删除、改变项目的。一旦改变 schema,此时就要按照新的 schema 来执行吗,之前的不用管。

如果 schema 中没有声明。但是实例化的对象中有这个属性,此时多余的属性不会被持久化。

但是反过来。实例化的对象没有 schema 的属性吗,则会是空的属性,这说明 schema 声明的项不是必填的。

# 静态方法 & 动态方法

  • 静态方法:要定义在 schema 上 xxSchema.statics.xxx = () => {} 是类本身能够调用的方法,例如 Math.random()
personSchema.statics.findByName = (name, cb = () => {}) => {
  // this: 这个thi指代的是数据表,就是 Persons
  this.find({ name: name }, (error, results) => {
    // results 是一个数组
    cb(results);
  });
};

personSchema.statics.changePersonName = (name) => {
  // this: 这个thi指代的是数据表,就是 Persons
  this.find({ name: name }, (error, results) => {
    // results 是一个数组
    results.forEach((res) => {
      if (res.name === "小明") {
        res.name = "小张";
        // 持久化
        res.save();
      }
    });
  });
};

personSchema.statics.formatSexByName = (name) => {
  // this: 这个thi指代的是数据表,就是 Persons
  this.find({ name: name }, (error, results) => {
    // results 是一个实例数组
    results.forEach((res) => {
      // 实例调用它自己的动态方法
      res.formatSex();
    });
  });
};

Persons.findByName("小明");
Persons.changePersonName("小明");
Persons.formatSexByName("小明");
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
  • 动态方法:要定义在 schema 上 xSchema.methods.xxx = ()=>{} 是实例能够调用的方法,例如 xiaoming.sayHello()
personSchema.methods.sayHello = (name) => {
  // this: 动态方法中的动态方法指向这个实例
  if (this.name) console.log("你好! 我是" + this.name);
};
personSchema.methods.formatSex = () => {
  // this: 动态方法中的动态方法指向这个实例
  if (this.sex === "男") {
    this.sex = "male";
  } else {
    this.sex = "female";
  }
  this.save();
};
1
2
3
4
5
6
7
8
9
10
11
12
13
  • Mongoose 中的静态方法能够返回得到 Mongoose 的 Model 的实例,这个实例又可以调用 schema 中定义好的动态方法
// 调用方法的时候,外层一定有一个静态方法,静态包裹动态。因为只有静态方法能够返回类的实例!
// 类的实例才可以调用动态方法

Person.findName("小明", (results) => {
  results.foreach((res) => {
    res.sayHello();
  });
});
1
2
3
4
5
6
7
8
Last Updated: 2022/8/30 上午10:39:18