MybatisPlus 实体类与数据库表映射关系&MybatisPlus:ORM思想
Posted Archie_java
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MybatisPlus 实体类与数据库表映射关系&MybatisPlus:ORM思想相关的知识,希望对你有一定的参考价值。
实体类与数据库表映射关系
使用mybatisPlus时,会确定实体类和数据的映射关系
具体的映射方法有两种
1、默认:采用驼峰映射规则
例如MyUserTable 对应的数据库表为 my_user_table ; TEMyUserTable 对应表名为t_e_my_user_table;
2、注解@TableName
在类名上方添加@TableName(“my_user_table”)
忽略某个实体类属性和数据库表字段之间的映射关系
问题描述
在开发中可能会遇到MyBatis-Plus使用实体类属性进行SQL操作,但是不用存到数据库中去查找,这时候我们的实体中有这个属性,但是数据库的表中没有这个字段(即:实体类属性非数据库表字段),如果不做处理就会报错。
API
@TableName
:数据库表相关@TableId
:表主键标识@TableField
:表字段标识@TableLogic
:表字段逻辑处理注解(逻辑删除)
解决方案
忽略映射字段时可以在实体类属性上使用以下注解:
@TableField(exist = false)
:表示该属性不为数据库表字段,但又是必须使用的。@TableField(exist = true)
:表示该属性为数据库表字段。
在实体类的属性上面加上这个注解后,此字段就不会映射数据库了。
@TableField(exist = false)
private Position position;
MybatisPlus: ORM思想
MybatisPlus介绍:
MyBatis-Plus(简称 MP)是一个 MyBatis 的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。
特性:
无侵入:只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑
损耗小:启动即会自动注入基本 CURD,性能基本无损耗,直接面向对象操作
强大的 CRUD 操作:内置通用 Mapper、通用 Service,仅仅通过少量配置即可实现单表大部分 CRUD 操作,更有强大的条件构造器,满足各类使用需求
支持 Lambda 形式调用:通过 Lambda 表达式,方便的编写各类查询条件,无需再担心字段写错
支持主键自动生成:支持多达 4 种主键策略(内含分布式唯一 ID 生成器 - Sequence),可自由配置,完美解决主键问题
支持 ActiveRecord 模式:支持 ActiveRecord 形式调用,实体类只需继承 Model 类即可进行强大的 CRUD 操作
支持自定义全局通用操作:支持全局通用方法注入( Write once, use anywhere )
内置代码生成器:采用代码或者 Maven 插件可快速生成 Mapper 、 Model 、 Service 、 Controller 层代码,支持模板引擎,更有超多自定义配置等您来使用
内置分页插件:基于 MyBatis 物理分页,开发者无需关心具体操作,配置好插件之后,写分页等同于普通 List 查询
分页插件支持多种数据库:支持 mysql、MariaDB、Oracle、DB2、H2、HSQL、SQLite、Postgre、SQLServer 等多种数据库
内置性能分析插件:可输出 Sql 语句以及其执行时间,建议开发测试时启用该功能,能快速揪出慢查询
内置全局拦截插件:提供全表 delete 、 update 操作智能分析阻断,也可自定义拦截规则,预防误操作
ORM介绍:
对象关系映射(英语:Object Relational Mapping,简称ORM,或O/RM,或O/R mapping),是一种程序设计技术,用于实现面向对象编程语言里不同类型系统的数据之间的转换。从效果上说,它其实是创建了一个可在编程语言里使用的“虚拟对象数据库”。如今已有很多免费和付费的ORM产品,而有些程序员更倾向于创建自己的ORM工具。
技术场景:
我们在进行业务时的增删改查操作的Sql语句是面向过程的语言。
例如当我们对user表执行sql语句: select * from user
- 我们用jdbc中的ResultSet(结果集对象)来封装我们查询到的结果 以便于在其他开发系统(比如java)进行使用:封装的ResultSet结果集传送至java开发环境中,java实现将其结果取出再封装至User对象中。
- 简化来说,即mybatis中的实现场景:写sql查询语句------->得到我们想要的User对象
从上图中不难理解,结果集与对象之间需要通过我们手动(或者框架的帮助)来进行两者之间的封装,开发的效率低下。
而ORM方式:
以对象的方法操作数据库,可以实现结果集与对象的自动映射。
ORM核心知识:(即MybatisPlus工作原理)
1.对象与哪张表要完成映射?
自定义注解进行标识
2.对象的属性与表中的字段如何一一对应?
在对对象属性和表字段命名时将其命名为相同的名字。(或利用特定的注解指定)
3.工具方法如何简化?
MybatisPlus动态生成CURD(增删改查)操作的接口,只要其他的mapper接口继承
4.对象如何转化为SQL语句?
利用对象中的属性及属性的值进行动态拼接。
操作案例:
1.首先引入MybatisPlus依赖,下载jar包
(如果maven项目中已经引入了Mybatis依赖,需将其删除,因为MybatisPlus默认配置了Mybatis,不将原有依赖删除可能会发生依赖冲突)
<!--spring整合mybatis-plus -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.2.0</version>
</dependency>
2.在POJO(User)中加入标识对象与表的映射关系的注解@TableName
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
@Data
@Accessors(chain = true)
@NoArgsConstructor
@AllArgsConstructor
@TableName("user")//标识对象与表的映射关系,如果表名与对象名称一致,user参数可不写
public class User
private Integer id;
private String name;
private Integer age;
private String sex;
3.对象的属性与表中的字段一一对应
使用@TableId,@TableField
package com.qiu.pojo;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
@Data //动态生成get/set/toString/equals等方法
@Accessors(chain = true) //开启链式加载结构 重构了set方法可以连续.
@NoArgsConstructor //无参构造 必须添加
@AllArgsConstructor //全参构造
@TableName("user")//标识对象与表的映射关系
public class User
@TableId(type= IdType.AUTO)//主键映射
private Integer id; //主键自增
@TableField(value="name")//其他字段映射,当字段和属性名一致时,此注解可省略
private String name;
private Integer age;
private String sex;
4.工具方法简化->
MybatisPlus动态生成CURD(增删改查)操作的接口,使用其他的mapper接口继承:
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.qiu.pojo.User;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
@Mapper
public interface UserMapper extends BaseMapper<User> //记住一定指定泛型
public List<User> findAll();
附加)修改下springboot项目中的配置文件,将原先的mybatis的配置改成mybaits-plus
server:
port: 8090
servlet:
context-path: /
spring:
datasource:
#驱动版本问题 高版本需要添加cj关键字 一般可以省略
#driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/jtdb?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf8&autoReconnect=true&allowMultiQueries=true
username: root
password: root
mybatis-plus:
#别名包定义 Mapper的resultType中只需要写类名 之后自动拼接即可
type-aliases-package: com.qiu.pojo
#加载指定的xml映射文件
mapper-locations: classpath:/mybatis/mappers/*.xml
#开启驼峰映射
configuration:
map-underscore-to-camel-case: true
5.利用对象中的属性及属性的值进行动态拼接。进而查询
@RestController
public class UserController
@Autowired
UserMapper userMapper;
@RequestMapping("/findAll")
public List<User> findAll()
return userMapper.selectList(null);//为null表示查询全部
运行项目
mybatisplus启动成功:
Hibernate面试题
1.讲下什么是Hibernate?
中文翻译过来是冬眠的意思,hibernate是一个开源的对象关系映射框架,它对JDBC进行了封装,实现了java实体类与数据库的表建立了映射关系。达到数据持久化的目的。
2.讲下什么是ORM?ORM组件有哪些?
orm是对象关系映射,是一种程序技术,通过将java对象映射到数据库表,通过操作java对象,就可以完成对数据表的操作。常用的orm组件有JDBC、Hibernate、mybatis、springDate等
3.Hibernate和JDBC相比的优点是什么?缺点是什么?
优点:简化了Dao层访问数据库的重复性代码
hibernate是一个全自动的orm框架,它可以自动生成sql语句,自动执行。
hibernate的映射灵活,(数据库方言)支持很多关系型数据库,从一对一到多对多的各种复杂关系
hibernate提供了缓存机制(session缓存,二级缓存,查询缓存),提高了性能。
缺点:hibernate是个重量级框架,对jdbc的封装过于厉害,失去了对sql的控制,无法对sql进行优化。在面对批量操作的时候,hibernate的性能就远远低于jdbc。
4.如何搭建一个Hibernate的环境
1.先导入jar包与配置文件、hibernate启动session的工具类。
2.在配置文件中配置数据库的基本信息与数据库方言
3.进行测试,先创建实体类和数据库中的表。创建映射文件,
命名规则是 实体类名.hbm.xml。位置要与实体类同一包下。
在映射文件中配置 实体类与数据库表之间的映射关系。
在hibernate.cfg.xml配置文件中添加映射文件的路径。
4.通过hibernate的工具类创建sessionfactory,通过工厂创建session对象,通过session开启事务,进行数据操作后,事务提交。
5.说说hibernate的三种状态之间如何转换?
hibernate的三种状态是瞬时状态、持久状态、托管状态
瞬时状态:session缓存中没有对象,数据库中也没有对应记录
持久状态:session缓存中有对象,数据库中有对应记录
托管状态:session缓存中没有对象,数据库中有对应记录
比如有一个User实体类和一张User表。当new了一个user对象,但没有开启事务。此时user就处于瞬时状态,与数据库的数据没有任何联系,当开启事务后,执行了session.save()方法后,session缓存中存放了该user对象,而数据库中也有相应的这条数据,此时就转换为持久状态。当事务提交后,session被销毁。session缓存中就没有user对象,而数据库表中有相应记录,此时为托管状态。
6.Hibernate中session有几种创建方式?都有那些区别?
有两种创建方式:
第一种是:通过sessionfactory.getcurrentSession()创建session,它是从当前线程中去找,看有没有session,如果有则返回session,如果没有则创建session。属于单例模式
第二种是:通过sessionfactory.opensession()创建session,每次都是新创建一个session。
7.Hibernate中有哪些缓存?都是如何配置的?(三个缓存都要说)
hibernate中有一级缓存(session缓存),二级缓存(sessionfactory缓存)、查询缓存(三级缓存)
1级缓存:创建session,每次获取数据,hibernate会优先从session中找,如果没有,再去查询。查询后放到缓存中,当session关闭,一级缓存销毁。session缓存中的数据不能被别的session共享
2级缓存:sessionfactory级别缓存,sessionfactory中的session共享一个二级缓存。
sessionfactory缓存分为两部分:内置缓存和外置缓存,内置缓存是hibernate自己使用,外界只能读取。而外置缓存是提供个用户使用,hibernate只提供了外置缓存的接口,需要第三方提供商实现。常用的有ehcache等。
二级缓存的使用:1.先导入ehcache的jar包和ehcache的配置文件(二级缓存的默认属性)
2.在hibernate.cfg.xml中开启二级缓存(默认是关闭)
3.确定二级缓存提供商
4.配置缓存对象(有两种模式,一种只读,一种读写)
3级缓存(查询缓存):由于session.creatquery()在二级缓存中不起作用,便提供了三级缓存
三级缓存的配置:1.开启二级缓存,确定提供商,确定缓存对象
2.查询后,调用setcacheable(true)放到缓存中
3.读取时,调用setcacheable(true)去缓存中取
8.说说get&load的区别
get:调用后立即发送sql去查询,如果查询一个不存在的值返回null。
load:懒加载机制,调用后返回一个代理对象,只有id有值。当使用到非id以外的属性时才会发sql语句去查询。如果查询一个不存在的值会抛出异常
9.如何在控制台看到hibernate生成并执行的sql?
在hibernate.cfg.xml中配置show_sql属性为true
10.Hibernate中有几种检索方式?
hibernate有两种检索方式:
1.立即检索:立即查询,在执行查询语句时,立即查询所有的数据。get
2.延迟检索:延迟查询,在执行查询语句之后,在需要时再查询。
11.说说save(),flush(),commit()方法调用后都做了什么?
save():编写好sql语句并存到缓存区中
flush():把缓存区中的sql刷到数据库中,更新数据。
commit():提交事务,并隐式调用flush(),更新数据
12.Hibernate中怎样实现类之间的关系?(如:一对多、多对多的关系)
1对多:
1.实体类中:1的一方用set集合保存多的一方 ,多的一方用对象来保存1的一方
2.在1的一方的映射文件中配置set标签,set标签中name属性=“存放多的一方的属性”,key标签中的column属性为外键字段。onetomany标签的class属性为多的一方的全类名。
3.在多的一方的映射文件中配置manytoone标签,标签中的name属性为保存一的一方的属性名。配置column标签 标签中的属性name为外键
多对多:
1.在实体类中都用set集合保存对方
2.在映射文件中配置set标签 标签中name为存放另一方的属性名,标签中table属性为中间表名
配置key标签 key标签中column属性为当前表的属性
再配置manytomany标签。标签中column属性为另一方的外键 class属性为另一方的实体类全类名
13.Hibernate是如何延迟加载?
通过lazy属性来控制懒加载机制,在映射文件中set标签中配置lazy属性,一般默认为true
lazy属性中有三个值,true为懒加载 false为不加载。extra为及其懒惰(当用户只需要订单数时发送聚合函数去查询)
14.谈谈Hibernate中inverse的作用?
inverse常用于一对多,多对多的映射文件中的set标签,inverse属性设置为true,是讲维护外键权反转到另一方,在一对多中,默认为1的一方,在多对多中,双方都维护,不设置权限反转会抛异常
15.MySQL默认的事务隔离级别是多少?jdbc如何修改?Hibernate如何修改?
mysql默认的事务隔离级别为4,在jdbc中通过connection这个类中的一个常量值来设置。
hibernate中通过在配置文件hibernate.cfg.xml中配置事务隔离级别,一般默认为4
16.事务的特性有哪些?
事务特性有原子性、隔离性、持久性、一致性
17.什么是脏读,不可重复读,幻读
脏读:就是读到另一个事务没有提交的数据
不可重复读:一个事务多次读取数据期间另一个事务进行修改,多次读取到的数据不同。
18.说说连接池的原理
连接池:连接池就是提前创建好connection放在一个池中,状态都为空闲状态,当外界需要用到connection时,分配connection给予使用,该connection状态为使用状态。连接池有自己的管理机制,但从conncetion不够时,它会闯创建,但多于规定数时,进行销毁。工作完成的connetion会被回收,状态变更为空闲状态
19.说说HQL和QBC,项目中都是怎么用的?
HQL与qbc都是面向对象的查询语句,qbc相对于hql更加面向对象,在qbc中把查询语句都封装成了方法。
qbc:通过调用不同的方法来实现对对象的操作,从而对数据进行操作
hql:可以手动编写sql语句来进行查询。
20.说说悲观锁和乐观锁?
悲观锁:默认在使用数据时一定发生别人修改我使用的数据,所以对使用数据进行上锁,数据库提供实现(通过for update来上锁)
乐观锁:默认在使用数据时没有发生别人修改我使用的数据。通过版本号来实现。在实体类中加入version属性,表中添加version字段,每次事务提交之前都核对版本号,如果版本号不匹配,这事务提交失败,重新获取数据,每次事务提交后,版本号自增
21.说说Struts2的来历
Struts2是由Struts1的名气加webwork的实干组成的,由于前期的struts1不满足需求,webwork知名度低,两者结合,形成了Struts2
22.说说struts2的工作流程
struts2工作流程:浏览器发送请求,请求通过一系列的过滤器到到达struts2核心控件filterdispatcher,filterdispatcher调用actionmapper来确定请求是否需要调用某个action,如果需要,filterdispatcher就把请求交给action代理对象,action的代理对象通过configuration Manager查询struts配置文件,找到需要调用的action类,action代理对象会创建一个actioninvcation实例来调用action,在调用action过程中会通过struts自带的18个拦截器,在action调用完后,会产生一个结果,如果这个结果是一个jsp的话,就会调用视图模板来产生一个jsp.然后在响应给浏览器。
23.如何搭建一个Struts2的项目
搭建struts2项目流程:1.先导入struts2的jar包和配置文件
2.在web。xml中添加struts2的核心控件
3.创建一个helloaction,在struts的配置文件中配置helloaction。
4.访问action进行测试
24.什么是值栈?项目中怎么用的?
值栈:就是一个存放数据的内存区域,可以看做request来使用。在struts2中指的就是valuestack,valuestack是actioncontext的一个对象,是栈结构。存放action对象。
在项目中,在action中声明与参数同名的熟悉,并提供get/set方法。当struts调用action的时候就会为action相应的属性赋值。而这个action对象就会存放到
值栈中,我们只需调用即可。
25.说说Struts2有几种校验方式
struts2有3中校验方式
第一种:action继承actionsupport,重写父类的validate方法(该方法对action中所有方法都进行校验)
第二种:重写validate方法名()方法 ,该方法只会校验validate后面跟着的方法名的方法(注意方法名首字母要大写)
第三种:框架校验,编写配置文件,命名规则是action类名-validation.xml,位置与要校验的action放在同一包下。
26.Struts2的拦截器怎么定义的?项目中怎么用的?
struts2的拦截器类似与过滤器,但只对action起作用。
在项目中,先创建一个拦截器类继承abstractintercepted类,重写intercept应特set()方法。
在struts。xml配置文件中,定义一个拦截器,用interceptor标签,标签中的name属性为拦截器名,class属性为拦截器类的全类名。在定义一个拦截器栈,通过interceptor-stack标签,在该标签中引入自定义的拦截器和默认的拦截器栈defalutestack。最后引用自定义的拦截器栈。
27.说下token的底层实现原理?
struts中的token是用来解决表单重复提交的问题,底层原理是,在浏览器请求访问一个带有token属性的页面的时候,服务器会生成一个随机数,这个随机数会保存一份在session中,也会发送一份到页面中,当用户提交表单的时候,服务器会去session中查找是否有与之相等的随机,如果有,则放行。服务器清除该随机数。当表单重复提交时,服务器在session中找不到与之匹配的随机数,则进行拦截。
28.说说OGNL表达式?struts2中怎么用的?
ognl:即对象导航图语言,可以用来代替页面中的java脚本,简化对数据的访问操作。ognl表达式:与el表达式类似
struts2中:ognl配合这struts表签来使用,存在值栈中的数据可以直接取,而存在非值栈中的数据就要
用#来获取,用%{}包裹的ognl表达式浏览器会以ognl表达式来解析。
29.action中如何访问ServletAPI有几种方式?
有三种方式:
第一种:通过actioncontent访问
第二种:通过servletactioncontent来访问
第三种:通过实现servlet*Aware接口来访问
30.说说Struts2和Hibernate整合流程
struts2与hibernate整合流程:
1.先搭建strut2环境:
1.导入struts2jar包和配置文件
2.在web.xml中配置struts2核心控件
3.编写一个hello action,并在struts2的配置文件中配置该action
4.测试环境是否搭建成功
2.搭建hibernate环境
1.导入hibernatejar包和配置文件
2.导入hibernate工具类
3.创建实体类和数据库建表
4.编写映射文件,命名规则:实体类名.hbm.xml,位置:与实体类在同一包下。在映射文件中配置实体类与数据库表的映射关系
5.编写测试类进行环境测试
以上是关于MybatisPlus 实体类与数据库表映射关系&MybatisPlus:ORM思想的主要内容,如果未能解决你的问题,请参考以下文章
MybatisPlus的BaseMapper和Wrapper使用
MybatisPlus的BaseMapper和Wrapper使用