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 ([email protected]).
 * <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 ([email protected]).
 * <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 ([email protected]).
 * <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的场景是当你的实体属性与数据表不一致时,进行手动映射,如果一致,就会自动映射。

原文地址:https://www.cnblogs.com/youcong/p/9021739.html

时间: 2024-11-09 07:18:56

MP实战系列(三)之实体类讲解的相关文章

MP实战系列(五)之封装方法讲解

mybatis plus封装的方法怎么用?以及它们对应的sql是那些sql?及其什么情况用? 这些需要说下,以下我将会将我常用的说下,不是常用的,可能提以下或者不提. 根据主键查询 UserEntity userEntity = ud.selectById(id); 上述这个没什么好说的 根据实体查询 UserEntity u = new UserEntity(); u.setEmail("[email protected]"); UserEntity u1 = ud.selectOn

MP实战系列(七)之集成springboot

springboot是现在比较流行的微服使用的框架,springboot本质上就是将spring+springmvc+mybatis零配置化,基本上springboot的默认配置符合我们的开发.当然有一部分还是需要自定义的. 本章不是专门讲springboot的,主要将springboot+mybatis plus是如何整合的. 一.导入pom依赖 <parent> <groupId>org.springframework.boot</groupId> <arti

MP实战系列(九)之集成Shiro

下面示例是在之前的基础上进行的,大家如果有什么不明白的可以参考MP实战系列的前八章 当然,同时也可以参考MyBatis Plus官方教程 建议如果参考如下教程,使用的技术为spring+mybatis plus + springmvc+jdk8+maven工程 满足这个条件可以减少不必要的麻烦,当然持久层也可以用mybatis. 只要按照如下示例来,也不会有大问题的.之前我也强调过mybatis和mybatis plus的区别主要是封装和继承,mybatis plus封装一系列增删改查的方法,但

MP实战系列(十二)之封装方法详解(续二)

继续MP实战系列(十一)之封装方法详解(续一)这篇文章之后. 此次要讲的是关于查询. 查询是用的比较多的,查询很重要,好的查询,加上索引如鱼得水,不好的查询加再多索引也是无济于事. 1.selectById()方法 演示示例: UserEntity user = ud.selectById(33); System.out.println(user.getEmail()); 简单的说明: 如果是在MyBatis中,需要再对应的xml编写这样的sql select column1,column2..

MP实战系列(二)之集成swagger

其实与spring+springmvc+mybatis集成swagger没什么区别,只是之前写的太不好了,所以这次决定详细写. 提到swagger不得不提rest,rest是一种架构风格,里面有对不同的资源有不同的请求标识.例如PUT,POST,GET,DELETE,OPTIONS,HEAD,PATCH等. 对于技术的初学,最好的话还是建议去官网,官网最详细也最权威,虽然不少博客对此有挺好的解说,但还是强烈建议去官网,不要求仔仔细细阅读,至少读个大概. 对于目前,有人要问我swagger能做什么

智能机器人“小昆”的实现(三)实体类的实现

在上一篇文章中,我们实现了获取服务器返回数据的工具类.没有读过的朋友可以点击下面链接: http://www.cnblogs.com/fuly550871915/p/4852568.html 这一篇文章要在上一篇的基础上,实现两个重要的实体类,一个是ChatMsg,用来封装数据从而实现标准的消息格式:一个是ResultMsg,用来封装从服务器端返回的数据. 一.准备工作 在这里,解析json字符串,我们打算使用第三方包GSON.首先点击下面的地址,下载该包. http://code.google

MP实战系列(四)之DAO讲解

说到DAO不得不提一个开发名词"三层架构",所谓的三层架构是什么呢?简单的可以概括为数据访问层,业务逻辑层,界面层(又称表现层). 这也是我们Java开发常用的手段,经常有人将三层架构和mvc模式混淆,在我看来,三层架构就是三层架构,mvc只是三层架构中的表现层中的架构,相当于在一个比较大的层面,往里面在细分,mvc细分,可分为模型,视图,控制器,在这里模型通常指数据,也可以叫JavaBean,而视图的话,这个视图就是展示给用户看的,通常用于视图的模板可以为jsp,freemarker

MP实战系列(十三)之批量修改操作(前后台异步交互)

MyBatis的批量操作其实同MyBatis基本是一样的.并无多大区别,要说区别,除了封装的方法之外,主要就是注解方面的区别,比如@TableId.@TableField.@TableName等等区别. 示例描述: 本次描述的是批量相关的操作,主要是批量修改等操作. 项目讲解:如何批量修改开锁方式? 准备环境和IDE工具:MySQL5.7+Maven3以上+JDK8或者JDK7+SSM框架+tomcat8或者tomcat7应用服务器+Eclipse. 本文核心:主要是Controller代码和数

{Java初级系列三}----面向对象和类

一:面向对象----Object 本人为自学Java系列,内容来自于中国大学mooc华东师范大学陈育良教授<Java核心技术>,在此感谢老师! 在Java中引入了对象和类的概念 对象是一个变量--------具体的东西: 类就是类型(是规范,是定义),从万千对象中抽取共性: 类规定了对象应该有的属性内容和方法: 对象就是类的具体实现,是活生生的: 例如:土豆丝菜谱是类,一盘土豆丝就是对象 从程序员的发展角度来理解,OO-Oriented Object是对OP—Oriented Procedur