zoukankan      html  css  js  c++  java
  • MP实战系列(三)之实体类讲解

    首先说一句,mybatis plus实在太好用了!

    mybaits plus的实体类:

    以我博客的用户类作为讲解

    package com.blog.entity;
    
    import com.baomidou.mybatisplus.annotations.TableField;
    import com.baomidou.mybatisplus.annotations.TableId;
    import com.baomidou.mybatisplus.annotations.TableLogic;
    import com.baomidou.mybatisplus.annotations.TableName;
    import com.baomidou.mybatisplus.enums.IdType;
    
    import java.io.Serializable;
    import java.util.Date;
    
    /**
     * 
     * 
     * @author youcong
     * @email ${email}
     * @date 2018-04-21 15:27:01
     */
    @TableName("user")
    public class UserEntity implements Serializable {
        private static final long serialVersionUID = 1L;
    
        /**
         * 用户ID
         */
        @TableId(type=IdType.AUTO)
        private Integer user_id;
        /**
         * 用户名
         */
        private String username;
        /**
         * 性别
         */
        private String sex;
        /**
         * 电话
         */
        private String phone;
        /**
         * 密码
         */
        private String password;
        /**
         * 等级
         */
        private Integer level;
        /**
         * 用户创建时间
         */
        @TableField(value="create_time")
        private String createTime;
        /**
         * 邮箱
         */
        private String email;
        /**
         * 登录标识
         */
        private Integer logo;
    
        /**
         * 设置:用户ID
         */
        public void setUserId(Integer user_id) {
            this.user_id = user_id;
        }
        /**
         * 获取:用户ID
         */
        public Integer getUserId() {
            return user_id;
        }
        /**
         * 设置:用户名
         */
        public void setUsername(String username) {
            this.username = username;
        }
        /**
         * 获取:用户名
         */
        public String getUsername() {
            return username;
        }
        /**
         * 设置:性别
         */
        public void setSex(String sex) {
            this.sex = sex;
        }
        /**
         * 获取:性别
         */
        public String getSex() {
            return sex;
        }
        /**
         * 设置:电话
         */
        public void setPhone(String phone) {
            this.phone = phone;
        }
        /**
         * 获取:电话
         */
        public String getPhone() {
            return phone;
        }
        /**
         * 设置:密码
         */
        public void setPassword(String password) {
            this.password = password;
        }
        /**
         * 获取:密码
         */
        public String getPassword() {
            return password;
        }
        /**
         * 设置:等级
         */
        public void setLevel(Integer level) {
            this.level = level;
        }
        /**
         * 获取:等级
         */
        public Integer getLevel() {
            return level;
        }
        /**
         * 设置:用户创建时间
         */
        public void setCreateTime(String createTime) {
            this.createTime = createTime;
        }
        /**
         * 获取:用户创建时间
         */
        public String getCreateTime() {
            return createTime;
        }
        /**
         * 设置:邮箱
         */
        public void setEmail(String email) {
            this.email = email;
        }
        /**
         * 获取:邮箱
         */
        public String getEmail() {
            return email;
        }
        /**
         * 设置:登录标识
         */
        public void setLogo(Integer logo) {
            this.logo = logo;
        }
        /**
         * 获取:登录标识
         */
        public Integer getLogo() {
            return logo;
        }
    }

    上述的注解什么意思,为什么用,我在第一篇MP实战中提过也加以描述说过。不过,今天我还是要强调一下,@TableName该注解用英文翻译就是"表名"的意思,通常在这里面写实体对应的表名,方便映射。大家还记得hibernate吗?hibernate中有个配置文件叫:hibernater-cfg.xml,该配置文件主要配置hibernate的数据源和实体映射扫描等等,这个实体映射扫描,就是通过注解,之前是每个实体对应的xml文件,而在这个xml文件中配置实体对应表的属性。后来hibernate进行升级了,如果是每一个实体对应一个xml文件,随着项目越来越大,xml文件管理起来也是个问题,于是注解,应需而生。

    大家可以参考我的关于spring+hibernate+springmvc框架搭建的例子,看其中有一个实体就是通过注解的形式映射。这个与mybatis plus实体注解也是一个意思,并无多大差异。下面贴个代码方便讲解:

    package com.ssh.entity;
    
    import lombok.Data;
    
    import javax.persistence.*;
    
    /**
     * Created by XRog
     * On 2/2/2017.2:03 PM
     */
    @Data
    @Entity
    @Table(name = "Person")
    public class Person {
    
        @Id
        @GeneratedValue
        private Long id;
    
        @Column(name = "created")
        private Long created = System.currentTimeMillis();
    
        @Column(name = "username")
        private String username;
    
        @Column(name = "address")
        private String address;
    
        @Column(name = "phone")
        private String phone;
    
        @Column(name = "remark")
        private String remark;
    
        public Long getId() {
            return id;
        }
    
        public void setId(Long id) {
            this.id = id;
        }
    
        public Long getCreated() {
            return created;
        }
    
        public void setCreated(Long created) {
            this.created = created;
        }
    
        public String getUsername() {
            return username;
        }
    
        public void setUsername(String username) {
            this.username = username;
        }
    
        public String getAddress() {
            return address;
        }
    
        public void setAddress(String address) {
            this.address = address;
        }
    
        public String getPhone() {
            return phone;
        }
    
        public void setPhone(String phone) {
            this.phone = phone;
        }
    
        public String getRemark() {
            return remark;
        }
    
        public void setRemark(String remark) {
            this.remark = remark;
        }
        
        
    }

    这是hibernate的实体注解, @Data : 注解在类上, 为类提供读写属性, 此外还提供了 equals()、hashCode()、toString() 方法

                                                 @Entity 对实体注释。任何Hibernate映射对象都要有这个注释

                  @Table 的意思与mybatis plus中的@TableName意思是一样的

                                                 @Id和@GeneratedValue是对主键的标识,这里与mybatis plus中的@TableId意思也是一样的

                                                 @Column 意思就如其名,标识列的,在属性上打上该注解,使其与数据表中的字段名进行映射,而mybatis plus这里的@TableField虽有映射的意思,但是还有其他的意思,

                                         比如mybatis中,为什么要用resultType?为什么要用resultMap?原因很简单,一句话即可解释,当实体属性与表的字段名一致时,自动映射,当不一致时,需手动映射。

                                               @TableFiled在此就有这个作用

    @TableName的源码如下:

    /**
     * Copyright (c) 2011-2014, hubin (jobob@qq.com).
     * <p>
     * Licensed under the Apache License, Version 2.0 (the "License"); you may not
     * use this file except in compliance with the License. You may obtain a copy of
     * the License at
     * <p>
     * http://www.apache.org/licenses/LICENSE-2.0
     * <p>
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
     * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
     * License for the specific language governing permissions and limitations under
     * the License.
     */
    package com.baomidou.mybatisplus.annotations;
    
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    
    /**
     * <p>
     * 数据库表相关
     * </p>
     *
     * @author hubin
     * @since 2016-01-23
     */
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.TYPE)
    public @interface TableName {
    
        /**
         * <p>
         * 实体对应的表名
         * </p>
         */
        String value() default "";
    
        /**
         * <p>
         * 实体映射结果集
         * </p>
         */
        String resultMap() default "";
    
    }

    这里对@Retention和@Target做简单的说明:

    元数据

    也叫元注解,是放在被定义的一个注解类的前面 ,是对注解一种限制。

    谈下这两个: @Retention 和 @Target  

    @Retention :用来说明该注解类的生命周期。它有以下三个参数:

    RetentionPolicy.SOURCE  : 注解只保留在源文件中

    RetentionPolicy.CLASS  : 注解保留在class文件中,在加载到JVM虚拟机时丢弃

    RetentionPolicy.RUNTIME  : 注解保留在程序运行期间,此时可以通过反射获得定义在某个类上的所有注解。

    @Target :  用来说明该注解可以被声明在那些元素之前。

    ElementType.TYPE:说明该注解只能被声明在一个类前。

    ElementType.FIELD:说明该注解只能被声明在一个类的字段前。

    ElementType.METHOD:说明该注解只能被声明在一个类的方法前。

    ElementType.PARAMETER:说明该注解只能被声明在一个方法参数前。

    ElementType.CONSTRUCTOR:说明该注解只能声明在一个类的构造方法前。

    ElementType.LOCAL_VARIABLE:说明该注解只能声明在一个局部变量前。

    ElementType.ANNOTATION_TYPE:说明该注解只能声明在一个注解类型前。

    ElementType.PACKAGE:说明该注解只能声明在一个包名前。

    @TableId源码:

    /**
     * Copyright (c) 2011-2014, hubin (jobob@qq.com).
     * <p>
     * Licensed under the Apache License, Version 2.0 (the "License"); you may not
     * use this file except in compliance with the License. You may obtain a copy of
     * the License at
     * <p>
     * http://www.apache.org/licenses/LICENSE-2.0
     * <p>
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
     * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
     * License for the specific language governing permissions and limitations under
     * the License.
     */
    package com.baomidou.mybatisplus.annotations;
    
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    
    import com.baomidou.mybatisplus.enums.IdType;
    
    /**
     * <p>
     * 表主键标识
     * </p>
     *
     * @author hubin
     * @since 2016-01-23
     */
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.FIELD)
    public @interface TableId {
    
        /**
         * <p>
         * 字段值(驼峰命名方式,该值可无)
         * </p>
         */
        String value() default "";
    
        /**
         * <p>
         * 主键ID
         * </p>
         * {@link IdType}
         */
        IdType type() default IdType.NONE;
    
    }

    @TableId中有这么几个属性,其中用的比较多的就是属Type

    Type常用的枚举有:

    AUTO 主键自增

    ID_WORKER

    INPUT 主键以输入的方式

    NONE 默认一般是自增

    UUID UUID方式

    我个人用的比较多,一个是AUTO,另外一个是UUID,这两个能满足大多数的项目需求

    @TableFied源码:

    /**
     * Copyright (c) 2011-2014, hubin (jobob@qq.com).
     * <p>
     * Licensed under the Apache License, Version 2.0 (the "License"); you may not
     * use this file except in compliance with the License. You may obtain a copy of
     * the License at
     * <p>
     * http://www.apache.org/licenses/LICENSE-2.0
     * <p>
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
     * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
     * License for the specific language governing permissions and limitations under
     * the License.
     */
    package com.baomidou.mybatisplus.annotations;
    
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    
    import com.baomidou.mybatisplus.enums.FieldFill;
    import com.baomidou.mybatisplus.enums.FieldStrategy;
    
    /**
     * <p>
     * 表字段标识
     * </p>
     *
     * @author hubin sjy tantan
     * @since 2016-09-09
     */
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.FIELD)
    public @interface TableField {
    
        /**
         * <p>
         * 字段值(驼峰命名方式,该值可无)
         * </p>
         */
        String value() default "";
    
        /**
         * <p>
         * 当该Field为类对象时, 可使用#{对象.属性}来映射到数据表.
         * </p>
         * <p>
         * 支持:@TableField(el = "role, jdbcType=BIGINT)<br>
         * 支持:@TableField(el = "role, typeHandler=com.baomidou.xx.typehandler.PhoneTypeHandler")
         * </p>
         */
        String el() default "";
    
        /**
         * <p>
         * 是否为数据库表字段
         * </p>
         * <p>
         * 默认 true 存在,false 不存在
         * </p>
         */
        boolean exist() default true;
    
        /**
         * <p>
         * 字段验证策略
         * </p>
         * <p>
         * 默认 非 null 判断
         * </p>
         */
        FieldStrategy strategy() default FieldStrategy.NOT_NULL;
    
        /**
         * <p>
         * 字段自动填充策略
         * </p>
         */
        FieldFill fill() default FieldFill.DEFAULT;
    }

    @TableField是比较常用的注解,有的时候觉得ajax要传实体(这个实体包含其它实体类属性),通常规范的做法是写个dto,直接传输,一来复用方便,二来简洁清楚,我们开发中通常不推荐一个实体中嵌入其他实体的属性,但是有的时候,人有点懒,需求有点变态,为了加快速度,就直接在一个实体中,写其他实体属性。

    这就好比,在一个html页面中,建议写外部js和css,一来规范,二来方便管理,三来复用,不过规范通常是让人痛苦的,不过对于时常变更的项目需求而言是快乐的,因为代码规范不乱,但是对于小公司而言,有的时候为了加快项目进度,不管三七二十一,行内样子能解决,绝对不用外部,最后一个页面内置一大堆css,js,而且html标签中又嵌入一大堆css标签或者js函数等,等到要优化时,有种想骂人的冲动。

    题外话就不多说了,总而言之,规范开发虽然是痛苦,但是对于未来是很有益的,坚持规范,做一个代码洁癖的人!目前我还是不符合。至少我还是与前者所说的,占了一半。深刻的体会到,代码不规范,乱七八糟带来的影响。@TableField中的exist属性就是为了当你的实体包含其它实体时,可以指定它,默认为true,需要指定为false,true的意思是该字段在数据表中存在,false是不存在,通常的话,如果你的自动生成查,查所有,而不使用setSqlSelect()方法指定具体的字段时,如果你的实体中包含其它属性,但又没有使用exist时,会出现找不到列异常。避免该异常的方法就是指定exist为false,不过开发过程中,不管怎么样建议使用setSqlSelect()方法,因为sql优化。调用该方法指明需要字段就是进行最简单的sql优化。一个个简单的sql优化,对于一个系统还是很有威力的。

    当然使用@TableField的场景是当你的实体属性与数据表不一致时,进行手动映射,如果一致,就会自动映射。

  • 相关阅读:
    学用 ASP.Net 之 "字符串" (5): StringBuilder 类
    学用 ASP.Net 之 System.DateTime 结构
    学用 ASP.Net 之 "字符串" (4): string 类的扩展方法
    学用 ASP.Net 之 System.Char 结构
    学用 ASP.Net 之 System.TimeSpan 结构
    学用 ASP.Net 之 "字符串" (6): StringInfo 类
    学用 ASP.Net 之 System.Math 类
    学用 ASP.Net 之 System.Random 类
    学用 ASP.Net 之 System.Collections.Hashtable 类与 DictionaryEntry 结构
    [收藏]如何开始创业
  • 原文地址:https://www.cnblogs.com/youcong/p/9021739.html
Copyright © 2011-2022 走看看