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的场景是当你的实体属性与数据表不一致时,进行手动映射,如果一致,就会自动映射。
MP实战系列(三)之实体类讲解的更多相关文章
- MP实战系列(五)之封装方法讲解
mybatis plus封装的方法怎么用?以及它们对应的sql是那些sql?及其什么情况用? 这些需要说下,以下我将会将我常用的说下,不是常用的,可能提以下或者不提. 根据主键查询 UserEntit ...
- MP实战系列(十四)之分页使用
MyBatis Plus的分页,有插件式的,也有其自带了,插件需要配置,说麻烦也不是特别麻烦,不过觉得现有的MyBatis Plus足以解决,就懒得配置插件了. MyBatis Plus的资料不算是太 ...
- MP实战系列(七)之集成springboot
springboot是现在比较流行的微服使用的框架,springboot本质上就是将spring+springmvc+mybatis零配置化,基本上springboot的默认配置符合我们的开发.当然有 ...
- MP实战系列(十二)之封装方法详解(续二)
继续MP实战系列(十一)之封装方法详解(续一)这篇文章之后. 此次要讲的是关于查询. 查询是用的比较多的,查询很重要,好的查询,加上索引如鱼得水,不好的查询加再多索引也是无济于事. 1.selectB ...
- MP实战系列(九)之集成Shiro
下面示例是在之前的基础上进行的,大家如果有什么不明白的可以参考MP实战系列的前八章 当然,同时也可以参考MyBatis Plus官方教程 建议如果参考如下教程,使用的技术为spring+mybatis ...
- MP实战系列(二)之集成swagger
其实与spring+springmvc+mybatis集成swagger没什么区别,只是之前写的太不好了,所以这次决定详细写. 提到swagger不得不提rest,rest是一种架构风格,里面有对不同 ...
- WCF开发实战系列三:自运行WCF服务
WCF开发实战系列三:自运行WCF服务 (原创:灰灰虫的家 http://hi.baidu.com/grayworm)上一篇文章中我们建立了一个WCF服务站点,为WCF服务库运行提供WEB支持,我们把 ...
- MP实战系列(一)之入门框架搭建和使用
mybatis plus官网:https://github.com/baomidou/mybatis-plus 上面有对应的实际例子,直接导入即可用. mybatis plus官方的怎么介绍,我就不在 ...
- MP实战系列(八)之SpringBoot+Swagger2
SpringBoot一个原则,爱好编程的朋友们都知道,那就是"习惯优于配置". 今天一上来主要说的还是代码,个人比较喜欢来的实战系列的,不过有的时候还是比较偏重于理论,理论是造轮子 ...
随机推荐
- RowVersion 用法
在数据表更新时,如何表征每个数据行更新时间的先后顺序?最简单的做法是使用RowVersion(行版本)字段,它和时间戳(TimeStamp)类型的功能相似,只不过TimeStamp 已过时,应避免用于 ...
- Linux环境变量详解与应用
在bash shell中,环境变量分为: >全局变量 >局部变量 全局变量,不仅对shell可见,对其子进程也可见 查看预设的全局环境变量: ghostwu@dev:~$ printenv ...
- Web设计中打开新页面或页面跳转的方法
一.asp.net c# 打开新页面或页面跳转 1. 最常用的页面跳转(原窗口被替代):Response.Redirect("newpage.aspx"); 2. 利用url地址打 ...
- Frobenius norm(Frobenius 范数)
Frobenius 范数,简称F-范数,是一种矩阵范数,记为||·||F. 矩阵A的Frobenius范数定义为矩阵A各项元素的绝对值平方的总和,即 可用于 利用低秩矩阵来近似单一数据矩阵. 用数学表 ...
- 洛谷P3987 我永远喜欢珂朵莉~(set 树状数组)
题意 题目链接 Sol 不会卡常,自愧不如.下面的代码只有66分.我实在懒得手写平衡树了.. 思路比较直观:拿个set维护每个数出现的位置,再写个线段树维护区间和 #include<bits/s ...
- 【代码笔记】Web-ionic-表单和输入框
一,效果图. 二,代码. <!DOCTYPE html> <html> <head> <meta charset="utf-8"> ...
- 【读书笔记】iOS-解析XML
使用最广泛的解析XML文档的方法有两种,一种基于SAX,另一种基于DOM.SAX解析器是事件驱动型的,在解析时增量地读取XML文档,当解析器识别出一个结点的时候会调用相应的委托方法. 参考资料< ...
- Linux 学习笔记之超详细基础linux命令 Part 6
Linux学习笔记之超详细基础linux命令 by:授客 QQ:1033553122 ---------------------------------接Part 5----------------- ...
- loadrunner 脚本开发-int型变量和字符串的相互转换
脚本开发-int型变量和字符串的相互转换 by:授客 QQ:1033553122 字符串转化为int型变量 Action2() { int j = 0; j = atoi("12345&qu ...
- JavaScript按纯数字排序
直接上代码: var arr=[ {name:"张散步",age:"23",sports:"篮球",number:"23112 ...