
@GeneratedValue 用于注解生成策略,内有strategy方法。默认情况下,spring会自动选择一个最适合底层数据库的主键生成策略:我这里 mysql 对应自增长auto increment
在javaxpersistenceGenerationType中有以下几种策略:
查询语句是 MyBatis 中最常用的元素之一,本文涉及mybatis的单表查询 *** 作,关联表有关的查询会后续补充。
巧妇难为无米之炊,要想从数据库中表中取出数据并转化为javaBean,所以,我们要先准备javabean以及与其对应的数据表。
javaBean:
public class President {
private int id;
private String name;
@Override
public String toString() {
return "President [id=" + id + ", name=" + name + "]";
}
//get set 方法
}
创建两个对应的数据库表,并插入两条数据:
create table president1(
p_id int not null auto_increment primary key,
p_name varchar(50) not null
);
insert into president1(p_name) values('lily'),('Tom');
create table president2(
id int not null auto_increment primary key,
name varchar(50) not null
);
insert into president2(name) values('lily'),('Tom');
创建两个数据库是为了测试两个不同的查询状况,
数据库字段名与实体类属性名相同
从sql表可以看出president2的字段名与javabean:President的属性名完全相同,这种情况下mybatis的select *** 作非常简单:
<!-- 从表 president2中查询-->
<select id="getPreByIdPresident2" parameterType="int" resultType="President">
select from president2 where id=#{id}
</select>
此时mybatis运用反射机制会将查询返回的结果(id,name)封装成President对象。
如果从表president1中查询,同样采用上面的sql语句
<!-- 从表 president1中查询-->
<select id="getPreByIdPresident1" parameterType="int" resultType="President">
<span style="white-space:pre"> </span>President p1 = sessionselectOne(statement+"getPreByIdPresident1", 1);
<span style="white-space:pre"> </span>Systemoutprintln("表president1中查询"+p1);
</select>
此时如果用getPreByIdPresident1进行查询,返回的结果会是null,我们将上面的sql语句在mysql中执行下:
有结果返回,但是返回的字段名为(p_id,p_name)这种结果mybatis在解析时无法与President类对应。多数情况下实体类属性名与数据库表的字段名都会有差异,这种情况如果mybatis不能处理也就太low了。
数据库字段名与实体类属性名不相同
mybatis针对该种情况有两种解决方法,但是归根到底都是同一种实现。
Method1:定义一个ResultMap将数据库字段名与实体类属性名做个映射
我们欲从表president1中查询数据,此时的mapper配置如下:
<resultMap type="President" id="getFromPresident2">
<!-- 主键必须用id标签映射,其他的用非集合用result映射 集合类用collection映射 -->
<!-- column为数据库字段名,property为实体类属性名 -->
<id column="p_id" property="id" />
<result column="p_name" property="name" />
</resultMap>
<select id="getPreByIdPresident1Method1" resultMap="getFromPresident2">
select from president1 where p_id=#{id}
</select>
首先定义了一个resultMap,将数据库表的字段名与实体类属性名做了一一对应,其中type为实体类(此处运用的类别名),id为了在select标签中引用映射结果。
在select标签中并没有用resultType属性,而使用了resultMap,即为上面定义的resultMap,mybatis会根据resultMap中的映射关系去构造President
Method1:直接在sql语句中使用别名
<!-- 从表 president1中查询 -->
<select id="getPreByIdPresident1Method2" resultType="President">
select p_id id,p_name name from president1 where p_id=#{id}
</select>
这种方法会查到实际的数据,这种方法与字段名和属性名相同都是基于相同的原理:MyBatis 会在幕后自动创建一个 ResultMap,基于属性名来映射列到JavaBean 的属性上。即mybatis底层都是通过创建ResultMap来进行关系的映射,与method1原理相同。。
比如我们在引入了jdbc的配置文件使用了properties标签,引入jdbc有什么好处?,可以在配置文件中统一管理
内容而不是在很多个文件改来改去,而且在核心配置文件中把数据库连接相关的写死,显然是硬编码的所以我们用配置文件代替 nice!!!
你可能注意到了上面的写法 用前缀jdbc 可以很好地将他们与其他的变量区分开,(可以从名字很容易看出是jdbc相关的数据,不至于和同名变量搞混因为username这种可能
不止会出现在数据库的连接)
上面的代码中引入配置文件的部分为
可以从上面看到写法:
下面这段就是用来设置类的别名:
那么问题来了,为什么要有类的别名这种 *** 作??
因为在映射文件中每次都要写全类名显然有点麻烦比如下面这样:
一个项目是会有很多个映射文件的为了方便,所以类别名就出现了。可以在核心配置文件写接口类和对应的别名
这样就可以在映射文件的命名空间里可以直接写User(对大小没有要求也可以是user; 其实可以比这更加简单,也是我们在实际开发中常用的写法
就是将整个包写成别名的形式,如果不写alias属性默认为类名(不区分大小写),这样就容易多了,我们只需一行代码,便可以在所有的映射文件命名空间
中直接写对应的类名
引入核心的配置文件
首先需要思考的这里是映射文件的引入,我们正常的一个项目的数据库是有很多个表组成的那么每一张表对应一个mapper接口,每个接口对应一个映射文件,那么就需要导入大量的映射文件,还容易漏掉-->
上面这种以包的形式的导入非常方便,不用每次新建一个接口就要导入它的映射文件,但是上面这种写法需要 注意 一些问题:
如果你在映射文件中编写查询语句的sql,但是粗心的你忘记了设置返回类型会在控制台抛异常且会看到这样的说明:
It's likely that neither a Result Type nor a Result Map was specified
下面只是指定返回类型的一种方式:resultType,还有 resultMap
它们的区别:
查询的标签必须指定resultType或resultMap
comkobedumybatis 获取参数的两种方式:${} 和 #{}
上面是使用了 #{}写法相当于原生jdbc的占位符,这个前面已经提到过了所以不多赘述, 需要注意的是#{}里面的变量名可以是任意的username规范显然很好,但是aaaa也没错因为只是用来占位的;
还有就是在使用${}时注意''单引号问题,因为${}是字符拼接的方式,所以需要注意!!
传输参数时有多个参数时
在测试代码里通过传入两个参数分别为 username和password 但是在上面代码的(映射文件里的部分代码)执行失败,(sql语句未能解析)
报错:
Cause: orgapacheibatisbindingBindingException: Parameter 'username' not found Available parameters are [arg1, arg0, param1, param2]
可以从错误提示的信息不难发现我们的参数在映射文件里未能真正地接受到,可以用[arg1, arg0, param1, param2] 的方式获取,mybatis将参数放到map容器可以通过建arg0,agr1的方式
获取参数(也可以是param1,param2)
将上面的代码改动:
需要注意的是:使用${}时需要手动添加''才能正常访问,因为他的处理方式是字符串的拼接
做了改动之后结果很感人!!
User{id=6, userName='旺财', age=20, password='cwlz'}
可以直接通过键访问相对应的值(通过自己的方式访问到数据,上面的形式是mybatis默认提供的map和mybatis默认的提取指的方式 arg0,arg2)
当需要传多个参数时将他们放到一个map容器,然后将map传给对应的方法(模拟mybatis的做法,就可以在sql语句中直接通过键访问到值)代码如下:
映射文件中的部分代码 :
通过键直接获取值,注意:使用${}时不要忘了单引号!!!!
当参数以实体对象的形式传参时如何解决?
只需要通过#{}以属性名的方式访问!
所以代码的编写一定要规范,才能减少这种错误!!!
一定要和注解中的参数名一一对应!!!
如果查询的结果只有一个,也可以通过Map集合接收,字段名为键字段的值为值:{password=0000, id=3, userName=图区, age=20}
javalangIngeger --> int ,Integer
int --> _int,_Integer
Map --> map
String --> string
注意:
所以在批量删除的案例:需要注意的是不能使用#{} 因为它是会自动添加'' 所以在批量删除的语句中我们要使用${}
若字段和属性名不一致 ,则可以通过resultMap设置自定义映射
在mybatis的核心配置文件用下面的代码将 数据库中命名的规范 (user_name) 转换为 java中的命名规范 (userName)
就是手动设置属性与字段的映射关系:
如果设置了手动的设置属性和字段的映射关系,注意主键使用 id 标签,普通字段使用 result标签,就算属性和字段名一一对应,只要
用了这种方式就 必须要写全 !!!
一对多的查询:
通过分步查询实现:
多条件的查询
if 根据标签中test的属性所对应的表达式决定标签中的内容是否拼接到sql语句中
上面的where后面的 1=1 是细节,因为当where后面的条件都为空时就成了 select from t_user where
显然这种sql语句是有问题的,还有一种情况就是当userName为null时语句就成了 select from t_user where and age=#{age}
这也是错的,所以在where后加一个恒成立的条件不仅不会影响查询结果,而且没有会在特定情况时sql语句是会报错的所以很有必要
where 当where标签中有内容时,会自动生成where关键字,并且将内容前多余的and 或者or去掉
当where中没有内容时,此时where标签没有任何效果 就是不会生成关键字 注意:在写条件时不能在后面加and or 这个在下一条语句无效时mybatis不会帮你去掉!
相当于 if else
一个案例 -->就是当我们需要批量删除一些东西时(参数以数组的形式传入)
sql 片段: 在我们的查询语句不能在实际开发中也一直写 ;因为我们要按需查找,不必将不需要的也查询出来,我们可以将我们平常查询次数较多的字段
放在sql片段内,可以在需要查询时直接进行引用!
缓存,这个术语我们听过很多次,在web阶段时访问网页时有缓存机制!
现在sql的查询时也有缓存机制,有一级缓存,一级缓存是默认开启的,一级缓存的范围时sqlSession,将我们查询到的数据先进行缓存,若下次有相同的查询时不用重新
访问数据库,可以直接从缓存中取出!!!!
手动清空缓存 sqlSessionclearCache();
在mapper配置文件中添加cache标签可以设置一些属性:
逆向工程就是不难理解,我们之前都是由实体类到数据库,而逆向类就是通过数据库表生成实体类,
Java单体项目里,我们一般是只需配置一个数据库,这时代码里的dao层都是只对一个数据库 *** 作;但有时候我们的数据可能在2个或者3个数据库,这时就需要配置更多数据源,进行数据库直连 *** 作,下面以MySQL的两个库为例(Oracle也就换个驱动类与连接串)。
(本文阅读大概花费两分钟)
技术条件:
springboot 253 (即springframework 539)
MySQL 57
mybatis-plus 350
dynamic-datasource 350
druid 129
idea开发工具、maven 339
1、导入相关依赖
2、建立两个数据库mydb(表 user)、db2(表t_class),并分别建一张表
3、编写applicationyaml配置文件
4、编写po类、dao层、一个接口测试类
其中,在dao的类加上对应的数据源标识符,使用此注解combaomidoudynamicdatasourceannotationDS
5、启动项目,查看结果
至此,多数据源环境集成成功;当然这里只使用了查询功能,对应事务相关的下一回合文章再做讨论啥。
为什么要学习它呢?
答:MyBatisPlus可以节省我们大量工作时间,所有的CRUD代码它都可以自动化完成!
优点:
1 易于上手和掌握。
2 sql写在xml里,便于统一管理和优化。
3 解除sql与程序代码的耦合。
4 提供映射标签,支持对象与数据库的orm字段关系映射
5 提供对象关系映射标签,支持对象关系组建维护
6 提供xml标签,支持编写动态sql。
MyBatis Plus(简称 MP)是一个 MyBatis的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。
就像 魂斗罗 中的 1P、2P,基友搭配,效率翻倍。
特性:
无侵入 :只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑。
损耗小 :启动即会自动注入基本 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 *** 作智能分析阻断,也可自定义拦截规则,预防误 *** 作。
11 、引入mybatis-plus相关maven依赖
引入mybatis-plus在spring boot中的场景启动器
ps:切记不可再在pomxml文件中引入mybatis与mybatis-spring的maven依赖,这一点,mybatis-plus的官方文档中已经说明的很清楚了
12、创建数据表
(1)SQL语句
(2) 数据表结构
13、 创建java bean
根据数据表新建相关实体类
1 package comexampledemopojo
14、 配置applicationproprties
数据源使用druid
ps:在进行crud实验之前,简单对mybatis与mybatis-plus做一个简单的对比
21、mybatis与mybatis-plus实现方式对比
(1)提出问题: 假设我们已存在一张 tbl_employee 表,且已有对应的实体类 Employee,实现 tbl_employee 表的 CRUD *** 作我们需要做什么呢?
(2)实现方式: 基于 Mybatis 需要编写 EmployeeMapper 接口,并手动编写 CRUD 方法 提供 EmployeeMapperxml 映射文件,并手动编写每个方法对应的 SQL 语句 基于 Mybatis-plus 只需要创建 EmployeeMapper 接口, 并继承BaseMapper 接口这就是使用 mybatis-plus 需要完成的所有 *** 作,甚至不需要创建 SQL 映射文件。
22、BaseMapper接口介绍
(1)如何理解核心接口BaseMapper
在使用Mybatis-Plus时,核心 *** 作类是BaseMapper接口,其最终也是利用的Mybatis接口编程的实现机制,其默认提供了一系列的增删改查的基础方法,并且开发人员对于这些基础 *** 作不需要写SQL进行处理 *** 作(Mybatis提供的机制就是需要开发人员在mapperxml中提供sql语句),那样我们可以猜测肯定是Mybatis-Plus完成了BaseMapper接口提供的方法的SQL语句的生成 *** 作。
(2)BaseMapper接口为我们定义了哪些方法
BaseMapper接口源码:
(3) mybatis-plus中常用的注解 1
由于我们的数据表名于实体类的类名不一致,并且实体类于数据表还存在字段名不对应的情况,因此我们需要引入mybatis-plus的注解
编写EmployeeMapper接口继承BaseMapper接口
准备考试环境:
(1)插入
(2)修改
控制台打印出的sql语句
如果我们不设置实体类的email与gender属性,结果是怎样的呢
控制台sql语句:
显然,mybatis-plus为我们做了非空判断,空值的话,默认不更新对应的字段想一想,这是不是类似于mybatis中的动态sql呢
这种处理效果又会带来什么好处呢
(3)查询
selectById方法
selectBatchIds方法
ps:发现该方法底层使用的竟然是sql的in关键字
selectByMap方法
(4)删除
3、不得不提的条件构造器---Wrapper
31wrapper及其子类介绍
(1)Wrapper :条件构造抽象类,最顶端父类,抽象类中提供3个方法以及其他方法
以上就是关于Springboot集成Mybatis ID生成策略注解 @GeneratedValue全部的内容,包括:Springboot集成Mybatis ID生成策略注解 @GeneratedValue、mybatis注解怎么解决字段名与属性名不同的问题、mybatis各阶段的详解等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)