mybatis各阶段的详解

mybatis各阶段的详解,第1张

比如我们在引入了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标签可以设置一些属性:

逆向工程就是不难理解,我们之前都是由实体类到数据库,而逆向类就是通过数据库表生成实体类,

public void save(){

try {

FileOutputStream outStream=thisopenFileOutput("atxt",ContextMODE_WORLD_READABLE);

outStreamwrite(textgetText()toString()getBytes());

outStreamclose();

ToastmakeText(MyActivitythis,"Saved",ToastLENGTH_LONG)show();

} catch (FileNotFoundException e) {

return;

}

*** 作。具体的步骤如下:

获取 MyBatis 中的 MappedStatement 对象。可以通过 SqlSession 的 getConfiguration() 方法获取 Configuration 对象,然后再通过 Configuration 对象的 getMappedStatement() 方法获取 MappedStatement 对象。

从 MappedStatement 对象中获取 BoundSql 对象,即 SQL 语句绑定的参数对象。

从 BoundSql 对象中获取 SQL 语句字符串。可以通过调用 getSql() 方法获取 SQL 语句字符串。

对 SQL 语句进行相应的 *** 作。例如,可以对 SQL 语句进行修改、输出等 *** 作。

Java 通过反射获取 MyBatis 中的 SQL 语句的代码示例:

SqlSession sqlSession = sqlSessionFactoryopenSession();

try {

// 获取 MappedStatement 对象

MappedStatement mappedStatement = sqlSessiongetConfiguration()getMappedStatement("comexamplemapperselectUser");

// 获取 BoundSql 对象

BoundSql boundSql = mappedStatementgetBoundSql(paramObject);

// 获取 SQL 语句字符串

String sql = boundSqlgetSql();

// 对 SQL 语句进行相应的 *** 作

//

} finally {

sqlSessionclose();

}

需要注意的是,在使用反射获取 SQL 语句时,要注意保护用户隐私和安全,以免发生 SQL 注入等问题。

……values(#{username, jdbcType=VARCHAR}, #{age, jdbcType=NUMBER}) 在所有可能为空的字段后面加jdbcType=XXX, XXX是这个值的数据类型,比如我上面插入的username是字符串,可能为空,所以加入jdbcType= VARCHAR, 至于jdbcType有哪些类型你可以查看myBatis API 官方文档,上面写的很清楚

IMESTAMP的变体

1,TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP

在创建新记录和修改现有记录的时候都对这个数据列刷新

2,TIMESTAMP DEFAULT CURRENT_TIMESTAMP 在创建新记录的时候把这个

字段设置为当前时间,但以后修改时,不再刷新它

3,TIMESTAMP ON UPDATE CURRENT_TIMESTAMP 在创建新记录的时候把这个字段设置为0,

以后修改时刷新它

4,TIMESTAMP DEFAULT ‘yyyy-mm-dd hh:mm:ss’ ON UPDATE CURRENT_TIMESTAMP

在创建新记录的时候把这个字段设置为给定值,以后修改时刷新它

MySQL目前不支持列的Default 为函数的形式,如达到你某列的默认值为当前更新日期

与时间的功能,你可以使用TIMESTAMP列类型下面就详细说明TIMESTAMP列类型

TIMESTAMP列类型

TIMESTAMP值可以从1970的某时的开始一直到2037年,精度为一秒,其值作为数字显示。

TIMESTAMP值显示尺寸的格式如下表所示:

+---------------+----------------+

| 列类型| 显示格式  |

| TIMESTAMP(14) | YYYYMMDDHHMMSS | 

| TIMESTAMP(12) | YYMMDDHHMMSS  |

| TIMESTAMP(10) | YYMMDDHHMM |

| TIMESTAMP(8) | YYYYMMDD  |

| TIMESTAMP(6) | YYMMDD |

| TIMESTAMP(4) | YYMM  |

| TIMESTAMP(2) | YY |

+---------------+----------------+

“完整”TIMESTAMP格式是14位,但TIMESTAMP列也可以用更短的显示尺寸

创造最常见的显示尺寸是6、8、12、和14。

你可以在创建表时指定一个任意的显示尺寸,但是定义列长为0或比14大均会被强制定义为列长14。

列长在从1~13范围的奇数值尺寸均被强制为下一个更大的偶数。

列如:

定义字段长度 强制字段长度

TIMESTAMP(0) -> TIMESTAMP(14)

TIMESTAMP(15)-> TIMESTAMP(14)

TIMESTAMP(1) -> TIMESTAMP(2)

TIMESTAMP(5) -> TIMESTAMP(6)

所有的TIMESTAMP列都有同样的存储大小,使用被指定的时期时间值的完整精度

(14位)存储合法的值不考虑显示尺寸。不合法的日期,将会被强制为0存储

这有几个含意:

1、虽然你建表时定义了列TIMESTAMP(8),但在你进行数据插入与更新时TIMESTAMP列

实际上保存了14位的数据(包括年月日时分秒),只不过在你进行查询时MySQL返回给

你的是8位的年月日数据。如果你使用ALTER TABLE拓宽一个狭窄的TIMESTAMP列,

以前被“隐蔽”的信息将被显示。

2、同样,缩小一个TIMESTAMP列不会导致信息失去,除了感觉上值在显示时,

较少的信息被显示出。

3、尽管TIMESTAMP值被存储为完整精度,直接 *** 作存储值的唯一函数是UNIX_TIMESTAMP();

由于MySQL返回TIMESTAMP列的列值是进过格式化后的检索的值,这意味着你可能不能使用某些函数来 *** 作TIMESTAMP列(例如HOUR()或SECOND()),除非TIMESTAMP值的相关部分被包含在格式化的值中。

例如,一个TIMESTAMP列只有被定义为TIMESTAMP(10)以上时,TIMESTAMP列的HH部分才会被显示,

因此在更短的TIMESTAMP值上使用HOUR()会产生一个不可预知的结果。

4、不合法TIMESTAMP值被变换到适当类型的“零”值(00000000000000)。(DATETIME,DATE亦然)

你可以使用下列语句来验证:

CREATE TABLE test ('id' INT (3) UNSIGNED AUTO_INCREMENT, 'date1'

TIMESTAMP (8) PRIMARY KEY('id'));

INSERT INTO test SET id = 1;

SELECT FROM test;

+----+----------------+

| id | date1 |

+----+----------------+

| 1 | 20021114  |

+----+----------------+

ALTER TABLE test CHANGE 'date1' 'date1' TIMESTAMP(14);

SELECT FROM test;

+----+----------------+

| id | date1 |

+----+----------------+

| 1 | 20021114093723 |

+----+----------------+

你可以使用TIMESTAMP列类型自动地用当前的日期和时间标记INSERT或UPDATE的 *** 作。

如果你有多个TIMESTAMP列,只有第一个自动更新。自动更新第一个TIMESTAMP列在下列任何条件下发生:

1、列值没有明确地在一个INSERT或LOAD DATA INFILE语句中指定。

2、列值没有明确地在一个UPDATE语句中指定且另外一些的列改变值。(注意一个UPDATE

设置一个列为它已经有的值,这将不引起TIMESTAMP列被更新,因为如果你设置一个列为

它当前的值,MySQL为了效率而忽略更改。)

3、你明确地设定TIMESTAMP列为NULL

4、除第一个以外的TIMESTAMP列也可以设置到当前的日期和时间,只要将列设为NULL,或NOW()。

CREATE TABLE test ( >

<appender name="ROLLING" class="chqoslogbackcorerollingRollingFileAppender">

<!-- 当发生滚动时 TimeBasedRollingPolicy滚动策略 根据时间来制定滚动策略 -->

<rollingPolicy class="chqoslogbackcorerollingTimeBasedRollingPolicy">

<!-- 按天回滚 daily -->

<!-- local

<fileNamePattern>/Users/liyixiang/Documents/logs/xxx-xxx-${appPort}-%d{-MM-dd}log</fileNamePattern>

-->

<!-- logdir 在maven profile里配置 -->

<fileNamePattern>/logs/xxx-xxx-${appPort}-%d{-MM-dd}log</fileNamePattern>

<!-- 控制保留的归档文件的最大数量 日志最大的历史 5天 -->

<maxHistory>5</maxHistory>

</rollingPolicy>

<!-- 日志格式化 -->

<encoder>

<pattern>%d{HH:mm:ssSSS} [%thread] %-5level %logger{36} - [%msg]%n</pattern>

</encoder>

<p>

</appender>

</p>

<p>

<br>

</p>

<p>

</p><pre class="brush:xml; toolbar: true; auto-links: false;">具体的pattern可以查询logback pattern like this --> </pre>

<p></p>

create tablebatchcon_info(

batch_novarchar(50) not null default '',

file_namevarchar(100) default null,

batch_statevarchar(50) default null,

unit_novarchar(50) default null,

sumint(50) default null,

sum_moneydecimal(15,2) default null,

re_datedate default null,

re_timetime default null,

primary key (batch_no)

)

这是我的表结构,对batch_no,file_name,batch_state,unit_no进行同态查询,同时对re_date进行范围动态查询。

该用什么参数的方法?把他们写在同一个sql语句,xml该怎么写? 传一个实体类的话,re_date对应两个数据,传不了。 传多个参数,parametertype报错了,不是原来的实体类。

以上就是关于mybatis各阶段的详解全部的内容,包括:mybatis各阶段的详解、mybatis3如何使用@Insert注解插入日期类型的字段、java通过反射拿到mybatis中的sql语句并 *** 作怎么用什么时候用等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/10173216.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-06
下一篇 2023-05-06

发表评论

登录后才能评论

评论列表(0条)

保存