目錄
ID 欄位
@Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "id", unique = true, nullable = false, insertable = true, updatable = false) private int id;
unique 屬性表示該欄位是否為唯一標識,預設為false。如果表中有一個欄位需要唯一標識,則既可以使用該標記,也可以使用@Table標記中的@UniqueConstraint。 nullable 屬性表示該欄位是否可以為null值,預設為true。 insertable 屬性表示在使用“INSERT”腳本插入數據時,是否需要插入該欄位的值。 updatable 屬性表示在使用“UPDATE”腳本插入數據時,是否需要更新該欄位的值。insertable和updatable屬性一般多用於只讀的屬性,例如主鍵和外鍵等。這些欄位的值通常是自動生成的。 columnDefinition屬性表示創建表時,該欄位創建的SQL語句,一般用於通過Entity生成表定義時使用。 table 屬性表示當映射多個表時,指定表的表中的欄位。預設值為主表的表名。 length 屬性表示欄位的長度,當欄位的類型為varchar時,該屬性才有效,預設為255個字元。 precision 屬性和scale屬性表示精度,當欄位類型為double時,precision表示數值的總長度,scale表示小數點所占的位數。
@Column(precision=18, scale=5) private BigDecimal principal; @Column(name="Price", columnDefinition="Decimal(10,2) default '100.00'")
public java.sql.Date createdate; 創建日期 YYYY-MM-DD public java.util.Date finisheddate; 創建日期時間 YYYY-MM-DD HH:MM:SS
Json預設為 yyyy-MM-ddTHH:mm:ss 注意日期與時間中間的T,修改日期格式將T去掉
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
Spring 提供了 import org.springframework.data.annotation.CreatedDate;
但是這些只能作用於實體類。
@CreatedDate private Date createdDateTime;
@Column(insertable = false) @org.hibernate.annotations.ColumnDefault("1.00") @org.hibernate.annotations.Generated( org.hibernate.annotations.GenerationTime.INSERT ) protected Date lastModified;
@Temporal(TemporalType.TIMESTAMP) @Column(updatable = false) @org.hibernate.annotations.CreationTimestamp protected Date createdDate;
@Column(name="update_time") @org.hibernate.annotations.UpdateTimestamp @Temporal(TemporalType.TIMESTAMP) private Date updateTime;
@Temporal(TemporalType.TIMESTAMP) @Column(insertable = false, updatable = false) @org.hibernate.annotations.Generated( org.hibernate.annotations.GenerationTime.ALWAYS )
package cn.netkiller.api.domain.elasticsearch; import java.util.Date; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.Table; @Entity @Table public class ElasticsearchTrash { @Id private int id; @Column(columnDefinition = "TIMESTAMP DEFAULT CURRENT_TIMESTAMP") private Date ctime; public int getId() { return id; } public void setId(int id) { this.id = id; } public Date getCtime() { return ctime; } public void setCtime(Date ctime) { this.ctime = ctime; } }
對應資料庫DDL
CREATE TABLE `elasticsearch_trash` ( `id` int(11) NOT NULL, `ctime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
需求是這樣的:
1. 創建時間與更新時間只能由資料庫產生,不允許在實體類中產生,因為每個節點的時間/時區不一定一直。另外防止人為插入自定義時間時間。
2. 插入記錄的時候創建預設時間,創建時間不能為空,時間一旦插入不允許日後在實體類中修改。
3. 記錄創建後更新日誌欄位為預設為 null 表示該記錄沒有被修改過。一旦數據被修改,修改日期欄位將記錄下最後的修改時間。
4. 甚至你可以通過觸發器實現一個history 表,用來記錄數據的歷史修改,詳細請參考作者另一部電子書《Netkiller Architect 手札》資料庫設計相關章節。
package cn.netkiller.api.domain.elasticsearch; import java.util.Date; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.Table; import javax.validation.constraints.Null; @Entity @Table public class ElasticsearchTrash { @Id private int id; // 創建時間 @Column(insertable = false, updatable = false, columnDefinition = "TIMESTAMP DEFAULT CURRENT_TIMESTAMP") private Date ctime; // 修改時間 @Column(nullable = true, insertable = false, updatable = false, columnDefinition = "TIMESTAMP NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP") private Date mtime; public int getId() { return id; } public void setId(int id) { this.id = id; } public Date getCtime() { return ctime; } public void setCtime(Date ctime) { this.ctime = ctime; } public Date getMtime() { return mtime; } public void setMtime(Date mtime) { this.mtime = mtime; } }
對應資料庫DDL
CREATE TABLE `elasticsearch_trash` ( `id` int(11) NOT NULL, `ctime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `mtime` timestamp NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8
需求:記錄最後一次修改時間
package cn.netkiller.api.domain.elasticsearch; import java.util.Date; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.Table; @Entity @Table public class ElasticsearchTrash { @Id private int id; @Column(columnDefinition = "TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP") private Date lastModified; }
產生DDL語句如下
CREATE TABLE `elasticsearch_trash` ( `id` int(11) NOT NULL, `last_modified` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
針對欄位做唯一索引
@Column(unique = true)
創建復合索引
package cn.netkiller.api.model; import java.io.Serializable; import java.util.Date; import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; import javax.persistence.Table; import javax.persistence.Temporal; import javax.persistence.TemporalType; import javax.persistence.UniqueConstraint; import com.fasterxml.jackson.annotation.JsonFormat; @Entity @Table(name = "comment", uniqueConstraints = { @UniqueConstraint(columnNames = { "member_id", "articleId" }) }) public class Comment implements Serializable { /** * */ private static final long serialVersionUID = -1484408775034277681L; @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "id", unique = true, nullable = false, insertable = true, updatable = false) private int id; @ManyToOne(cascade = { CascadeType.ALL }) @JoinColumn(name = "member_id") private Member member; private int articleId; private String message; @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") @Temporal(TemporalType.TIMESTAMP) @Column(updatable = false) @org.hibernate.annotations.CreationTimestamp protected Date createDate; public int getId() { return id; } public void setId(int id) { this.id = id; } public Member getMember() { return member; } public void setMember(Member member) { this.member = member; } public int getArticleId() { return articleId; } public void setArticleId(int articleId) { this.articleId = articleId; } public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } public Date getCreateDate() { return createDate; } public void setCreateDate(Date createDate) { this.createDate = createDate; } }
CREATE TABLE `comment` ( `id` int(11) NOT NULL AUTO_INCREMENT, `article_id` int(11) NOT NULL, `create_date` datetime DEFAULT NULL, `message` varchar(255) DEFAULT NULL, `member_id` int(11) DEFAULT NULL, PRIMARY KEY (`id`), UNIQUE KEY `UK5qxfiu92nwlvgli7bl3evl11m` (`member_id`,`article_id`), CONSTRAINT `FKmrrrpi513ssu63i2783jyiv9m` FOREIGN KEY (`member_id`) REFERENCES `member` (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
@Enumerated(value = EnumType.ORDINAL) //ORDINAL序數
在實體中處理枚舉類型適用於所有資料庫,Spring data 將枚舉視為 String 類型。
package cn.netkiller.api.domain; import java.io.Serializable; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Table; @Entity @Table(name = "statistics_history") public class StatisticsHistory implements Serializable { /** * */ private static final long serialVersionUID = 1L; @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "id", unique = true, nullable = false, insertable = true, updatable = false) private long id; private long memberId; private long statisticsId; public enum StatisticsType { LIKE, COMMENT, BROWSE; } private StatisticsType type; public Long getId() { return id; } public void setId(Long id) { this.id = id; } public long getMemberId() { return memberId; } public void setMemberId(long memberId) { this.memberId = memberId; } public long getStatisticsId() { return statisticsId; } public void setStatisticsId(long statisticsId) { this.statisticsId = statisticsId; } public StatisticsType getType() { return type; } public void setType(StatisticsType type) { this.type = type; } }
預設 enum 類型創建資料庫等效 int(11)
CREATE TABLE `statistics_history` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `member_id` bigint(20) NOT NULL, `statistics_id` bigint(20) NOT NULL, `type` int(11) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8; SELECT * FROM test.statistics;
@Enumerated(EnumType.STRING) 註解可以使其成功字元串類型。
public enum StatisticsType { LIKE, COMMENT, BROWSE; } @Enumerated(EnumType.STRING) private StatisticsType type;
SQL
CREATE TABLE `statistics_history` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `member_id` bigint(20) NOT NULL, `statistics_id` bigint(20) NOT NULL, `type` varchar(255) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
在枚舉中處理類型雖然可以適用於所有資料庫,但有時我們希望適用資料庫的枚舉類型(例如MySQL),資料庫中得枚舉類型要比字元串效率更高
package cn.netkiller.api.domain.elasticsearch; import java.util.Date; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.Table; @Entity @Table public class NetkillerTrash { @Id private int id; @Column(columnDefinition = "enum('Y','N') DEFAULT 'N'") private boolean status; public int getId() { return id; } public void setId(int id) { this.id = id; } public boolean isStatus() { return status; } public void setStatus(boolean status) { this.status = status; } }
實際對應的資料庫DLL
CREATE TABLE `netkiller_trash` ( `id` int(11) NOT NULL, `status` enum('Y','N') DEFAULT 'N', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8
無符號整形
package com.example.api.domain.elasticsearch; import java.util.Date; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.Table; @Entity @Table public class Member { @Id private int id; @Column(columnDefinition = "INT(10) UNSIGNED NOT NULL") private int age; @Column(insertable = false, updatable = false, columnDefinition = "TIMESTAMP DEFAULT CURRENT_TIMESTAMP") private Date ctime; @Column(nullable = true, insertable = false, updatable = false, columnDefinition = "TIMESTAMP NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP") private Date mtime; @Column(columnDefinition = "enum('Y','N') DEFAULT 'N'") private boolean status; }
CREATE TABLE `member` ( `id` int(11) NOT NULL, `age` int(10) unsigned NOT NULL, `ctime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `mtime` timestamp NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP, `status` enum('Y','N') DEFAULT 'N', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8
@JoinColumn與@Column註釋類似,它的定義如下代碼所示。
@Target({METHOD, FIELD}) @Retention(RUNTIME) public @interface JoinColumn { String name() default ""; String referencedColumnName() default ""; boolean unique() default false; boolean nullable() default true; boolean insertable() default true; boolean updatable() default true; String columnDefinition() default ""; String table() default ""; }
一對一表結構,如下面ER圖所示,users表是用戶表裡面有登陸信息,profile 保存的時死人信息,這樣的目的是我們儘量減少users表的欄位,在頻繁操作該表的時候性能比較好,另外一個目的是為了橫向水平擴展。
+----------+ +------------+ | users | | profile | +----------+ +------------+ | id | <---1:1---o | id | | name | | sex | | password | | email | +----------+ +------------+
package cn.netkiller.api.domain.test; import java.io.Serializable; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Table; @Entity @Table(name = "users") public class Users implements Serializable { @Id @GeneratedValue(strategy = GenerationType.AUTO) private int id; private String name; private String password; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } @Override public String toString() { return "Users [id=" + id + ", name=" + name + ", password=" + password + "]"; } }
package cn.netkiller.api.domain.test; import java.io.Serializable; import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.OneToOne; import javax.persistence.Table; @Entity @Table(name = "profile") public class Profile implements Serializable { /** * */ private static final long serialVersionUID = -2500499458196257167L; @Id @OneToOne @JoinColumn(name = "id") private Users users; private int age; private String sex; private String email; public Users getUsers() { return users; } public void setUsers(Users users) { this.users = users; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } @Override public String toString() { return "Profile [users=" + users + ", age=" + age + ", sex=" + sex + ", email=" + email + "]"; } }
CREATE TABLE `users` ( `id` INT(11) NOT NULL AUTO_INCREMENT, `name` VARCHAR(255) NULL DEFAULT NULL, `password` VARCHAR(255) NULL DEFAULT NULL, PRIMARY KEY (`id`) ) COLLATE='utf8_general_ci' ENGINE=InnoDB; CREATE TABLE `profile` ( `age` INT(11) NOT NULL, `email` VARCHAR(255) NULL DEFAULT NULL, `sex` VARCHAR(255) NULL DEFAULT NULL, `id` INT(11) NOT NULL, PRIMARY KEY (`id`), CONSTRAINT `FK6x079ilawxjrfsljwyyi5ujjq` FOREIGN KEY (`id`) REFERENCES `users` (`id`) ) COLLATE='utf8_general_ci' ENGINE=InnoDB;
如果第二張表關聯的並非主表的PK(主鍵)需要使用 referencedColumnName 指定。
@JoinColumn(name = "member_id",referencedColumnName="member_id")
我們要實現一個一對多實體關係,ER 圖如下
+----------+ +------------+ | Classes | | Student | +----------+ +------------+ | id | <---+ | id | | name | | | name | +----------+ +--o | classes_id | +------------+
classes 表需要 OneToMany 註解,Student 表需要 ManyToOne 註解,這樣就建立起了表與表之間的關係
package cn.netkiller.api.domain.test; import java.io.Serializable; import java.util.Set; import javax.persistence.CascadeType; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.OneToMany; import javax.persistence.Table; @Entity @Table(name="classes") public class Classes implements Serializable{ /** * */ private static final long serialVersionUID = -5422905745519948312L; @Id @GeneratedValue(strategy=GenerationType.AUTO) private int id; private String name; @OneToMany(cascade=CascadeType.ALL,mappedBy="classes") private Set<Student> students; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Set<Student> getStudents() { return students; } public void setStudents(Set<Student> students) { this.students = students; } @Override public String toString() { return "classes [id=" + id + ", name=" + name + ", students=" + students + "]"; } }
package cn.netkiller.api.domain.test; import java.io.Serializable; import javax.persistence.CascadeType; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; import javax.persistence.Table; @Entity @Table(name = "student") public class Student implements Serializable{ /** * */ private static final long serialVersionUID = 6737037465677800326L; @Id @GeneratedValue(strategy = GenerationType.AUTO) private int id; private String name; // 若有多個cascade,可以是:{CascadeType.PERSIST,CascadeType.MERGE} @ManyToOne(cascade = { CascadeType.ALL }) @JoinColumn(name = "classes_id") private Classes classes; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Classes getClasses() { return classes; } public void setClasses(Classes classes) { this.classes = classes; } @Override public String toString() { return "Student [id=" + id + ", name=" + name + ", classes=" + classes + "]"; } }
最終 SQL 表如下
CREATE TABLE `classes` ( `id` INT(11) NOT NULL AUTO_INCREMENT, `name` VARCHAR(255) NULL DEFAULT NULL, PRIMARY KEY (`id`) ) COLLATE='utf8_general_ci' ENGINE=InnoDB; CREATE TABLE `student` ( `id` INT(11) NOT NULL AUTO_INCREMENT, `name` VARCHAR(255) NULL DEFAULT NULL, `class_id` INT(11) NULL DEFAULT NULL, PRIMARY KEY (`id`), INDEX `FKnsl7w2nw6o6eq53hqlxfcijpm` (`class_id`), CONSTRAINT `FKnsl7w2nw6o6eq53hqlxfcijpm` FOREIGN KEY (`class_id`) REFERENCES `classes` (`id`) ) COLLATE='utf8_general_ci' ENGINE=InnoDB;
Classes classes=new Classes(); classes.setName("One"); Student st1=new Student(); st1.setSname("jason"); st1.setClasses(classes); studentRepostitory.save(st1); Student st2=new Student(); st2.setSname("neo"); st2.setClasses(classes); studentRepostitory.save(st2);
用戶與角色就是一個多對多的關係,多對多是需要中間表做關聯的。所以我方需要一個 user_has_role 表。
+----------+ +---------------+ +--------+ | users | | user_has_role | | role | +----------+ +---------------+ +--------+ | id | <------o | user_id | /---> | id | | name | | role_id | o---+ | name | | password | | | | | +----------+ +---------------+ +--------+
創建 User 表
package cn.netkiller.api.domain.test; import java.io.Serializable; import java.util.Set; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.JoinTable; import javax.persistence.ManyToMany; import javax.persistence.Table; import javax.persistence.JoinColumn; @Entity @Table(name = "users") public class Users implements Serializable { /** * */ private static final long serialVersionUID = -2480194112597046349L; @Id @GeneratedValue(strategy = GenerationType.AUTO) private int id; private String name; private String password; @ManyToMany(fetch = FetchType.EAGER) @JoinTable(name = "user_has_role", joinColumns = { @JoinColumn(name = "user_id", referencedColumnName = "id") }, inverseJoinColumns = { @JoinColumn(name = "role_id", referencedColumnName = "id") }) private Set<Roles> roles; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public Set<Roles> getRoles() { return roles; } public void setRoles(Set<Roles> roles) { this.roles = roles; } @Override public String toString() { return "Users [id=" + id + ", name=" + name + ", password=" + password + ", roles=" + roles + "]"; } }
創建 Role 表
package cn.netkiller.api.domain.test; import java.io.Serializable; import java.util.Set; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.ManyToMany; import javax.persistence.Table; @Entity @Table(name = "roles") public class Roles implements Serializable { private static final long serialVersionUID = 6737037465677800326L; @Id @GeneratedValue(strategy = GenerationType.AUTO) private int id; private String name; @ManyToMany(mappedBy = "roles") private Set<Users> users; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Set<Users> getUsers() { return users; } public void setUsers(Set<Users> users) { this.users = users; } @Override public String toString() { return "Roles [id=" + id + ", name=" + name + ", users=" + users + "]"; } }
最終產生資料庫表如下
CREATE TABLE `users` ( `id` INT(11) NOT NULL AUTO_INCREMENT, `name` VARCHAR(255) NULL DEFAULT NULL, `password` VARCHAR(255) NULL DEFAULT NULL, PRIMARY KEY (`id`) ) COLLATE='utf8_general_ci' ENGINE=InnoDB; CREATE TABLE `roles` ( `id` INT(11) NOT NULL AUTO_INCREMENT, `name` VARCHAR(255) NULL DEFAULT NULL, PRIMARY KEY (`id`) ) COLLATE='utf8_general_ci' ENGINE=InnoDB; CREATE TABLE `user_has_role` ( `user_id` INT(11) NOT NULL, `role_id` INT(11) NOT NULL, PRIMARY KEY (`user_id`, `role_id`), INDEX `FKsvvq61v3koh04fycopbjx72hj` (`role_id`), CONSTRAINT `FK2dl1ftxlkldulcp934i3125qo` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`), CONSTRAINT `FKsvvq61v3koh04fycopbjx72hj` FOREIGN KEY (`role_id`) REFERENCES `roles` (`id`) ) COLLATE='utf8_general_ci' ENGINE=InnoDB;
orphanRemoval = true 可以實現數據級聯刪除
package cn.netkiller.api.domain; import java.io.Serializable; import java.util.Set; import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.OneToMany; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Table; import com.fasterxml.jackson.annotation.JsonIgnore; @Entity @Table(name = "member") public class Member implements Serializable { /** * */ private static final long serialVersionUID = 1L; @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "id", unique = true, nullable = false, insertable = true, updatable = false) private int id; private String name; private String sex; private int age; private String wechat; @Column(unique = true) private String mobile; private String picture; private String ipAddress; @JsonIgnore @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, mappedBy = "member") private Set<Comment> comment; @JsonIgnore @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, mappedBy = "member") private Set<StatisticsHistory> statisticsHistory; public Member() { } public Member(int id) { this.id = id; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getWechat() { return wechat; } public void setWechat(String wechat) { this.wechat = wechat; } public String getMobile() { return mobile; } public void setMobile(String mobile) { this.mobile = mobile; } public String getPicture() { return picture; } public void setPicture(String picture) { this.picture = picture; } public String getIpAddress() { return ipAddress; } public void setIpAddress(String ipAddress) { this.ipAddress = ipAddress; } @Override public String toString() { return "Member [id=" + id + ", name=" + name + ", sex=" + sex + ", age=" + age + ", wechat=" + wechat + ", mobile=" + mobile + ", picture=" + picture + ", ipAddress=" + ipAddress + "]"; } }