# 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
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
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
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
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
2
3
4
5
6
7
8