myb

阅读 / 问答 / 标签

Mybαbyismissing是什么意思中文?

请用百度翻译软件去了解。

mybⅰrthdayⅰsonaprⅰ|英语什么意思?

我的生日在4月

rmyb是什么格式

视频文件的编码格式是不因后缀名称而改变的,比如你把×××.mp3改为×××.avi,但是这个文件任然是mp3编码格式的所以,虽然你的文件后缀名是rmyb,但不代表就是rmyb编码的,可能就是rmvb的,故意弄个特殊的后缀

CTMNX,YHWZYBMZL,MZBRHY,NMYB,WNMNQSWKM,NMD,ZBNMZXZZDYDHA,求大神翻译 好像是骂人的还是什么的

我看清了一个,第6个词,这个意思是:NMD(National Missile Defence ),即美国国家导弹防御系统,由美国前总统克林顿提出。其工作模式为: 预警雷达首先发现目标,即“敌方”的进攻洲际导弹;预警雷达将报警信号传送到军事卫星; 军事卫星将报警信号传送到指挥部; 指挥部发出命令发射反导弹导弹; 反导弹导弹利用红外跟踪原理搜寻敌方进攻导弹, 识别真假弹头, 然后在地球大气层外拦截敌方进攻导弹, 并用激光武器将其摧毁,第二个意思是:你妈的!

Myb00kis0nthedesk.改为一般疑问句

Is your book on the desk?

医院里面yb是医保的缩写,那jmyb是什么

居民医保

ZWCBXQDSHDWSXNZMYB 这些字母是一句话 就是拼音的头字 但小弟不才.拼不出来.那个高手能帮我拼下先谢谢了!

ZWCBXQDSHDWSXNZMYB CBXQDSHZMB以每个字母为拼音字头的汉字都有十几个、几十个甚至几百个,一个一个慢慢组合吧。

mauymyb在哪里直播

你想问的是mayumi在哪里直播吧,在斗鱼直播。mayumi在斗鱼直播,首秀直播时间是2020年7月1日21:00。英雄联盟巴西女辅助mayumi正式宣布加盟了斗鱼直播平台,在7月1日开启首秀直播。mayumi是巴西日本混血,生日:5月22日,会基本的日语,英语和葡萄牙语。Mayumi曾在2020年春季赛效力于英雄联盟巴西联赛的INTZ战队,但在春季赛结束之后,双方并没有续约。同时Mayumi还爆料战队仅仅是将她作为一个噱头用来吸引粉丝,实际上没有当做选手进行好好的培养。

mybedrrom英语作文四年级新书上第一课的

I have a lovely bedroom. There is a bed in my bedroom. There is a desk near my bed. There is a pink doll on my bed. I sleep with it every night. There is a big window in my bedroom. The yellow lamp is on my desk .Every evening, I do my homework under the lamp. I have a big shelf in my bedroom. There are many books on the shelf. I like reading very much. Do you like reading? You can borrow the books from me if you like? My bedroom is so nice. I like it.

茶叶赠送有缘人上一句怎么说3.s:/^0v83B42mYB^?

琼浆瑾献寻梦者茶叶赠送有缘人

怎么从序列号辨别苹果电脑真伪,序列号为C02K4MYBDRVC

序列号:C02K4MYBDRVC设备名称:MacBook Air (13-inch颜 色:铝类 型:MacBookAir5,2型 号:MD231激活状态:已激活(2013年03月25日)电话支持:未过期(2013年06月23日)硬件保修:未过期(2014年03月24日)生产日期:2013年01月22日 - 2013年01月28日生产工厂:广达电脑真品!!!!!

已知xy=mn,则把它改写成比例式后,正确的是(  )A.xn=myB.yx=mnC.xm=ynD.xn=y

∵xy=mn,∴xn=my.故选A.

mauymyb在哪里直播

你好,你想问mayumi在哪里直播?mayumi在斗鱼直播。mayumi在斗鱼直播,首秀直播时间是2020年7月1日21:00。英雄联盟巴西女辅助mayumi正式宣布加盟了斗鱼直播平台,在7月1日开启首秀直播。

基因注释是myb 后面加个related是啥意思啊?

related 的意思是“与之有关联”。附图的第一行表述是苹果,这是苹果的基因注释??

myb-dna-bind怎么分类

MYB转录因子以保守的DNA结合域为共同特征,是植物最大的转录因子家族之一,广泛参与植物代谢调控。本文根据植物中MYB转录因子的DNA保守结构域,通过RT-PCR和RACE的方法从大豆品种吉林3号的叶片中分离得到了2个MYB基因GmMYBJ6和GmMYBJ7,并对其结构特征和表达特性进行了分析鉴定。基因组DNA序列分析表明,两个基因都含有两个内含子;酵母系统检测表明,两个基因均具有转录激活活性;β-半乳糖甘酶活性分析表明,内含子的存在使两个基因的转录激活活性明显降低;实时荧光定量PCR检测结果显示,GmMYBJ6在大豆中的表达受ABA、GA3和NAA的诱导,而GmMYBJ7的表达则受ABA和NAA的诱导;半定量RT-PCR分析表明,两个基因在大豆的根、茎、叶、花和未成熟种子中均有表达。GmMYBJ6和GmMYBJ7为典型的R2R3-MYB转录因子新基因;他们在大豆中的表达可能与ABA和NAA的信号转导途径有关。(附加:老兄,你的问题好难啊!!)

mybb是什么意思

MyBB是国际上非常优秀的免费论坛软件MyBB的全称是mybboard,是一个基于PHP+MySQL搭建,功能强大,高效的开源论坛系统。 MyBB 使用了标准的论坛结构和模式,所以您的用户可以在您的论坛获得良好的用户体验。 用户可以通过用 MyBB 国外最好的论坛英文版 是一个基于PHP+MySQL搭建,功能强大,高效的开源论坛系统。 MyBB在设计时集成了很多经过深思熟虑的用户习惯,这让MyBB变得更加简单易用。

mybb是什么意思

MyBB的全称是mybboard,MyBB开发团队官方网站是:MyBB。MyBB是一个已经有一段历史的论坛软件,今天它已经从其它布告栏成为了论坛软件。它是一个由积极的开发团队开发的专业和高效率的论坛软件。MyBB的发展历史已经记录,可供感兴趣的朋友阅读。

我想问一下怎么在NCBI上查找苹果,草莓的Myb同源序列,请详细一点,谢谢

.《简明生物信息学》...

MYB转录因子 M Y B 分别是哪几个单词的缩写??

Myb(v-myb avian myeloblastosis viral oncogene homolog)

MYB转录因子的分子结构

首先是每隔约18个氨基酸规则间隔的色氨酸残基,它们参与空间结构中疏水核心的形成。有时色氨酸残基会被某个芳香族氨基酸或疏水氡基酸所取代,尤其是在植物R2R3-MYB转录因子中,R3MYB结构域的第一色氨酸经常被亮氨酸、异亮氮酸或苯丙氨酸所取代。其次,在每个保守的色氨酸前后都存在一些高度保守的氨基酸,例如在第一个色氨酸的C-末端通常是一簇酸性氨基酸正是上述这些保守的氨基酸残基使MYB结构域折叠成螺旋-螺旋-转角-螺旋结构。

lyh.mybb.rovks是什么

lyh.mybb.rocks是一个网站的域名1.域名的结构和含义lyh.mybb.rocks是一个由三个部分组成的域名。域名是用来标识互联网上特定网站的字符串,它的结构是从右到左依次分为顶级域名(TLD)、二级域名(SLD)和三级域名(subdomain)。在lyh.mybb.rocks中,“rocks”是顶级域名,“mybb”是二级域名,“lyh”是三级域名。2.顶级域名.rocks的含义顶级域名.rocks是一种通用顶级域名(gTLD),由Internet Assigned Numbers Authority(IANA)管理。rocks在英语中表示“岩石”,因此.rocks域名常被用于与石头、岩石或其他类似主题相关的网站。它可以被用来创建个人博客、社区论坛、学术研究等各种类型的网站。3.二级域名mybb的含义二级域名mybb是在.rocks域名下的一个子域名。mybb可能是指一个特定的项目、产品或服务。根据上下文来看,mybb可能是指一个名为MyBB的软件或平台。MyBB是一个开源的论坛软件,它提供了用于创建和管理在线论坛的功能。如果lyh.mybb.rocks是一个网站的域名,那么很可能它是基于MyBB论坛软件搭建的。4.三级域名lyh的含义三级域名lyh是在.mybb.rocks域名下的一个子域名。根据具体情况,lyh可能是该网站的个性化标识或标签。在许多情况下,三级域名被用于区分不同的部门、功能或用户组。因此,lyh可能代表网站中某个特定的板块、用户或个人。总结:lyh.mybb.rocks是一个由三个部分组成的域名。其顶级域名.rocks表示网站可能与岩石相关,二级域名mybb可能指的是一个基于开源的MyBB论坛软件搭建的网站,而三级域名lyh可能代表网站中的某个特定板块、用户或个人。具体的含义还需根据上下文来确定。

请问化妆品白色瓶子上写着“MYB”这个是什么牌子,瓶身绿色字写着纯中药晚霜,有谁知道

根据您的描述,大概可以知道可能是蜜诗美品牌的产品。

MYB转录因子的特点及功能

参与植物苯丙烷类次生代谢途径的调节,苯丙烷类代谢是植物主要的3条次生代谢途径之一,它起始于苯丙氨酸,经过几个共同步骤后,分成两个主要分支途径,其中一条分支称为黄酮类代谢途径 ,主要与植物色素合成相关。R2R3-MYB转录因子作为调节蛋 白广泛参与苯丙烷类代谢途径的调控, 主要的证据来自对欧芹、玉米、金鱼草和矮牵牛中黄酮类分支途径的生化和遗传学研究。

MYB转录因子MYB分别是哪几个单词的缩写

American movies take the lead around the world,

MYB转录因子的介绍

MYB类转录因子家族是指含有MYB结构域的一类转录因子。MYB结构域是一段约51-52个氨基酸的肽段,包含一系列高度保守的氨基酸残基和间隔序列。

Myb因子是什么?

MYB转录因子以保守的DNA结合域为共同特征,是植物最大的转录因子家族之一,广泛参与植物代谢调控。本文根据植物中MYB转录因子的DNA保守结构域,通过RT-PCR和RACE的方法从大豆品种吉林3号的叶片中分离得到了2个MYB基因GmMYBJ6和GmMYBJ7,并对其结构特征和表达特性进行了分析鉴定。基因组DNA序列分析表明,两个基因都含有两个内含子;酵母系统检测表明,两个基因均具有转录激活活性;β-半乳糖甘酶活性分析表明,内含子的存在使两个基因的转录激活活性明显降低;实时荧光定量PCR检测结果显示,GmMYBJ6在大豆中的表达受ABA、GA3和NAA的诱导,而GmMYBJ7的表达则受ABA和NAA的诱导;半定量RT-PCR分析表明,两个基因在大豆的根、茎、叶、花和未成熟种子中均有表达。GmMYBJ6和GmMYBJ7为典型的R2R3-MYB转录因子新基因;他们在大豆中的表达可能与ABA和NAA的信号转导途径有关。(附加:老兄,你的问题好难啊!!)

myb是什么意思

是骂人的话吧

myb是什么牌子的衣服

男依邦。男依邦MYB,福建男依邦服饰有限公司是一家从设计、研发、销售为一体的连锁经营品牌公司。人类最初的衣服是用兽皮制成的,包裹身体的最早织物用麻类纤维和草制成。在国家标准中对服装的定义为,衣裳,穿于人体起保护和装饰作用的制品,又称衣服。服装在人类社会发展的早期就已出现,古代人把身边能找到的各种材料做成粗陋的衣服,用以护身。

myB是什么职业

myBmyB是韩国MarooEntertainment于2015年8月25日推出的女子组合。由全熙珠、李俞晶、姜智媛、崔文熙、李珠_、郑河允六名成员组成。组合已于次年12月解散。外文名:MyB/___别名:myBest、mybaby、mybestgirl国籍:韩国职业:歌手经纪公司:MarooEntertainment代表作品:《心脏进攻》《DDODDO》出道日期:2015年8月25日早年经历myB成员李珠_与崔文熙在进入MarooEntertainment当练习生前曾在JYPEntertainment当过练习生。myB成员李珠_曾是JYP经纪公司预备女团6mix的成员,后因个人原因退出JYP经纪公司。演艺经历2015年8月17日,Maroo通过Facebook公开myB首位成员崔文熙;8月18日,公开第二位成员李珠_;8月19日,公布第三位成员姜智媛;8月20日,公布第四、第五位成员全熙珠、李俞晶。2015年8月21日,公开了《心脏进攻(MYOHMY)》MV预告。8月25日,myB携第一张单曲专辑《心脏进攻(MYOHMY)》正式出道并公开了《心脏进攻(MYOHMY)》的MV。2015年11月3日,发布myB回归预告;11月6日,发布《myBubble》MV预告;11月9日,公开新曲《__(DDODDO)》预告并宣布myB将加入新成员郑河允;11月13日,发表第二张单曲专辑《__(DDODDO)》并公开了《__(DDODDO)》的MV。2015年11月初,myB参加综艺《李正的myBaby》,11月24日起在SBS电视台每周二18点放送。myB的经纪公司表示:“不同于其他的女子组合,她们发散了满分的活力。第一支音乐录影带中使用了BMX自行车,独轮自行车,滑板等极限运动道具。加上造型为街头风服装,配以华丽的舞台表演,希望可以给大家看到形象健康的myB。六人女子组合myB在2016年12月正式解散。成员介绍全熙珠艺名:__/Hee-Joo本名:___/全熙珠生日:1996年11月30日星座:天蝎座身高:167cm血型:B队内职务:副主唱、领舞李俞晶艺名:__/U-Jung本名:___/李俞晶生日:1997年2月26日星座:双鱼座身高:164cm血型:A队内职务:副主唱姜智媛艺名:__/G-Won本名:___/姜智媛生日:1997年7月3日星座:巨蟹座身高:166cm血型:A队内职务:主唱、领舞崔文熙艺名:__/Moon-Hee本名:___/崔文熙生日:1997年4月25日星座:金牛座身高:167cm血型:AB队内职务:门面、副主唱、领舞、说唱李珠_艺名:__/Joo-Kyung本名:___/李珠_生日:1997年9月27日星座:天秤座身高:165cm血型:O队内职务:队长、副主唱、领舞、说唱郑河允艺名:__/Ha-Yoon本名:___/郑河允生日:1998年11月21日星座:天蝎座身高:165cm队内职务:副主唱综艺节目音乐作品外界评价女团myB和其他女团不一样的是她们没有选择走性感路线去夺人眼球,而是走健康的运动风,着实让看惯了性感女团的观众们感受道一股清新之风。(韩国生活网评)这个女团的每首歌都很有活力,每个舞台都很卖力。(音悦台网友评)

mybatis boolean和tinyint怎么转换

两个位数不一样。。4位跟1位。。只能boolean=>tinyint哦。。

fewofthemcometomyhomeformybirthday

someting to drink would like on show let"s watch 最后一个不确定

tomybalabala跟巴拉巴拉是一家吗

tomybalabala跟巴拉巴拉是一家吗?我们一起来看看吧!tomybalabala跟巴拉巴拉是一家的,均属于森马集团有限公司,只是市场定位不同。minibalabala主要针对于0-5左右的幼儿以及婴儿,而巴拉巴拉则主要面向于3-15岁左右的青少年儿童。巴拉巴拉产品全面覆盖0-14岁儿童的服装、鞋品、生活家居、出行等品类,是国内儿童时尚生活方式品牌。以上就是小编收集整理出来的,望能够帮助到大家。

英语jeremybaker怎么读

Jeremy(杰热米)英[du0292eru0259mu026a]美[du0292u025bru0259mu026a]n.杰里米(男子名)baker(背克【儿】)英["beu026aku0259]美["beku025a]n.面包师;面包工人;(便携式)烘炉Baker贝克,面包师,贝克(蒙大拿州)这个应该是烘培屋的店名,以jeremy人名命名的

JeremyBurnham是什么职业

JeremyBurnhamJeremyBurnham,演员、编剧,主要作品有《EmmerdaleFarm:Episodedated4August2003》、《CatsEyes》、《看守者》。外文名:JeremyBurnham职业:编剧、演员代表作品:《EmmerdaleFarm:Episodedated4August2003》合作人物:NeilAlderton主要作品电影作品电视剧作品人物关系

mybatis通过预编译进行参数拼接的符号

#{}占位符:占位使用#{}意味着使用的预编译的语句,即在使用jdbc时的preparedStatement,sql语句中如果存在参数则会使用?作占位符,我们知道这种方式可以防止sql注入,并且在使用#{}时形成的sql语句,已经带有引号,例,select * from table1 where id=#{id} 在调用这个语句时我们可以通过后台看到打印出的sql为:select * from table1 where id=‘2" 加入传的值为2.也就是说在组成sql语句的时候把参数默认为字符串。如果传入的是基本类型,那么#{}中的变量名称可以随意写如果传入的参数是pojo类型,那么#{}中的变量名称必须是pojo中的属性.属性.属性?${}拼接符:字符串原样拼接如果传入的是基本类型,那么${}中的变量名必须是value如果传入的参数是pojo类型,那么${}中的变量名称必须是pojo中的属性.属性.属性?注意:使用拼接符有可能造成sql注入使用${}时的sql不会当做字符串处理,是什么就是什么,如上边的语句:select * from table1 where id=${id} 在调用这个语句时控制台打印的为:select * from table1 where id=2 ,假设传的参数值为2从上边的介绍可以看出这两种方式的区别,我们最好是能用#{}则用它,因为它可以防止sql注入,且是预编译的,在需要原样输出时才使用${},如,select * from ${tableName} order by ${id} 这里需要传入表名和按照哪个列进行排序 ,加入传入table1、id 则语句为:select * from table1 order by id如果是使用#{} 则变成了select * from ‘table1" order by ‘id" 我们知道这样就不对了。另,在使用以下的配置时,必须使用#{}

MyBatis查询结果不能映射到pojo,什么原因?

MyBatis详解 与配置MyBatis+Spring+MySqlMyBatis 是一个可以自定义SQL、存储过程和高级映射的持久层框架。MyBatis 摒除了大部分的JDBC代码、手工设置参数和结果集重获。MyBatis 只使用简单的XML 和注解来配置和映射基本数据类型、Map 接口和POJO 到数据库记录。相对Hibernate和Apache OJB等“一站式”ORM解决方案而言,Mybatis 是一种“半自动化”的ORM实现。需要使用的Jar包:mybatis-3.0.2.jar(mybatis核心包)。mybatis-spring-1.0.0.jar(与Spring结合包)。MyBatis简介 MyBatis 是一个可以自定义SQL、存储过程和高级映射的持久层框架。MyBatis 摒除了大部分的JDBC代码、手工设置参数和结果集重获。MyBatis 只使用简单的XML 和注解来配置和映射基本数据类型、Map 接口和POJO 到数据库记录。相对Hibernate和Apache OJB等“一站式”ORM解决方案而言,Mybatis 是一种“半自动化”的ORM实现。需要使用的Jar包:mybatis-3.0.2.jar(mybatis核心包)。mybatis-spring-1.0.0.jar(与Spring结合包)。

mybestfriend英语作文,要点:你的朋友叫什么名字,她长什么样,她喜欢穿什么

Now we use this method to measure the distance precisely because we can measure the time more accurately than the length of the measurement..Actually,Rice is is defined as a light in the distance walked away at a Pt atomic clocks to measure O.000000003335640952 seconds (take

英文舞曲,歌词里有therivermybenine叫什么歌名

Yesterday - Black Eyed Peas Yesterday yesterday yesterday曾经 过去I wanna go back to yesterday我想回到过去I wanna go back to yesterday我想回到过去I wanna go back to yesterday我想回到过去I wanna go back to yesterday我想回到过去Yesterday回到过去We going back to the front give them what they want回到潮流前线 统统让你们得偿所愿Back to the past retro glass回到过去 看那些老古董们Back to the leader back to reviews追忆当年的说唱大亨Take them back to the future将他们带回现在Take them to the true school让他们见识一下什么才是真正的说唱流派Cause we was breaking atoms live at the barbeque过去我们唱着Breaking Atoms,Live at the BarbequeNow we reminiscing pumping audio two现在我们唱着Audio two 追忆过往Listening to niggas niggas with them attitudes听着黑人歌手的摇滚Apl with some black sheep screamingApl和渣货们一起狂喊You can get with this or you can get with that你一定会达成所愿 心想事成Smoke emcees or you could smoke crack成为瘾君子不是什么问题You can sell dope or you can sell raps卖毒品 不如搞搞说唱I sell dope raps cause that"s where it"s at一切由你掌控Now I"m back on the scene crispy and clean hip hop fiend现在我回到过去 说出那些说唱能手Source magazine world famous is the supreme team杂志上的组合都是最好的Sp-1200 drum machine hail to latifah she be the queen熟练的操作着乐器 latifah就是她这个世界的女王Dmc and run be the kings king of rockRun Dmc乐队就是摇滚世界的王My nigga ice-t killed a cop我们兄弟干掉了一个条子And we be to rap what key be to lock我们堪称说唱的灵魂I"m cool like that I"m cool like that我就是这么酷I move like that because I"m smooth like that这就是我的步伐 因为我就是这么优雅I rap like that because I"m phat like that这就是我的说唱 因为我就是这样酷I rock like that because I got it like that这就是我的摇滚 因为我就是这样摇摆And I"m ill like that skilled like that我就是这样有才 就是这样能唱Phil-i-ppines cause I feel like that我只为倾倒 我觉得就该这样I"m real like that yes I"m chill like that我爱它 就爱这样He gots the chill爱到无法自拔I got pounds and pounds of peas you know我有成吨上亿的豆粉I"m not large professor but I"m an extra pro我不是Large Professor 但我也一样再行Punks jump up to punk rock"n"roll随着朋克的节奏一起跳起来The master p-nut is a pistachio我们豆豆组合就是你们的开心果The peas peak past the pinnacle plateau我们早就跨越巅峰Posses a fresh porsche I don"t push peugeot有了保时捷 标志就是小菜Packing out paper in a pass I was pulled抽出支票 老子就是这么任性Get paid to rock mics and used to call the show摇滚不够兴 花钱来场演唱会Here we go yo here we go yo我们开始吧Check the flow yo cause this retro唱着这首复古的歌曲It"s my classic mani-fucking-festo这就是我的迷你机器Lyrically I"m magic fucking presto我幻化出奇妙的歌词和旋律Insuring hip-hop like gecko向他人热情介绍摇滚Making sure it won"t stop baby heck no让它能万古长青That"s a what that"s a what the scenario就是这样的一个画面Reminiscing while I listen to the stereo我们听着音乐回忆过去I reminisce I reminisce回忆过去I reminisce I reminisce回忆过去When it"s sounding like this就是这样I wanna go back to yesterday我想回到过去I wanna go back to yesterday我想回到过去I wanna go back to rappable我想回到过去Cause oh baby I like it raw因为它原汁原味Yeah baby I like it raw原汁原味的Oh baby I like it raw我喜欢原汁原味的音乐Yeah baby I like it raw原汁原味的Shimmy shimmy ya shimmy yam shimmy yey跟我一起跳shimmy舞曲Comment allez-vous parlez vous francais你好吗 你会讲法语吗?Adios motherfuckers bon voyage再见 混蛋 拜拜Home of the liquid flows and liquid swords液体剑就是液体的归属Black eyed killer peas on the swarm我们黑眼豆豆杀手们就藏在人群中Coming to your college and disco dorm来到你的学校和舞厅Y"all can"t touch my skills你们都学不到我们的本领I can switch it up das efx and get iggity-iggity-ill我播放Das Efx的歌又听着No DiggityYiggity-yes rapper my style is uniqueDiggity的说唱歌手有着独特的风格Iggity ice on my teeth so it"s cold when I speakIggity ice这首歌在我舌尖跳动 瞬间冰冻我Word to mom I"m in my own world我在我的世界唱着给妈妈的歌Galaxy raised powerful星际光线 赞I wanna go back to yesterday我想回到过去I wanna go back to yesterday我想回到过去I wanna go back to yesterday我想回到过去So I can hit you with the bass how low can you go我能用我的低音打动你 你能唱多低呢I get lower than the midget doing limbo我可是能比地狱还低I got shit that you haven"t heard a while ago你听都没听过的好东西"88-"92 the style"ll go way back rocking on the a-track老风格 我想要 跟节奏一起摇Memorex tdk all of that throw back before all the razer rapMemorex TDK这些品牌 回到说唱的源头Willy is his name and the boy"s coming straight out of la那时候Willy很出名 男孩们也很火 就到洛杉矶去A crazy motherfucker named willy有个混蛋叫willyI"m so cold my flow stay chilly我就是那么的高冷I got a laser aimed at them haters拿着镭射枪扫射那些讨厌者们And I"m cutting motherfuckers with my razor我用刀片搞定那些混蛋You too boy if you fuck with me如果你惹了我 你也是一样I"mma dice you up slice you up quickly我会把你剁成肉泥I signed to ruthless when dre dropped dre day当Dr.Dre推出Dre Day时 我是那么的冷酷无情That"s why I do this to bring you back to yesterday这就是我带你重回过去的原因Yesterday yesterday yesterday tiger style曾经 过去那是Tiger的时代There"s no place to hide as I step inside the room我走进房间 竟无处容身Dr doom prepare for the boom bam I slam毁灭先生 准备摧毁世界吧Aw man you fucking with william你惹了william了Cause I"m torching and scorching my style is awesome我正用我的风格摧毁一切Cracking motherfuckers" skulls like it"s porcelain像是敲碎瓷器般 敲碎贱人们的头Ay yo let"s save hip hop from dr kevorkian让我们从Dr kevorkian开始拯救摇滚Bring it right here right back to it"s origing将它带回归属地Ay yo I"mma hop in my motherfucking delorean我在我的车里摆动So I can go back and fucking perform again所以我能重振旗鼓 再次表演Ay yo I be some wind mills and some fucking linoleum我带着点Wind Mills和Linoleum的味道Mc mic controlling them I was likeMc mic控制了这个时代I was steady policing them我要稳步掌控他们Killing emcees I was straight deceasing them我要扫清他们Compute-deleting them "til them niggas don"t exist将他们一个个清除Because black eyes peas is hard as hell黑眼豆豆坚不可摧Battle anybody I don"t care if you tell我可以和任何人比试比试I excel they all fail而他们都失败了I told them motherfuckers I"mma take them我学得一技之长Back to yesterday回到过去I"m taking you back to yesterday我会带你们回到过去I"m taking you back to yesterday我会带你们回到过去I"m taking you back to yesterday我会带你们回到过去I took you back to yesterday我带你们回到过去I took you back to yesterday我带你们回到过去I took you back to yesterday我带你们回到过去I took you back to yesterday我带你们回到过去And now I"m taking you to the future现在我要带你们回到未来I"m taking you to the future我要带你们回到未来I"m taking you to the future我要带你们回到未来I"m taking you to the future我要带你们回到未来I"m taking you to the future我要带你们回到未来Taking you to the future带你们回到未来Take you to the future带你们回到未来Take you to the future带你们回到未来Future future future future future回到未来Future我们的未来

Mybatis提示" Invalid bound statement(not found)"是什么问题啊?

Invalid bound statement (not found)这个问题的实质就是 mapper接口和mapper.xml没有映射起来 常见的低智商问题有下列几个: 1.mapper.xml 里面的 namespace与实际类不一样 mapper.xml 里面的 namespace应该是其对应的接口路径。这个有个快捷的检测办法就是按住ctrl键,然后点击namespace里面的包名,如果能跳到对应的类,那就说明没问题。 2.mapper接口的函数名称和mapper.xml里面的标签id不一致 这个问题也很常见,最好的办法还是复制过去,这样可以确保没得问题,1点和2点都是关于拼写错误的情况 3.构建没有进去,请看一下target文件夹下面这些是否存在,没有请重新构建 4.包扫描路径是否正确 检查mybatis的配置是否正确,需要配mapperLocations和typeAliasesPackage属性。 也可以在springboot启动类上面加@MapperScan注解,指定扫描路径 5.配置文件写错 如果你是Mybatis的话请注意yml或者properties文件里面的 如果你是Mybatis plus 这个时候你要注意了,mybatis plus是下面这样的配置,如果你发现1,2,3,4点的问题都没有问题,你需要注意一下这个东西

lhavenofeetmybodyisveryloong啥意思?

lhavenofeetmybodyisveryloong我的身体很长

mybatis-plus默认值问题

mybatis-plus中设置了默认值(如statu默认值为0),但我在save时对象的statu属性有值为1,它的值是1还是0呢?(目前测了一次是0)想知道默认值设置的原理解析,请大神指教

mybatis工作原理及为什么要用

需要,,ibatis只是写sql语句的。一般传值接收值,还是用类控制的。

java 版quartz 可以和mybatis一起用吗

1、用script标签包围,然后像xml语法一样书写@Select({"<script>", "SELECT * FROM tbl_order", "WHERE 1=1", "<when test="title!=null">", "AND mydate = #{mydate}", "</when>", "</script>"})2、用Provider去实现SQL拼接,例如:public class OrderProvider { private final String TBL_ORDER = "tbl_order"; public String queryOrderByParam(OrderPara param) { SQL sql = new SQL().SELECT("*").FROM(TBL_ORDER); String room = param.getRoom(); if (StringUtils.hasText(room)) { sql.WHERE("room LIKE #{room}"); } Date myDate = param.getMyDate(); if (myDate != null) { sql.WHERE("mydate LIKE #{mydate}"); } return sql.toString(); }}public interface OrderDAO { @SelectProvider(type = OrderProvider.class, method = "queryOrderByParam") List<Order> queryOrderByParam(OrderParam param);}注意:方式1有个隐患就是当传入参数为空的时候,可能会造成全表查询。复杂SQL用方式2会比较灵活(当然,并不建议写复杂SQL),而且可以抽象成通用的基类,使每个DAO都可以通过这个基类实现基本的通用查询,原理类似Spring JDBC Template。

mybatis自定义插件要实现什么接口

竟然Mybatis是对四大接口进行拦截的,那我们药先要知道Mybatis的四大接口对象 Executor, StatementHandler, ResultSetHandler, ParameterHandler。上图Mybatis框架的整个执行过程。Mybatis插件能够对则四大对象进行拦截,可以包含到了Mybatis一次会议的所有操作。可见Mybatis的的插件很强大。Executor是 Mybatis的内部执行器,它负责调用StatementHandler操作数据库,并把结果集通过 ResultSetHandler进行自动映射,另外,他还处理了二级缓存的操作。从这里可以看出,我们也是可以通过插件来实现自定义的二级缓存的。StatementHandler是Mybatis直接和数据库执行sql脚本的对象。另外它也实现了Mybatis的一级缓存。这里,我们可以使用插件来实现对一级缓存的操作(禁用等等)。ParameterHandler是Mybatis实现Sql入参设置的对象。插件可以改变我们Sql的参数默认设置。ResultSetHandler是Mybatis把ResultSet集合映射成POJO的接口对象。我们可以定义插件对Mybatis的结果集自动映射进行修改。插件InterceptorMybatis的插件实现要实现Interceptor接口,我们看下这个接口定义的方法。public interface Interceptor {Object intercept(Invocation invocation) throws Throwable;Object plugin(Object target);void setProperties(Properties properties);}这个接口只声明了三个方法。setProperties方法是在Mybatis进行配置插件的时候可以配置自定义相关属性,即:接口实现对象的参数配置plugin方法是插件用于封装目标对象的,通过该方法我们可以返回目标对象本身,也可以返回一个它的代理,可以决定是否要进行拦截进而决定要返回一个什么样的目标对象,官方提供了示例:return Plugin.wrap(target, this);intercept方法就是要进行拦截的时候要执行的方法理解这个接口的定义,先要知道java动态代理机制。plugin接口即返回参数target对象(Executor/ParameterHandler/ResultSetHander/StatementHandler)的代理对象。在调用对应对象的接口的时候,可以进行拦截并处理。Mybatis四大接口对象创建方法Mybatis的插件是采用对四大接口的对象生成动态代理对象的方法来实现的。那么现在我们看下Mybatis是怎么创建这四大接口对象的。public Executor newExecutor(Transaction transaction, ExecutorType executorType) {//确保ExecutorType不为空(defaultExecutorType有可能为空)executorType = executorType == null ? defaultExecutorType : executorType;executorType = executorType == null ? ExecutorType.SIMPLE : executorType;Executor executor; if (ExecutorType.BATCH == executorType) {executor = new BatchExecutor(this, transaction);} else if (ExecutorType.REUSE == executorType) {executor = new ReuseExecutor(this, transaction);} else {executor = new SimpleExecutor(this, transaction);} if (cacheEnabled) {executor = new CachingExecutor(executor);}executor = (Executor) interceptorChain.pluginAll(executor);return executor;}public StatementHandler newStatementHandler(Executor executor, MappedStatement mappedStatement, Object parameterObject, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) {StatementHandler statementHandler = new RoutingStatementHandler(executor, mappedStatement, parameterObject, rowBounds, resultHandler, boundSql);statementHandler = (StatementHandler) interceptorChain.pluginAll(statementHandler);return statementHandler;}public ParameterHandler newParameterHandler(MappedStatement mappedStatement, Object parameterObject, BoundSql boundSql) {ParameterHandler parameterHandler = mappedStatement.getLang().createParameterHandler(mappedStatement, parameterObject, boundSql);parameterHandler = (ParameterHandler) interceptorChain.pluginAll(parameterHandler);return parameterHandler;}public ResultSetHandler newResultSetHandler(Executor executor, MappedStatement mappedStatement, RowBounds rowBounds, ParameterHandler parameterHandler, ResultHandler resultHandler, BoundSql boundSql) {ResultSetHandler resultSetHandler = new DefaultResultSetHandler(executor, mappedStatement, parameterHandler, resultHandler, boundSql, rowBounds);resultSetHandler = (ResultSetHandler) interceptorChain.pluginAll(resultSetHandler);return resultSetHandler;}查看源码可以发现, Mybatis框架在创建好这四大接口对象的实例后,都会调用InterceptorChain.pluginAll()方法。InterceptorChain对象是插件执行链对象,看源码就知道里面维护了Mybatis配置的所有插件(Interceptor)对象。// target --> Executor/ParameterHandler/ResultSetHander/StatementHandlerpublic Object pluginAll(Object target) {for (Interceptor interceptor : interceptors) {target = interceptor.plugin(target);}return target;}其实就是安顺序执行我们插件的plugin方法,一层一层返回我们原对象(Executor/ParameterHandler/ResultSetHander/StatementHandler)的代理对象。当我们调用四大接口对象的方法时候,实际上是调用代理对象的响应方法,代理对象又会调用十大接口对象的实例。Plugin对象我们知道,官方推荐插件实现plugin方法为:Plugin.wrap(target, this);public static Object wrap(Object target, Interceptor interceptor) {// 获取插件的Intercepts注解Map<Class<?>, Set<Method>> signatureMap = getSignatureMap(interceptor);Class<?> type = target.getClass();Class<?>[] interfaces = getAllInterfaces(type, signatureMap);if (interfaces.length > 0) {return Proxy.newProxyInstance(type.getClassLoader(), interfaces, new Plugin(target, interceptor, signatureMap));}return target;}这个方法其实是Mybatis简化我们插件实现的工具方法。其实就是根据当前拦截的对象创建了一个动态代理对象。代理对象的InvocationHandler处理器为新建的Plugin对象。插件配置注解@InterceptsMybatis的插件都要有Intercepts注解来指定要拦截哪个对象的哪个方法。我们知道,Plugin.warp方法会返回四大接口对象的代理对象(通过new Plugin()创建的IvocationHandler处理器),会拦截所有的执行方法。在代理对象执行对应方法的时候,会调用InvocationHandler处理器的invoke方法。Mybatis中利用了注解的方式配置指定拦截哪些方法。具体如下:public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {try {Set<Method> methods = signatureMap.get(method.getDeclaringClass());if (methods != null && methods.contains(method)) {return interceptor.intercept(new Invocation(target, method, args));}return method.invoke(target, args);} catch (Exception e) {throw ExceptionUtil.unwrapThrowable(e);}}可以看到,只有通过Intercepts注解指定的方法才会执行我们自定义插件的intercept方法。未通过Intercepts注解指定的将不会执行我们的intercept方法。官方插件开发方式@Intercepts({@Signature(type = Executor.class, method = "query",args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class})})public class TestInterceptor implements Interceptor {public Object intercept(Invocation invocation) throws Throwable {Object target = invocation.getTarget(); //被代理对象Method method = invocation.getMethod(); //代理方法Object[] args = invocation.getArgs(); //方法参数// do something ...... 方法拦截前执行代码块Object result = invocation.proceed();// do something .......方法拦截后执行代码块return result;}public Object plugin(Object target) {return Plugin.wrap(target, this);}}以上就是Mybatis官方推荐的插件实现的方法,通过Plugin对象创建被代理对象的动态代理对象。可以发现,Mybatis的插件开发还是很简单的。自定义开发方式Mybatis的插件开发通过内部提供的Plugin对象可以很简单的开发。只有理解了插件实现原理,对应不采用Plugin对象我们一样可以自己实现插件的开发。下面是我个人理解之后的自己实现的一种方式。public class TestInterceptor implements Interceptor {public Object intercept(Invocation invocation) throws Throwable {Object target = invocation.getTarget(); //被代理对象Method method = invocation.getMethod(); //代理方法Object[] args = invocation.getArgs(); //方法参数// do something ...... 方法拦截前执行代码块Object result = invocation.proceed();// do something .......方法拦截后执行代码块return result;}public Object plugin(final Object target) {return Proxy.newProxyInstance(Interceptor.class.getClassLoader(), target.getClass().getInterfaces(), new InvocationHandler() {public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {return intercept(new Invocation(target, method, args));}});}public void setProperties(Properties properties) {}}当然,Mybatis插件的那这个时候Intercepts的注解起不到作用了。作者:曹金桂链接:http://www.jianshu.com/p/7c7b8c2c985d来源:简书著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

mybatis java注解怎么加判断

把“,”改成“+”才可以用。

spring集成了springmvc为什么不直接用,spring+mybatis,而还要用ssm

你可以把springmvc当成struts2,大概就明白了。以下内容来自网络,请认真看一遍。Spring是一个轻型容器(light-weight container),其核心是Bean工厂(Bean Factory),用以构造我们所需要的M(Model)。在此基础之上,Spring提供了AOP(Aspect-Oriented Programming, 面向层面的编程)的实现,用它来提供非管理环境下申明方式的事务、安全等服务;对Bean工厂的扩展ApplicationContext更加方便我们实现J2EE的应用;DAO/ORM的实现方便我们进行数据库的开发;Web MVC和Spring Web提供了Java Web应用的框架或与其他流行的Web框架进行集成。1)开源框架2)IoC(控制反转),将类的创建和依赖关系写在配置文件里,由配置文件注入,实现了松耦合3)AOP 将安全,事务等于程序逻辑相对独立的功能抽取出来,利用spring的配置文件将这些功能插进去,实现了按照方面编程,提高了复用性前言最近在看Spring MVC的源码,就把自己对MVC模式和对各种框架的实现的认识写出来给大家看看,算是一个总结.所以,恳请大家用怀疑的眼光来看待这篇文章,假如有认识不对的地方,麻烦指出.MVC与WEB应用MVC是什么就不用我多说了.对于现有较成熟的Model-View-Control(MVC)框架而言,其注意的主要问题无外乎下面这些:Model:模型应该包含由视图显示的数据.在J2EE Web应用中,数据通常应该由普通的javabean组成.一旦一个控制器选择了视图,模型就要包含视图相应的数据.模型本身不应该进一步的访问数据,也不应该和业务对象相联系.模型要解决的问题包括:l 封装要显示的数据l 我不认为模型要依赖于特定的框架l 不一定非得是javabeanView:视图负责显示出模型包含的信息,视图不必了解控制器或是底层业务对象的具体实现视图要解决的问题包括:l 在显示给定数据模型的情况下显示内容l 不应该包含有业务逻辑l 可能需要执行显示逻辑,比如颜色交替的显示某个数组的各行l 视图最好不处理验证的错误,数据的验证应该在由其他组件完成l 视图不应该处理参数,参数应该交由控制器集中处理Control:控制器就好像MVC里的中枢神经,它也许会需要一些助手来帮助它比如解析视图,解析参数等.控制器可以访问到业务对象或者是它的代理是很重要的,比如Struts里的Action.控制器要解决的问题包括:l 检查和抽取请求参数l 调用业务对象,传递从请求中获取的参数l 创建模型,视图讲显示对应的模型l 选择一个合适的视图发送给客户端l 控制器有时不会只有一个现有的框架现在已经有很多的MVC的框架实现.比较流行的应该就是Struts和Webwork了Struts这是最流行的web框架,几乎成为了实际上的工业标准.除了上面讨论的MVC模式应该有的优点以外.它还有如下一些缺点:l 每个Action只生成一次,然后就被缓存起来,再次请求这个Action的时候就不会生成新的对象,而是重复使用第一次生成的对象,这就意味着每个Action必须是线程安全的l 采用ActionForm封装了表单数据,但是却只能对应String类型的数据, 虽然它可以使用工具Commons Beanutils进行类型转化,但是仅仅是提供了对象级别的支持l 严重的依赖于Servlet API, 测试比较困难(不过下一版Struts里的Action.execute的方法签名讲会换成execute(ActionContext actionContext),依赖也许不会那么严重)l 框架本身的验证规则比较简单,一般都是依赖于Commons Validation进行验证l 想在Action前后做些处理很困难.有时甚至不得不自己去写专门的控制器l 由于Struts都是具体的类继承,这样很容易打破封装?l 提供各式各样的自定义的标签,但是数据绑定太原始了,这样就使页面代码依赖于Struts这个特定的框架,而它却不是规范,我觉得这是很致命的l 它太面向JSP了,尽管使用其他视图技术是有可能的,但是使用的时候却不是很方便Webwork这个框架虽然我没使用过,但是却一直在关注它的发展 Webwork的设计思想采用了比Struts更为聪明的一种方式,就技术角度上说比Struts要高出不少.它以Command模式为基础.分为Xwork和Webwork,而且框架并不依赖于Servlet API. Xwork提供了很多核心功能:拦截器(Interceptor),运行时表单验证,类型转换,IoC容器等. WebWork建立在Xwork之上,用于处理基于HTTP的响应和请求.用Map和ActionContext封装了Session,Application等这些Servlet对象.从而解除了和Servlet API的耦合. 但是它仍然不是完美的:l 为每一个请求都创建一个Action可能有些浪费.(但是Servlet引擎也是为每个请求创建多个对象,但是也没看出来对性能有多大的影响?)l 当项目越来越大的时候,配置文件可能会很零乱.好像它不支持多个配置文件l 异常处理是Command模式里值得注意的问题:我们不知道某一特定命令可能会抛出什么特定的异常,所以execute()被迫抛出异常,而不论异常是运行时异常,还是已检查异常 Spring MVC Framework的目标上面说了一些MVC的原理,以及现在主流框架的一些问题,现在来看Spring是如何处理的. Spring MVC框架根据不同的角色定义了很多接口,但是它最大的问题也是依赖于Servlet APISpring MVC Framework有这样一些特点:l 它是基于组件技术的.全部的应用对象,无论控制器和视图,还是业务对象之类的都是java组件.并且和Spring提供的其他基础结构紧密集成.l 不依赖于Servlet API(目标虽是如此,但是在实现的时候确实是依赖于Servlet的)l 可以任意使用各种视图技术,而不仅仅局限于JSPl 支持各种请求资源的映射策略l 它应是易于扩展的我认为评价一个框架,应该有几个原则l 它应该是易于使用的,易于测试的Spring 易于使用吗?我不这么觉得,尤其是它的配置文件.在最恐怖的情况下,各种业务逻辑,基础设施也许会拥挤在一个配置文件里.而如事务处理这些基础设施应该是由容器管理而不是开发人员,就算把这些分开到几个配置文件里,逻辑上虽然清晰了,但是基础设置却还是暴露在外边Spring易于测试吗?对Spring进行单元测试很容易,测试起来很方便l 应该在多个层次上提供接口Spring提供了很多接口,而几乎每个接口都有默认的抽象实现,每个抽象实现都有一些具体实现,所以在可扩展性这点上Spring无疑是很优秀的l 框架内部和框架外部应该被区别对待框架内部可以很复杂,但是使用起来一定要简单,Spring的内部比较麻烦,但是它很好的隐藏了这种复杂性,使用起来很舒服,比如设置一个bean的属性.仅仅是setPropertyValue(String propertyName, Object value)就完成,至于怎么去设置,Spring完全隐藏了这种复杂性l 完善的文档和测试集这个就不用说了,老外的东西,都很完善 Spring Web框架基本流程知道了Spring MVC框架,现在来看看它的流程Spring MVC Framework大至流程如下:当web程序启动的时候,ContextLoaderServlet会把对应的配置文件信息读取出来,通过注射去初始化控制器DispatchServlet. 而当接受到一个HTTP请求的时候, DispatchServlet会让HandlerMapping去处理这个请求.HandlerMapping根据请求URL(不一定非要是URL,完全可以自定义,非常灵活)来选择一个Controller. 然后DispatchServlet会在调用选定的Controller的handlerRequest方法,并且在这个方法前后调用这个Controller的interceptor(假如有配置的话),然后返回一个视图和模型的集合ModelAndView.框架通过ViewResolver来解析视图并且返回一个View对象,最后调用View的render方法返回到客户端DispatcherServlet这是框架的控制器,是一个具体类,它通过运行时的上下文对象来初始化.控制器本身并不去控制流程,而只是是Controller的”控制器”,他只是把处理请求的责任委托给了对应的Controller. 控制器继承自抽象基类FrameworkServlet,它的属性webApplicationContext就代表着这个web程序上下文,而这个上下文对象默认实现就是从一个XML文件读取配置信息(当然也可以是其他文件格式). WebApplicationContext其实是beans包的东西,这个包提供了这个Spring整个框架的基础结构,以后我会分析这个包的内容.但是现在仅仅需要知道WebApplicationContext代表一个web应用的上下文对象. 现在来看看DispatchServlet是如何工作的:DispatchServlet由于继承自抽象基类FrameworkServlet,而FrameworkServlet里的doGet(),doPost()方法里有调用serviceWrapper(),跳到serviceWrapper()里去看,结果发现它有把具体实现委托给了doService(request, response); 方法.所以现在已经很清楚了, DispatchServlet真正实现功能的是doService() 这个方法. 特别的, FrameworkServlet的initFrameworkServlet()这个方法是控制器的初始化方法,用来初始化HandlerMappings之类的对象,这也是延迟到子类实现的.其实就是一个Template模式的实现.don"t call us, we will call u.总的看来,Spring就是通过这样来实现它的控制反转的:用框架来控制流程,而不是用户 跳到doService()一看究竟,就会发现真正工作的又是另一个助手函数doDispatch(request, response),没办法,继续看下去,发现这样两行代码HandlerExecutionChain mappedHandler = null; mappedHandler = getHandler(processedRequest, false);看HandlerExecutionChain源码就发现它其实就是对Controller和它的Interceptors的进行了包装; getHandler()就是从HandlerMappings(这是一个List,存放的handlerMapping对象)中取出对应的handlerMapping对象, 每个HandlerMapping对象代表一个Controller和URL的映射(其实在运行的时候是一个HandlerExecutionChain和URL的映射,而HandlerExecutionChain对象其实就是对Controller和它interceptors的一个包装器,可以把HandlerMapping看成Controller和URL的映射).而这个HandlerMapping是通过配置文件在运行时注射进来的,一般是SimpleUrlHandlerMapping这个子类 取得了HandlerMapping对象,继续向下看,发现: if (mappedHandler.getInterceptors() != null) { for (int i = 0; i < mappedHandler.getInterceptors().length; i++) { HandlerInterceptor interceptor = mappedHandler.getInterceptors()[i]; if (!interceptor.preHandle(processedRequest, response, mappedHandler.getHandler())) { triggerAfterCompletion(mappedHandler, interceptorIndex, processedRequest, response, null); return; } interceptorIndex = i; } }这里就是在调用Controller的拦截器,原理就是这句了: interceptor.preHandle(processedRequest, response, mappedHandler.getHandler(), mv);preHandle方法传入了mappedHandler.getHandler()这个参数来实现递归调用!而interceptor.postHandle方法如此一般.只不过这个方法是在handleRequest方法后调用 继续看下去: HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler()); mv = ha.handle(processedRequest, response, mappedHandler.getHandler());发现Controller的handleRequest真正的操作又被代理给了HandlerAdapter的handle方法,并且返回一个ModelAndView,我想这里增加一层的意义应该是为了解除Controller和DispatchServlet的耦合吧. 接着就很简单了,调用render()方法,在这个方法里面由ViewResoler解析出视图名,再调用视图对象的render方法把合适的视图展现给用户 到此,控制器的流程就OVER了HandlerMapping通过使用HandlerMapping,控制器可以用URL和某一个Controller进行标准的映射,而实现URL映射的具体子类的UrlHandlerMapping. Spring还允许我们自定义映射,比如通过Session,cookie或者用户状态来映射.而这一切仅仅只需要实现HandlerMapping接口而已.不过URL映射已经能满足大部分的要求ControllerController 类似Structs的Action, Controller接口只有一个方法handleRequest(),放回一个ModelAndView对象,如同设计目标所说的那样,每个Controller都是一个java组件,所以它可以在上下文环境中任意配置,组件属性都会在初始化的时候被配置.Spring自己提供了几个具体的实现.方便我们使用ViewResolverController通常返回包含视图名字而不是视图对象的ModelAndView对象.从而彻底的解除了控制器和视图之间的耦合关系,并且在这里还可以提供国际化的支持.在你的配置文件中你可以:welcomeView.class = org.springframework.web.servlet.view. InternalResourceViewwelcomeView.url=/welcome.jsp也可以welcomeView.class = org.springframework.web.servlet.view.xslt. XsltViewwelcomeView.url=/xslt/default.xslt View这也是一个java组件,它不做任何请求处理或是业务逻辑,它仅仅获取模型传递的数据,并把数据显示出来.它里面的 render方法按照如下流程工作:l 设置模型的数据到request作用域l 取得视图的URLl 转发到对应的URL总结:Spring的web框架是一个很优秀的框架,在这里只是走马观花的分析了Spring的工作流程和一些关键的类,但是并没有去深入的去探讨它背后所体现的思想,还有它的优缺点等东西.这些都等下次再说吧

java 怎么使用注解操作mybatis

1、用script标签包围,然后像xml语法一样书写@Select({"<script>", "SELECT * FROM tbl_order", "WHERE 1=1", "<when test="title!=null">", "AND mydate = #{mydate}", "</when>", "</script>"})2、用Provider去实现SQL拼接,例如:public class OrderProvider { private final String TBL_ORDER = "tbl_order"; public String queryOrderByParam(OrderPara param) { SQL sql = new SQL().SELECT("*").FROM(TBL_ORDER); String room = param.getRoom(); if (StringUtils.hasText(room)) { sql.WHERE("room LIKE #{room}"); } Date myDate = param.getMyDate(); if (myDate != null) { sql.WHERE("mydate LIKE #{mydate}"); } return sql.toString(); }}public interface OrderDAO { @SelectProvider(type = OrderProvider.class, method = "queryOrderByParam") List<Order> queryOrderByParam(OrderParam param);}注意:方式1有个隐患就是当传入参数为空的时候,可能会造成全表查询。复杂SQL用方式2会比较灵活(当然,并不建议写复杂SQL),而且可以抽象成通用的基类,使每个DAO都可以通过这个基类实现基本的通用查询,原理类似Spring JDBC Template。

sqlId,Mybatis怎么确定需要执行的方法

因为他手里拿着大把的进入仓库的令牌,他给你一个你就能进去,出来后你还给他,他再接着可以给下一个人,这个时候我们仓库门是一直打开的状态,省去了大把我们开锁、开门、关门、锁门的操作,完全交由一个专业人士管理,更神奇的是他还能记录你的一系列操作。对于tomcat的崇敬之情让我决定深入其中,一探究竟。于是我找到了网上大家首推的教材——《深入剖析tomcat》,书比较老,但是很权威,不影响原理性东西的理解。目前已经看到第二章。一个算法对其每一个输入的实例,都能输出正确的结果并停止,则称它是正确的,我们说一个正确的算法解决了给定的计算问题。不正确的算法对于某些输入来说,可能根本不会停止,或者停止时给出的不是预期的结果。然而,与人们对不正确算法的看法想反,如果这些算法的错误率可以得到控制的话,它们有时候也是有用的。但是一般而言,我们还是仅关注正确的算法!这两个框架的作者是园区里面的江大渔。 首先感谢他的无私开源贡献。之所以要写这个文章是因为群里经常有人问这个客户端框架要如何使用。原因在于服务端框架的文档比较多,客户端的文档比较少,所以很多c#基础比较差的人就不懂怎么玩起来。今天就这里写一个例子希望能给部分人抛砖引玉吧。http://www.cnblogs.com/gutye/ 代理接口方式,我们姑且不管是怎么样代理的,但能够运行起来,肯定是有一段真正的可以运行的代码——实际上就是调用SqlSession接口中的方法。因此首先需要解决的就是下面三个基本问题:配置base指定模板目录可以缩短模板的路径,并且能够避免include语句越级访问任意路径引发安全隐患但是随着项目上线后,发现业务数据越来越多,查询效率越来越慢,这时就需要分析慢查询记录了。如何开启慢查询记录?就是本篇文章介绍的内容了。http://www.cnblogs.com/jrtjwe/ 从表现层来看,Spring MVC用了逻辑命名视图策略,通过引入ViewResolver和View,清晰分离了视图策略的选择和渲染与具体控制器之间的耦合,适合各种视图技术很容易集成到Spring MVC中,不管是JSP/JSTL作为视图技术,还是Velocity/FreeMarker,甚至是PDF/Excel等二进制格式视图形式,使用它们,只需要简单的配置。这个对象最早在IE中被实现,不过它最早的时候是通过ActiveXObject实现的,如果不需要管兼容的话,IE9或者其他浏览器使用 new XMLHttpRequest() 就能创建了一个 XHR (XMLHttpRequest) 对象,IE中由于存在三个版本的XHR对象,所以如果需要兼容,需要对这三个版本进行处理,从中选出IE浏览器中最新支持对象。在大部分 .Net 开发人心目中,好像并没有数据库连接池的概念,只有数据库连接,然后用完要记得close和用using,在 Java 中有太多的开源的数据库连接池,而且好像一个吹的比一个厉害。我其实告诉你,其实在 .Net 中 ADO.Net 已经帮我们实现了数据库连接池,我们并不需要什么配置,用就是了,但 Java 不一样,需要我们自己选择合适的数据库连接池。下面我说说项目中为什么选择了阿里的 Druid 数据库连接池。sqlId,Mybatis怎么确定需要执行的方法标签:

刚开始学习mybatis,有没有什么好的书推荐的?

可以看看《深入浅出MyBatis技术原理与实战》

mybatis 参数是一个基本数据类型时使用#{参数名}为什么有时会报错,而换成#{value}就好了?

举个例子来研究一下。

mybatis中的#和$的区别

mybatis预编译底层实现原理 MyBatis何做SQL预编译呢其实框架底层JDBCPreparedStatement类起作用PreparedStatement我熟悉Statement类象包含编译SQL语句种准备式仅能提高安全性且执行同SQL能够提高效率原SQL已编译再执行需再编译总结 #{}:相于JDBCPreparedStatement ${}:输变量值 简单说#{}经预编译安全;${}未经预编译仅仅取变量值非安全存SQL注入希望帮助~-

mybatis原理是什么?

MyBatis 是支持普通 SQL查询,存储过程和高级映射的优秀持久层框架。MyBatis 消除了几乎所有的JDBC代码和参数的手工设置以及结果集的检索。MyBatis使用简单的 XML或注解用于配置和原始映射,将接口和 Java 的POJOs(Plain Ordinary Java Objects,普通的 Java对象)映射成数据库中的记录。每个MyBatis应用程序主要都是使用SqlSessionFactory实例的,一个SqlSessionFactory实例可以通过SqlSessionFactoryBuilder获得。用xml文件构建SqlSessionFactory实例是非常简单的事情。mybatis的功能构架:1、API接口层:提供给外部使用的接口API,开发人员通过这些本地API来操纵数据库。接口层一接收到调用请求就会调用数据处理层来完成具体的数据处理。2、数据处理层:负责具体的SQL查找、SQL解析、SQL执行和执行结果映射处理等。它主要的目的是根据调用的请求完成一次数据库操作。

mybatis工作原理是什么?

MyBatis 是支持普通 SQL查询,存储过程和高级映射的优秀持久层框架。MyBatis 消除了几乎所有的JDBC代码和参数的手工设置以及结果集的检索。MyBatis 使用简单的 XML或注解用于配置和原始映射,将接口和 Java 的POJOs(Plain Ordinary Java Objects,普通的 Java对象)映射成数据库中的记录。每个MyBatis应用程序主要都是使用SqlSessionFactory实例的,一个SqlSessionFactory实例可以通过SqlSessionFactoryBuilder获得。SqlSessionFactoryBuilder可以从一个xml配置文件或者一个预定义的配置类的实例获得。用xml文件构建SqlSessionFactory实例是非常简单的事情。推荐在这个配置中使用类路径资源(classpath resource),但你可以使用任何Reader实例,包括用文件路径或file://开头的url创建的实例。MyBatis有一个实用类----Resources,它有很多方法,可以方便地从类路径及其它位置加载资源。把Mybatis的功能架构分为三层:1、API接口层:提供给外部使用的接口API,开发人员通过这些本地API来操纵数据库。接口层一接收到调用请求就会调用数据处理层来完成具体的数据处理。2、数据处理层:负责具体的SQL查找、SQL解析、SQL执行和执行结果映射处理等。它主要的目的是根据调用的请求完成一次数据库操作。3、基础支撑层:负责最基础的功能支撑,包括连接管理、事务管理、配置加载和缓存处理,这些都是共用的东西,将他们抽取出来作为最基础的组件。为上层的数据处理层提供最基础的支撑。

mybatis注解怎么解决字段名与属性名不同的问题

查询语句是 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 = session.selectOne(statement+"getPreByIdPresident1", 1);<span style="white-space:pre"> </span>System.out.println("表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中的映射关系去构造PresidentMethod1:直接在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原理相同。。

mybatis mapper 怎么映射到xml 原理

具体方法一般要检查配置文件命名空间,还有applicationContext.xml里的配置<bean id ="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"p:dataSource-ref="dataSource" p:configLocation="classpath:mybatis-config.xml"><property name="mapperLocations"><list><value>classpath*:com/xxx/**/*Mapper.xml</value></list></property></bean>

Mybatis源码解析(1) 如何获得SQL语句

笔者只能说会使用Mybtis,并没有具体研究过源码,站在一个使用者的角度记录解决的问题。 跳过大部分源码,从一个功能点开始入手。 以 Select 操作为例,研究如何获取经过 Mybatis 中 动态语句 转换后的的 SQL语句 。 我们这里不涉及复杂的过程原理(如:读取配置文件、Mapper代理等( 我也不懂 )),只说明一下具体流程。 发现studentMapper被MapperProxy实现。 好奇的同学肯定会问studentMapper是如何创建MapperProxy实例的呢? 一路跟随瞎点。会发现一个配置类,里面东西很多,目前只看和Mapper有关系。 我们继续下一步 到此关于Mapper的运行过程已经分析完了,下面继续分析SelectOne过程。 selectOne 其实只是 selectList 取第一个元素(这点是没有想到的)。 源码解析,这还是第一次写这类文章,确实这些框架的原理,并没有研究过只是知道一点概念,Mapper动态代理之类的。网上的博客从大方向出发,框架设计、设计模式之类的,对于我这种基础薄弱的人看的云里雾里。我准备从一个一个功能开始初步了解、研究此类框架原理。 参考 https://blog.csdn.net/luanlouis/article/details/40422941

Mybatis Mapper接口是如何找到实现类的-源码分析

KeyWords: Mybatis 原理,源码,Mybatis Mapper 接口实现类,代理模式,动态代理,Java动态代理,Proxy.newProxyInstance,Mapper 映射,Mapper 实现 MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。我们在使用 Mybaits 进行 ,通常只需要定义几个 Mapper 接口,然后在编写一个 xml 文件,我们在配置文件中写好 sql , Mybatis 帮我们完成 Mapper 接口道具体实现的调用。以及将结果映射到 model bean 中。 我们在项目中所编写的众多的 Mapper 类只是一个接口(interface ),根据 Java 的多态性我们知道,可以使用接口接口作为形参,进而在运行时确定具体实现的对象是什么。但是,对于 Mapper 接口,我们并没有编写其实现类!Mybatis是如何找到其实现类,进而完成具体的 CRUD 方法调用的呢?原理何在? 为了弄清楚 Mapper 接口是如何找到实现类的,我们先回忆一下 Mybatis 是怎么使用的,根据实际的例子,进而一点点的去分析。这里的使用指的是Mybatis 单独使用,而不是整合 spring , 因为整合 spring 的话,还需要涉及 Mapper dao 装载到 spring 容器的问题,spring 帮忙创建数据源配置等问题。 通常我们使用 Mybatis 的主要步骤是: 从一段代码看起 上面我们概括了使用 Mybatis 的4个步骤。这4个步骤看起来很简单,但是用代码写出来就很多。我们不妨先记着这4个步骤,再去看代码,会容易点。 在这块代码中,第 1 部分我们使用了 Java 编码的形式来实现 SqlSessionFactory ,也可以使用 xml 。如果使用xml的话,上面的第一部分代码就是这样的: 我们本次的目标是弄清楚 “ Mapper 是如何找到实现类的 ”,我们注意上面代码 3 , 4 的位置: 这里 mapper 可以调用selectBlog(1) 这个方法,说明 mapper 是个对象,因为对象才具有方法行为实现啊。BlogMapper接口是不能实例化的,更没有具体方法实现。我们并没有定义一个类,让它实现BlogMapper接口,而在这里它只是通过调用session.getMapper() 所得到的。由此,我们可以推断:肯定是session.getMapper() 方法内部产生了BlogMapper的实现类。有什么技术可以根据BlogMapper 接口生成了一个实现类呢?想到这里,对于有动态代理 使用经验的程序员来说,很容易想到,这背后肯定是基于动态代理技术,具体怎么实现的呢?下面我们来根据源码一探究竟。 Mapper 接口的注册 从上面的代码中,我们知道 BlogMapper 接口的实现类是从session.getMapper中得来的,大概是基于动态代理技术实现。我们既然能够从SqlSession中得到BlogMapper接口的,那么我们肯定需要先在哪里把它放进去了,然后 SqlSession 才能生成我们想要的代理类啊。上面代码中有这么一行: 跟着这个 addMapper 方法的代码实现是这样的: 我们看到这里 mapper 实际上被添加到 mapperRegissry 中。继续跟进代码: 看到这里我们知道上面所执行的configuration.addMapper(BlogMapper.class); 其实最终被放到了HashMap中,其名为knownMappers ,knowMappers是MapperRegistry 类的一个私有属性,它是一个HashMap 。其Key 为当前Class对象,value 为一个MapperProxyFactory 实例。 这里我们总结一下: 诸如BlogMapper 之类的Mapper接口被添加到了MapperRegistry 中的一个HashMap中。并以 Mapper 接口的 Class 对象作为 Key , 以一个携带Mapper接口作为属性的MapperProxyFactory 实例作为value 。MapperProxyFacory从名字来看,好像是一个工厂,用来创建Mapper Proxy的工厂。我们继续往下看。 Mapper接口的动态代理类的生成 上面我们已经知道,Mapper 接口被到注册到了MapperRegistry中——放在其名为knowMappers 的HashMap属性中,我们在调用Mapper接口的方法的时候,是这样的: 这里,我们跟踪一下session.getMapper() 方法的代码实现,这里 SqlSession 是一个接口,他有两个实现类,一个是DefaultSqlSession,另外一个是SqlSessionManager,这里我们用的是DefaultSqlSession. 为什么是DefaultSqlSession呢?因为我们在初始化SqlSessionFactory的时候所调用的SqlSessionFactoryBuilder的build()方法里边配置的就是DefaultSqlSession, 所以,我们进入到DefaultSession类中,看看它对session.getMapper(BlogMapper.class)是怎么实现的: 如代码所示,这里的 getMapper 调用了 configuration.getMapper , 这一步操作其实最终是调用了MapperRegistry,而此前我们已经知道,MapperRegistry是存放了一个HashMap的,我们继续跟踪进去看看,那么这里的get,肯定是从这个hashMap中取数据。我们来看看代码: 我们调用的session.getMapper(BlogMapper.class);最终会到达上面这个方法,这个方法,根据BlogMapper的class对象,以它为key在knowMappers 中找到了对应的value —— MapperProxyFactory(BlogMapper) 对象,然后调用这个对象的newInstance()方法。根据这个名字,我们就能猜到这个方法是创建了一个对象,代码是这样的: 看到这里,就清楚了,最终是通过Proxy.newProxyInstance产生了一个BlogMapper的代理对象。Mybatis 为了完成 Mapper 接口的实现,运用了代理模式。具体是使用了JDK动态代理,这个Proxy.newProxyInstance方法生成代理类的三个要素是: 代理模式中,代理类(MapperProxy)中才真正的完成了方法调用的逻辑。我们贴出MapperProxy的代码,如下: 我们调用的 Blog blog = mapper.selectBlog(1); 实际上最后是会调用这个MapperProxy的invoke方法。这段代码中,if 语句先判断,我们想要调用的方法是否来自Object类,这里的意思就是,如果我们调用toString()方法,那么是不需要做代理增强的,直接还调用原来的method.invoke()就行了。只有调用selectBlog()之类的方法的时候,才执行增强的调用——即mapperMethod.execute(sqlSession, args);这一句代码逻辑。 而mapperMethod.execute(sqlSession, args);这句最终就会执行增删改查了,代码如下: 再往下一层,就是执行JDBC那一套了,获取链接,执行,得到ResultSet,解析ResultSet映射成JavaBean。 至此,我们已经摸清楚了Blog blog = mapper.selectBlog(1); 中,BlogMapper接口调用到得到数据库数据过程中,Mybaitis 是如何为接口生成实现类的,以及在哪里出发了最终的CRUD调用。实际上,如果我们在调用Blog blog = mapper.selectBlog(1);之前,把从slqSession中得到的 mapper 对象打印出来就会看到,输出大概是这样的: 动态代理没错吧,Java动态代理实在是太美妙了。 上面我们用层层深入的方式摸清楚了 Mapper接口是如何找到实现类的。我们分析了 Mapper接口是如何注册的,Mapper接口是如何产生动态代理对象的,Maper接口方法最终是如何执行的。总结起来主要就是这几个点:

mybatis spring struts2原理或者ssh的工作原理

在src的根目录下建一个struts-2.0.dtd(struts包里面有)和struts.xml,struts.xml里面配置常量和自己写的action的路径,在WEB-INF(WEB-ROOT)目录下建一个applicationContext.xml,在这里面配置事务管理器、事务通知、事务切点以及数据库的关联配置和bean文件的关联,还有在web.xml里面配置struts2的filter和filter-mapping

MyBatis解析

从命名上可以看出,这个是一个 Builder 模式的,用于创建 SqlSessionFactory 的类。SqlSessionFactoryBuilder 根据配置来构造 SqlSessionFactory。其中配置方式有两种: mybatis-config.xml 就是我们的配置文件: Java Config 相比较 XML 文件的方式而言,会有一些限制。比如修改了配置文件需要重新编译,注解方式没有 XML 配置项多等。所以,业界大多数情况下是选择 XML 文件的方式。但到底选择哪种方式,这个要取决与自己团队的需要。比如,项目的 SQL 语句不复杂,也不需要一些高级的 SQL 特性,那么 Java Config 则会更加简洁一点;反之,则可以选择 XML 文件的方式。 创建配置文件解析器XMLConfigBuilder 解析mybatis-config.xml里的配置为Configuration对象,Mybatis的全局配置对象。 XMLConfigBuilder#parseConfiguration解析mapper下的xml XMLMapperBuilder#bindMapperForNamespace,根据xml里的 namespace 反射出 mapper接口 的 class,如果有mapper接口,则把该mapper接口的class添加到Configuration的mapperRegistry里。 如果该接口已经注册,则抛出已经绑定的异常。 为该接口注册MapperProxyFactory,但这里只是注册其创建MapperProxy的工厂,并不是创建MapperProxy。 如果Mapper对应的xml资源未加载,触发xml的绑定操作,将xml中的sql语句与Mapper建立关系。 addMapper方法,只是为**Mapper创建对应对应的MapperProxyFactory。 根据Mapper接口与SqlSession创建MapperProxy对象。 根据接口类获取MapperProxyFactory。 调用MapperProxyFactory的newInstance创建MapperProxy对象。 SqlSessionFactory 顾名思义,是用于生产 SqlSession 的工厂。 通过如下的方式来获取 SqlSession 实例: SqlSession 包含了执行 SQL 的所有的方法。以下是示例: 当然,下面的方式可以做到类型安全: MapperProxy是MapperProxyFactory使用SqlSession创建出来的。所以MapperProxy中包含SqlSession。 可以看到MapperProxy调用invoke方法,进而调用MapperMethod的execute(),这些MapperMethod就是和你要执行的命令相关,比如执行select语句,则会通过SqlSession的select()方法,最终调用到Executor的query方法。Executor会再协调另外三个核心组件。 MapperProxy: MapperMethod: 插件的构建: 谈原理首先要知道StatementHandler,ParameterHandler,Result Handler都是代理,他们是Configuration创建,在创建过程中会调用interceptorChain.pluginAll()方法,为四大组件组装插件(再底层是通过Plugin.wrap(target,XX, new Plugin( interceptor))来来创建的)。 插件链是何时构建的: 在执行SqlSession的query或者update方法时,SqlSession会通过Configuration创建Executor代理,在创建过程中就调用interceptor的pluginAll方法组装插件。然后executor在调用doQuery()方法的时候,也会调用Configuration的newStatementHandler方法创建StatemenHandler(和上面描述的一样,这个handler就是个代理,也是通过interceptorChain的pluginAll方法构建插件) 插件如何执行: 以statementhandler的prepare方法的插件为例,正如前面所说,statementhandler是一个proxy,执行他的prepare方法,将调用invokeHandler的invoke方法,而invokeHandler就是Plugin.wrap(target, xxx, new Plugin(interceptor))中的第三个参数,所以很自然invokeHanlder的invoke的方法最终就会调用interceptor对象的intercept方法。 Mybatis的插件配置在configuration内部,初始化时,会读取这些插件,保存于Configuration对象的InterceptorChain中。 org.apache.ibatis.plugin.InterceptorChain.java源码。 上面的for循环代表了只要是插件,都会以责任链的方式逐一执行,所谓插件,其实就类似于拦截器。 插件的编写 插件必须实现org.apache.ibatis.plugin.Interceptor接口。 -intercept()方法:执行拦截内容的地方,拦截目标对象的目标方法的执行 -plugin()方法:决定是否触发intercept()方法。 作用:包装目标对象,包装就是为目标对象创建一个代理对象 -setProperties()方法:给自定义的拦截器传递xml配置的属性参数。将插件注册时的property属性设置进来 下面自定义一个拦截器: 为什么要写Annotation注解?注解都是什么含义? Mybatis规定插件必须编写Annotation注解,是必须,而不是可选。@Intercepts注解:装载一个@Signature列表,一个@Signature其实就是一个需要拦截的方法封装。那么,一个拦截器要拦截多个方法,自然就是一个@Signature列表。 type = Executor.class, method = "query", args = { MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class } 解释:要拦截Executor接口内的query()方法,参数类型为args列表。 Plugin.wrap(target, this)是干什么的? 使用JDK的动态代理,给target对象创建一个delegate代理对象,以此来实现方法拦截和增强功能,它会回调intercept()方法。 Mybatis可以拦截哪些接口对象? Mybatis只能拦截ParameterHandler、ResultSetHandler、StatementHandler、Executor共4个接口对象内的方法。 重新审视interceptorChain.pluginAll()方法:该方法在创建上述4个接口对象时调用,其含义为给这些接口对象注册拦截器功能,注意是注册,而不是执行拦截。 拦截器执行时机:plugin()方法注册拦截器后,那么,在执行上述4个接口对象内的具体方法时,就会自动触发拦截器的执行,也就是插件的执行。 Invocation 可以通过invocation来获取拦截的目标方法,以及执行目标方法。 分页插件原理 由于Mybatis采用的是逻辑分页,而非物理分页,那么,市场上就出现了可以实现物理分页的Mybatis的分页插件。 要实现物理分页,就需要对String sql进行拦截并增强,Mybatis通过BoundSql对象存储String sql,而BoundSql则由StatementHandler对象获取。 因此,就需要编写一个针对StatementHandler的query方法拦截器,然后获取到sql,对sql进行重写增强。

MyBatis分页插件的实现原理是什么?

你好,很高兴回答你的问题。mybatis分页插件是通过在你写好的sql语句基础上,拼接生成两个sql语句实现的。第一个是以你的sql作为子查询进行count的语句,用来查询符合条件是数据总条数。另一个是在你的sql的基础上拼接了limit进行分页查询。如果有帮助到你,请点击采纳。我解答的大部分是软件开发新人遇到的问题,如果有兴趣可以关注我。

Spring整合Mybatis一文讲透,手把手带你实操

在介绍Spring整合Mybatis原理之前,我们得先来稍微介绍Mybatis的工作原理。 在Mybatis中,我们可以使用一个接口去定义要执行sql,简化代码如下: 定义一个接口,@Select表示要执行查询sql语句。 以下为执行sql代码: Mybatis的目的是:使得程序员能够以调用方法的方式执行某个指定的sql,将执行sql的底层逻辑进行了封装。 这里重点思考以下mapper这个对象,当调用SqlSession的getMapper方法时,会对传入的接口生成一个 代理对象,而程序要真正用到的就是这个代理对象,在调用代理对象的方法时,Mybatis会取出该方法所对应的sql语句,然后利用JDBC去执行sql语句,最终得到结果。 UserService中的userMapper属性就会被自动注入为Mybatis中的代理对象。如果你基于一个已经完成整合的项目去调试即可发现,userMapper的类型为: org.apache.ibatis.binding.MapperProxy@41a0aa7d。证明确实是Mybatis中的代理对象。 好,那么现在我们要解决的问题的就是:如何能够把Mybatis的代理对象作为一个bean放入Spring容器中?要解决这个,我们需要对Spring的bean生成过程有一个了解。 Spring启动过程中,大致会经过如下步骤去生成bean 假设有一个A类,假设有如下代码: 一个A类 一个B类,不存在@Component注解 执行如下代码: 输出结果为:com.luban.util.A@6acdbdf5 A类对应的bean对象类型仍然为A类。但是这个结论是不确定的,我们可以利用BeanFactory后置处理器来 修改BeanDefinition,我们添加一个BeanFactory后置处理器: 这样就会导致,原本的A类对应的BeanDefiniton被修改了,被修改成了B类,那么后续正常生成的bean对 象的类型就是B类。此时,调用如下代码会报错: 但是调用如下代码不会报错,尽管B类上没有@Component注解: 并且,下面代码返回的结果是:com.luban.util.B@4b1c1ea0 之所以讲这个问题,是想说明 个问题:在Spring中,bean对象跟class没有直接关系,跟 BeanDefinition才有直接关系。 那么回到我们要解决的问题:如何能够把Mybatis的代理对象作为一个bean放入Spring容器中? 在Spring中,如果你想生成一个bean,那么得先生成一个BeanDefinition,就像你想new一个对象实 例,得先有一个class。 继续回到我们的问题,我们现在想自己生成一个bean,那么得先生成一个BeanDefinition,只要有了 BeanDefinition,通过在BeanDefinition中设置bean对象的类型,然后把BeanDefinition添加给 Spring,Spring就会根据BeanDefinition 动帮我们 成 个类型对应的bean对象。 所以,现在我们要解决两个问题: 注意:上文中我们使用的BeanFactory后置处理器,他只能修改BeanDefinition,并不能新增一个 BeanDefinition。我们应该使用Import技术来添加一个BeanDefinition。后面再详细介绍如果使用Import 技术来添加一个BeanDefinition,可以先看一下伪代码实现思路。 假设:我们有一个UserMapper接口,他的代理对象的类型为UserMapperProxy。 那么我们的思路就是这样的,伪代码如下: 但是,这里有一个严重的问题,就是上文中的UserMapperProxy是我们假设的,他表示一个代理类的类 型,然而Mybatis中的代理对象是利用的JDK的动态代理技术实现的,也就是代理对象的代理类是动态生成的,我们根本方法确定代理对象的代理类到底是什么。 所以回到我们的问题:Mybatis的代理对象的类型是什么? 本来可以有两个答案: 1. 代理对象对应的代理类 2. 代理对象对应的接口 那么答案1就相当于没有了,因为是代理类是动态生成的,那么我们来看答案2:代理对象对应的接口如果我们采用答案2,那么我们的思路就是: 但是,实际上给BeanDefinition对应的类型设置为一个接口是行不通的,因为Spring没有办法根据这个 BeanDefinition去new出对应类型的实例,接口是没法直接new出实例的。 那么现在问题来了,我要解决的问题:Mybatis的代理对象的类型是什么? 两个答案都被我们否定了,所以这个问题是无解的,所以我们不能再沿着这个思路去思考了,只能回到最 开始的问题:如何能够把Mybatis的代理对象作为一个bean放入Spring容器中? 总结上文的推理:我们想通过设置BeanDefinition的class类型,然后由Spring自动的帮助我们去生成对应的bean,但是这条路是行不通的。 终极解决方案 那么我们还有没有其他办法,可以去生成bean呢?并且生成bean的逻辑不能由Spring来帮我们做了,得 由我们自己来做。 FactoryBean 有,那就是Spring中的FactoryBean。我们可以利用FactoryBean去自定义我们要生成的bean对象,比如 我们定义了一个LubanFactoryBean,它实现了FactoryBean,getObject方法就是用来自定义生成bean 对象逻辑的。 执行如下代码: 将打印: lubanFactoryBean: com.luban.util.LubanFactoryBean 1@4d41cee &lubanFactoryBean: com.luban.util.LubanFactoryBean@3712b94 lubanFactoryBean-class: class com.sun.proxy. Proxy20 从结果我们可以看到,从Spring容器中拿名字为"lubanFactoryBean"的bean对象,就是我们所自定义的 jdk动态代理所生成的代理对象。 所以,我们可以通过FactoryBean来向Spring容器中添加一个自定义的bean对象。上文中所定义的 LubanFactoryBean对应的就是UserMapper,表示我们定义了一个LubanFactoryBean,相当于把 UserMapper对应的代理对象作为一个bean放入到了容器中。 但是作为程序员,我们不可能每定义了一个Mapper,还得去定义一个LubanFactoryBean,这是很麻烦的 事情,我们改造一下LubanFactoryBean,让他变得更通用,比如: 改造LubanFactoryBean之后,LubanFactoryBean变得灵活了,可以在构造LubanFactoryBean时,通 过构造传入不同的Mapper接口。 实际上LubanFactoryBean也是一个Bean,我们也可以通过生成一个BeanDefinition来生成一个 LubanFactoryBean,并给构造方法的参数设置不同的值,比如伪代码如下: 特别说一下注意二,表示表示当前BeanDefinition在生成bean对象时,会通过调用LubanFactoryBean的 构造方法来生成,并传入UserMapper的Class对象。那么在生成LubanFactoryBean时就会生成一个 UserMapper接口对应的代理对象作为bean了。 到此为止,其实就完成了我们要解决的问题:把Mybatis中的代理对象作为一个bean放入Spring容器中。 只是我们这是用简单的JDK代理对象模拟的Mybatis中的代理对象,如果有时间,我们完全可以调 Mybatis中提供的方法区生成一个代理对象。这里就不花时间去介绍了。 Import 到这里,我们还有一个事情没有做,就是怎么真正的定义一个BeanDefinition,并把它添加到Spring中, 上文说到我们要利用Import技术,比如可以这么实现: 定义如下类: 并且在AppConfig上添加@Import注解: 这样在启动Spring时就会新增一个BeanDefinition,该BeanDefinition会生成一个LubanFactoryBean对 象,并且在生成LubanFactoryBean对象时会传入UserMapper.class对象,通过LubanFactoryBean内部 的逻辑,相当于会自动生产一个UserMapper接口的代理对象作为一个bean。 总结一下,通过我们的分析,我们要整合Spring和Mybatis,需要我们做的事情如下: 作者:程序员周瑜 链接:https://juejin.cn/post/7089023062800236552

mybatis二级缓存原理

mybatis篇 一级缓存的作用域是Sqlsession级别的,也就是说不同的Sqlsession是不会走一级缓存的,那么如果需要跨Sqlsession的缓存,就需要使用到二级缓存了。 二级缓存的话默认是关闭的,所以需要我们开启,开启的方式官网也有介绍,需要在mybatis-config.xml核心配置文件中开启二级缓存功能,并且我们mapper.xml中也需要加入<cache/>标签,二者缺一不可,后面我们看源码就能知道为啥这两个缺一不可。 先来看个例子 执行结果很意外,为什么二级缓存的功能都开启了,结果sql还是执行了2次,并没有走缓存,其实,二级缓存还有一个要注意的点那就是必须要提交事务二级缓存才会保存记录,因为已经是跨SqlSession共享缓存了,所以事务必须要提交,否则会读取到因混滚导致的错误数据。 有个地方需要注意,二级缓存的Sqlsession中的Executor实际上是CachingExecutor 我们知道getMapper最终的执行都会走到MapperProxy类中的invoker方法,具体就来分析这个类。 最后来到了重点的地方 CacheKey我们可以认为他就是每个方法对应的一个唯一标识符。 这里我们就可以看出为什么之前两者必须要配置,cacheEnable开启了才会用CachingExecutor包装一下BaseExecutor,而<cache/>标签只有配置了才会走缓存的逻辑 这里的tcm 到这,我们就差不多揭开了二级缓存的秘密,重要的还是<cache/>这个标签,因为它的存在就对应着每个mapper.xml中的一个具体Cache类,而这个类在每个mapper.xml中又是同一个,所以最终的值是放入了Cache类中,key为CacheKey,value就是sql执行的结果。 至于为什么需要事务提交才能命中二级缓存,我们看下put方法就知道 这里的putObject并没有真正的把值存入Cache中,而是存入了待提交的Map中,所以再来看下commit做了什么 具体看tcm.commit() 而这里可以看到此处会遍历所有的TransactionCache并执行commit方法 真相就出来了,会遍历待提交的Map然后把里面的值都存入Cache中,所以后面的查询就能直接从Cache中拿到值了。 总结 二级缓存先会把Sqlsession中的Executor包装成包装成CacheingExecutor,所有的sql都会经过这个类,而该类通过mapper.xml中配置的唯一<cache/>标签生成的Cache类存放每个方法执行的结果

mybatis原理

MyBatis 的工作原理:读取 MyBatis 配置文件、加载映射文件、构造会话工厂、创建会话对象、Executor 执行器、输入参数映射、输出结果映射。mybatis原理具体介绍如下:1、读取 MyBatis 配置文件:mybatis-config.xml 为 MyBatis 的全局配置文件,配置了 MyBatis 的运行环境等信息,例如数据库连接信息。2、加载映射文件:映射文件即 SQL 映射文件,该文件中配置了操作数据库的 SQL 语句,需要在 MyBatis 配置文件 mybatis-config.xml 中加载。mybatis-config.xml 文件可以加载多个映射文件,每个文件对应数据库中的一张表。3、构造会话工厂:通过 MyBatis 的环境等配置信息构建会话工厂 SqlSessionFactory。4、创建会话对象:由会话工厂创建 SqlSession 对象,该对象中包含了执行 SQL 语句的所有方法。5、Executor 执行器:MyBatis 底层定义了一个 Executor 接口来操作数据库,它将根据 SqlSession 传递的参数动态地生成需要执行的 SQL 语句,同时负责查询缓存的维护。6、MappedStatement 对象:在 Executor 接口的执行方法中有一个 MappedStatement 类型的参数,该参数是对映射信息的封装,用于存储要映射的 SQL 语句的 id、参数等信息。7、输入参数映射:输入参数类型可以是 Map、List 等集合类型,也可以是基本数据类型和 POJO 类型。输入参数映射过程类似于 JDBC 对 preparedStatement 对象设置参数的过程。8、输出结果映射:输出结果类型可以是 Map、 List 等集合类型,也可以是基本数据类型和 POJO 类型。输出结果映射过程类似于 JDBC 对结果集的解析过程。

mybatis多个参数不加@Param

mybatis 3.4.1之后,允许不加 @Param指定参数名称,自动会以入参的名称作为param key 不加 @Param 的多入参mapper 入参为: update(110, "testAppName") useActualParamName 默认是true,如果入参没加@Param指定参数key,则会利用java8的特性,从反射类Parameter#getName()获取这个参数的名称 例如,可以maven编译插件上指定 不推荐偷懒,这种方式依赖java8的编译特性,比较隐晦,容易让其他开发混淆

hibernate和mybatis怎么防止sql注入

SQL注入是一种代码注入技术,用于攻击数据驱动的应用,恶意的SQL语句被插入到执行的实体字段中(例如,为了转储数据库内容给攻击者)。[摘自] SQL injection - WikipediaSQL注入,大家都不陌生,是一种常见的攻击方式。攻击者在界面的表单信息或URL上输入一些奇怪的SQL片段(例如“or ‘1"="1"”这样的语句),有可能入侵参数检验不足的应用程序。所以,在我们的应用中需要做一些工作,来防备这样的攻击方式。在一些安全性要求很高的应用中(比如银行软件),经常使用将SQL语句全部替换为存储过程这样的方式,来防止SQL注入。这当然是一种很安全的方式,但我们平时开发中,可能不需要这种死板的方式。MyBatis框架作为一款半自动化的持久层框架,其SQL语句都要我们自己手动编写,这个时候当然需要防止SQL注入。其实,MyBatis的SQL是一个具有“输入+输出”的功能,类似于函数的结构,如下:<select id="getBlogById" resultType="Blog" parameterType=”int”>SELECT id,title,author,contentFROM blogWHERE id=#{id}</select>这里,parameterType表示了输入的参数类型,resultType表示了输出的参数类型。回应上文,如果我们想防止SQL注入,理所当然地要在输入参数上下功夫。上面代码中黄色高亮即输入参数在SQL中拼接的部分,传入参数后,打印出执行的SQL语句,会看到SQL是这样的:SELECT id,title,author,content FROM blog WHERE id = ?不管输入什么参数,打印出的SQL都是这样的。这是因为MyBatis启用了预编译功能,在SQL执行前,会先将上面的SQL发送给数据库进行编译;执行时,直接使用编译好的SQL,替换占位符“?”就可以了。因为SQL注入只能对编译过程起作用,所以这样的方式就很好地避免了SQL注入的问题。【底层实现原理】MyBatis是如何做到SQL预编译的呢?其实在框架底层,是JDBC中的PreparedStatement类在起作用,PreparedStatement是我们很熟悉的Statement的子类,它的对象包含了编译好的SQL语句。这种“准备好”的方式不仅能提高安全性,而且在多次执行同一个SQL时,能够提高效率。原因是SQL已编译好,再次执行时无需再编译。话说回来,是否我们使用MyBatis就一定可以防止SQL注入呢?当然不是,请看下面的代码:<select id="getBlogById" resultType="Blog" parameterType=”int”>SELECT id,title,author,contentFROM blogWHERE id=${id}</select>仔细观察,内联参数的格式由“#{xxx}”变为了“${xxx}”。如果我们给参数“id”赋值为“3”,将SQL打印出来是这样的:SELECT id,title,author,content FROM blog WHERE id = 3(上面的对比示例是我自己添加的,为了与前面的示例形成鲜明的对比。)<select id="orderBlog" resultType="Blog" parameterType=”map”>SELECT id,title,author,contentFROM blogORDER BY ${orderParam}</select>仔细观察,内联参数的格式由“#{xxx}”变为了“${xxx}”。如果我们给参数“orderParam”赋值为“id”,将SQL打印出来是这样的:SELECT id,title,author,content FROM blog ORDER BY id显然,这样是无法阻止SQL注入的。在MyBatis中,“${xxx}”这样格式的参数会直接参与SQL编译,从而不能避免注入攻击。但涉及到动态表名和列名时,只能使用“${xxx}”这样的参数格式。所以,这样的参数需要我们在代码中手工进行处理来防止注入。【结论】在编写MyBatis的映射语句时,尽量采用“#{xxx}”这样的格式。若不得不使用“${xxx}”这样的参数,要手工地做好过滤工作,来防止SQL注入攻击。#{}:相当于JDBC中的PreparedStatement${}:是输出变量的值简单说,#{}是经过预编译的,是安全的;${}是未经过预编译的,仅仅是取变量的值,是非安全的,存在SQL注入。如果我们order by语句后用了${},那么不做任何处理的时候是存在SQL注入危险的。你说怎么防止,那我只能悲惨的告诉你,你得手动处理过滤一下输入的内容。如判断一下输入的参数的长度是否正常(注入语句一般很长),更精确的过滤则可以查询一下输入的参数是否在预期的参数集合中。Face your past without regret. Handle your present with confidence.Prepare for future without fear. keep the faith and drop the fear. 面对过去无怨无悔,把握现在充满信心,备战未来无所畏惧。保持信念,克服恐惧!一点一滴的积累,一点一滴的沉淀,学技术需要不断的积淀!

MyBatis怎么防止SQL注入

SQL注入是一种代码注入技术,用于攻击数据驱动的应用,恶意的SQL语句被插入到执行的实体字段中(例如,为了转储数据库内容给攻击者)。[摘自] SQL injection - WikipediaSQL注入,大家都不陌生,是一种常见的攻击方式。攻击者在界面的表单信息或URL上输入一些奇怪的SQL片段(例如“or ‘1"="1"”这样的语句),有可能入侵参数检验不足的应用程序。所以,在我们的应用中需要做一些工作,来防备这样的攻击方式。在一些安全性要求很高的应用中(比如银行软件),经常使用将SQL语句全部替换为存储过程这样的方式,来防止SQL注入。这当然是一种很安全的方式,但我们平时开发中,可能不需要这种死板的方式。MyBatis框架作为一款半自动化的持久层框架,其SQL语句都要我们自己手动编写,这个时候当然需要防止SQL注入。其实,MyBatis的SQL是一个具有“输入+输出”的功能,类似于函数的结构,如下:<select id="getBlogById" resultType="Blog" parameterType=”int”> SELECT id,title,author,content FROM blogWHERE id=#{id}</select>这里,parameterType表示了输入的参数类型,resultType表示了输出的参数类型。回应上文,如果我们想防止SQL注入,理所当然地要在输入参数上下功夫。上面代码中黄色高亮即输入参数在SQL中拼接的部分,传入参数后,打印出执行的SQL语句,会看到SQL是这样的:SELECT id,title,author,content FROM blog WHERE id = ?不管输入什么参数,打印出的SQL都是这样的。这是因为MyBatis启用了预编译功能,在SQL执行前,会先将上面的SQL发送给数据库进行编译;执行时,直接使用编译好的SQL,替换占位符“?”就可以了。因为SQL注入只能对编译过程起作用,所以这样的方式就很好地避免了SQL注入的问题。【底层实现原理】MyBatis是如何做到SQL预编译的呢?其实在框架底层,是JDBC中的PreparedStatement类在起作用,PreparedStatement是我们很熟悉的Statement的子类,它的对象包含了编译好的SQL语句。这种“准备好”的方式不仅能提高安全性,而且在多次执行同一个SQL时,能够提高效率。原因是SQL已编译好,再次执行时无需再编译。话说回来,是否我们使用MyBatis就一定可以防止SQL注入呢?当然不是,请看下面的代码:<select id="getBlogById" resultType="Blog" parameterType=”int”> SELECT id,title,author,content FROM blogWHERE id=${id}</select>仔细观察,内联参数的格式由“#{xxx}”变为了“${xxx}”。如果我们给参数“id”赋值为“3”,将SQL打印出来是这样的:SELECT id,title,author,content FROM blog WHERE id = 3(上面的对比示例是我自己添加的,为了与前面的示例形成鲜明的对比。)<select id="orderBlog" resultType="Blog" parameterType=”map”> SELECT id,title,author,content FROM blogORDER BY ${orderParam}</select>仔细观察,内联参数的格式由“#{xxx}”变为了“${xxx}”。如果我们给参数“orderParam”赋值为“id”,将SQL打印出来是这样的:SELECT id,title,author,content FROM blog ORDER BY id显然,这样是无法阻止SQL注入的。在MyBatis中,“${xxx}”这样格式的参数会直接参与SQL编译,从而不能避免注入攻击。但涉及到动态表名和列名时,只能使用“${xxx}”这样的参数格式。所以,这样的参数需要我们在代码中手工进行处理来防止注入。【结论】在编写MyBatis的映射语句时,尽量采用“#{xxx}”这样的格式。若不得不使用“${xxx}”这样的参数,要手工地做好过滤工作,来防止SQL注入攻击。[摘自] mybatis的#{}和${}的区别以及order by注入问题#{}:相当于JDBC中的PreparedStatement${}:是输出变量的值简单说,#{}是经过预编译的,是安全的;${}是未经过预编译的,仅仅是取变量的值,是非安全的,存在SQL注入。如果我们order by语句后用了${},那么不做任何处理的时候是存在SQL注入危险的。你说怎么防止,那我只能悲惨的告诉你,你得手动处理过滤一下输入的内容。如判断一下输入的参数的长度是否正常(注入语句一般很长),更精确的过滤则可以查询一下输入的参数是否在预期的参数集合中。

mybatis以及预编译如何防止SQL注入

SQL注入是一种代码注入技术,用于攻击数据驱动的应用,恶意的SQL语句被插入到执行的实体字段中(例如,为了转储数据库内容给攻击者)。[摘自]SQL injection - WikipediaSQL注入,大家都不陌生,是一种常见的攻击方式。攻击者在界面的表单信息或URL上输入一些奇怪的SQL片段(例如“or u20181u2019=u20191u2019”这样的语句),有可能入侵参数检验不足的应用程序。所以,在我们的应用中需要做一些工作,来防备这样的攻击方式。在一些安全性要求很高的应用中(比如银行软件),经常使用将SQL语句全部替换为存储过程这样的方式,来防止SQL注入。这当然是一种很安全的方式,但我们平时开发中,可能不需要这种死板的方式。MyBatis框架作为一款半自动化的持久层框架,其SQL语句都要我们自己手动编写,这个时候当然需要防止SQL注入。其实,MyBatis的SQL是一个具有“输入+输出”的功能,类似于函数的结构,如下:<selectid="getBlogById"resultType="Blog"parameterType=”int”>SELECT id,title,author,contentFROM blogWHERE id=#{id}</select>这里,parameterType表示了输入的参数类型,resultType表示了输出的参数类型。回应上文,如果我们想防止SQL注入,理所当然地要在输入参数上下功夫。上面代码中黄色高亮即输入参数在SQL中拼接的部分,传入参数后,打印出执行的SQL语句,会看到SQL是这样的:SELECT id,title,author,content FROM blog WHERE id =?不管输入什么参数,打印出的SQL都是这样的。这是因为MyBatis启用了预编译功能,在SQL执行前,会先将上面的SQL发送给数据库进行编译;执行时,直接使用编译好的SQL,替换占位符“?”就可以了。因为SQL注入只能对编译过程起作用,所以这样的方式就很好地避免了SQL注入的问题。【底层实现原理】MyBatis是如何做到SQL预编译的呢?其实在框架底层,是JDBC中的PreparedStatement类在起作用,PreparedStatement是我们很熟悉的Statement的子类,它的对象包含了编译好的SQL语句。这种“准备好”的方式不仅能提高安全性,而且在多次执行同一个SQL时,能够提高效率。原因是SQL已编译好,再次执行时无需再编译。话说回来,是否我们使用MyBatis就一定可以防止SQL注入呢?当然不是,请看下面的代码:<selectid="getBlogById"resultType="Blog"parameterType=”int”>SELECT id,title,author,contentFROM blogWHERE id=${id}</select>仔细观察,内联参数的格式由“#{xxx}”变为了“${xxx}”。如果我们给参数“id”赋值为“3”,将SQL打印出来是这样的:SELECT id,title,author,content FROM blog WHERE id =3(上面的对比示例是我自己添加的,为了与前面的示例形成鲜明的对比。)<selectid="orderBlog"resultType="Blog"parameterType=”map”>SELECT id,title,author,contentFROM blogORDER BY${orderParam}</select>仔细观察,内联参数的格式由“#{xxx}”变为了“${xxx}”。如果我们给参数“orderParam”赋值为“id”,将SQL打印出来是这样的:SELECT id,title,author,content FROM blog ORDER BYid显然,这样是无法阻止SQL注入的。在MyBatis中,“${xxx}”这样格式的参数会直接参与SQL编译,从而不能避免注入攻击。但涉及到动态表名和列名时,只能使用“${xxx}”这样的参数格式。所以,这样的参数需要我们在代码中手工进行处理来防止注入。【结论】在编写MyBatis的映射语句时,尽量采用“#{xxx}”这样的格式。若不得不使用“${xxx}”这样的参数,要手工地做好过滤工作,来防止SQL注入攻击。#{}:相当于JDBC中的PreparedStatement${}:是输出变量的值简单说,#{}是经过预编译的,是安全的;${}是未经过预编译的,仅仅是取变量的值,是非安全的,存在SQL注入。如果我们order by语句后用了${},那么不做任何处理的时候是存在SQL注入危险的。你说怎么防止,那我只能悲惨的告诉你,你得手动处理过滤一下输入的内容。如判断一下输入的参数的长度是否正常(注入语句一般很长),更精确的过滤则可以查询一下输入的参数是否在预期的参数集合中。mybatis以及预编译如何防止SQL注入标签:观察内容启用应用程序order程序作用长度转储

MyBatis如何防止SQL注入

</select>这里,parameterType表示了输入的参数类型,resultType表示了输出的参数类型。回应上文,如果我们想防止SQL注入,理所当然地要在输入参数上下功夫。上面代码中黄色高亮即输入参数在SQL中拼接的部分,传入参数后,打印出执行的SQL语句,会看到SQL是这样的:SELECT id,title,author,content FROM blog WHERE id = ?不管输入什么参数,打印出的SQL都是这样的。这是因为MyBatis启用了预编译功能,在SQL执行前,会先将上面的SQL发送给数据库进行编译;执行时,直接使用编译好的SQL,替换占位符“?”就可以了。因为SQL注入只能对编译过程起作用,所以这样的方式就很好地避免了SQL注入的问题。【底层实现原理】MyBatis是如何做到SQL预编译的呢?其实在框架底层,是JDBC中的PreparedStatement类在起作用,PreparedStatement是我们很熟悉的Statement的子类,它的对象包含了编译好的SQL语句。这种“准备好”的方式不仅能提高安全性,而且在多次执行同一个SQL时,能够提高效率。原因是SQL已编译好,再次执行时无需再编译。话说回来,是否我们使用MyBatis就一定可以防止SQL注入呢?当然不是,请看下面的代码:<select id="getBlogById" resultType="Blog" parameterType=”int”> SELECT id,title,author,content FROM blogWHERE id=${id}</select>仔细观察,内联参数的格式由“#{xxx}”变为了“${xxx}”。如果我们给参数“id”赋值为“3”,将SQL打印出来是这样的:SELECT id,title,author,content FROM blog WHERE id = 3(上面的对比示例是我自己添加的,为了与前面的示例形成鲜明的对比。)<select id="orderBlog" resultType="Blog" parameterType=”map”> SELECT id,title,author,content FROM blogORDER BY ${orderParam}</select>仔细观察,内联参数的格式由“#{xxx}”变为了“${xxx}”。如果我们给参数“orderParam”赋值为“id”,将SQL打印出来是这样的:SELECT id,title,author,content FROM blog ORDER BY id显然,这样是无法阻止SQL注入的。在MyBatis中,“${xxx}”这样格式的参数会直接参与SQL编译,从而不能避免注入攻击。但涉及到动态表名和列名时,只能使用“${xxx}”这样的参数格式。所以,这样的参数需要我们在代码中手工进行处理来防止注入。【结论】在编写MyBatis的映射语句时,尽量采用“#{xxx}”这样的格式。若不得不使用“${xxx}”这样的参数,要手工地做好过滤工作,来防止SQL注入攻击。[摘自] mybatis的#{}和${}的区别以及order by注入问题#{}:相当于JDBC中的PreparedStatement${}:是输出变量的值简单说,#{}是经过预编译的,是安全的;${}是未经过预编译的,仅仅是取变量的值,是非安全的,存在SQL注入。如果我们order by语句后用了${},那么不做任何处理的时候是存在SQL注入危险的。你说怎么防止,那我只能悲惨的告诉你,你得手动处理过滤一下输入的内容。如判断一下输入的参数的长度是否正常(注入语句一般很长),更精确的过滤则可以查询一下输入的参数是否在预期的参数集合中。MyBatis如何防止SQL注入标签:转储如何bsp表单攻击cep添加typeback

mybatis是如何防止SQL注入的

select id="selectByNameAndPassword" parameterType="java.util.Map" resultMap="BaseResultMap">select id, username, password, rolefrom userwhere username = #{username,jdbcType=VARCHAR}and password = #{password,jdbcType=VARCHAR}</select><select id="selectByNameAndPassword" parameterType="java.util.Map" resultMap="BaseResultMap">select id, username, password, rolefrom userwhere username = ${username,jdbcType=VARCHAR}and password = ${password,jdbcType=VARCHAR}</select>mybatis中的#和$的区别:1、#将传入的数据都当成一个字符串,会对自动传入的数据加一个双引号。如:where username=#{username},如果传入的值是111,那么解析成sql时的值为where username="111", 如果传入的值是id,则解析成的sql为where username="id".2、$将传入的数据直接显示生成在sql中。如:where username=${username},如果传入的值是111,那么解析成sql时的值为where username=111;如果传入的值是;drop table user;,则解析成的sql为:select id, username, password, role from user where username=;drop table user;3、#方式能够很大程度防止sql注入,$方式无法防止Sql注入。4、$方式一般用于传入数据库对象,例如传入表名.5、一般能用#的就别用$,若不得不使用“${xxx}”这样的参数,要手工地做好过滤工作,来防止sql注入攻击。6、在MyBatis中,“${xxx}”这样格式的参数会直接参与SQL编译,从而不能避免注入攻击。但涉及到动态表名和列名时,只能使用“${xxx}”这样的参数格式。所以,这样的参数需要我们在代码中手工进行处理来防止注入。【结论】在编写MyBatis的映射语句时,尽量采用“#{xxx}”这样的格式。若不得不使用“${xxx}”这样的参数,要手工地做好过滤工作,来防止SQL注入攻击。2、什么是sql注入sql注入解释:是一种代码注入技术,用于攻击数据驱动的应用,恶意的SQL语句被插入到执行的实体字段中(例如,为了转储数据库内容给攻击者)SQL注入,大家都不陌生,是一种常见的攻击方式。攻击者在界面的表单信息或URL上输入一些奇怪的SQL片段(例如“or ‘1"="1"”这样的语句),有可能入侵参数检验不足的应用程序。所以,在我们的应用中需要做一些工作,来防备这样的攻击方式。在一些安全性要求很高的应用中(比如银行软件),经常使用将SQL语句全部替换为存储过程这样的方式,来防止SQL注入。这当然是一种很安全的方式,但我们平时开发中,可能不需要这种死板的方式。3、mybatis是如何做到防止sql注入的MyBatis框架作为一款半自动化的持久层框架,其SQL语句都要我们自己手动编写,这个时候当然需要防止SQL注入。其实,MyBatis的SQL是一个具有“输入+输出”的功能,类似于函数的结构,参考上面的两个例子。其中,parameterType表示了输入的参数类型,resultType表示了输出的参数类型。回应上文,如果我们想防止SQL注入,理所当然地要在输入参数上下功夫。上面代码中使用#的即输入参数在SQL中拼接的部分,传入参数后,打印出执行的SQL语句,会看到SQL是这样的:select id, username, password, role from user where username=? and password=?不管输入什么参数,打印出的SQL都是这样的。这是因为MyBatis启用了预编译功能,在SQL执行前,会先将上面的SQL发送给数据库进行编译;执行时,直接使用编译好的SQL,替换占位符“?”就可以了。因为SQL注入只能对编译过程起作用,所以这样的方式就很好地避免了SQL注入的问题。【底层实现原理】MyBatis是如何做到SQL预编译的呢?其实在框架底层,是JDBC中的PreparedStatement类在起作用,PreparedStatement是我们很熟悉的Statement的子类,它的对象包含了编译好的SQL语句。这种“准备好”的方式不仅能提高安全性,而且在多次执行同一个SQL时,能够提高效率。原因是SQL已编译好,再次执行时无需再编译。//安全的,预编译了的Connection conn = getConn();//获得连接String sql = "select id, username, password, role from user where id=?"; //执行sql前会预编译号该条语句PreparedStatement pstmt = conn.prepareStatement(sql); pstmt.setString(1, id); ResultSet rs=pstmt.executeUpdate(); ......//不安全的,没进行预编译private String getNameByUserId(String userId) { Connection conn = getConn();//获得连接 String sql = "select id,username,password,role from user where id=" + id; //当id参数为"3;drop table user;"时,执行的sql语句如下: //select id,username,password,role from user where id=3; drop table user; PreparedStatement pstmt = conn.prepareStatement(sql); ResultSet rs=pstmt.executeUpdate(); ......}【结论:】#{}:相当于JDBC中的PreparedStatement${}:是输出变量的值简单说,#{}是经过预编译的,是安全的;${}是未经过预编译的,仅仅是取变量的值,是非安全的,存在SQL注入。如果我们order by语句后用了${},那么不做任何处理的时候是存在SQL注入危险的。你说怎么防止,那我只能悲惨的告诉你,你得手动处理过滤一下输入的内容。如判断一下输入的参数的长度是否正常(注入语句一般很长),更精确的过滤则可以查询一下输入的参数是否在预期的参数集合中。4、参考文章http://blog.csdn.net/yizhenn/article/details/52384601https://www.cnblogs.com/200911/p/5869097.htmlhttp://www.jb51.net/article/95314.htmmybatis是如何防止SQL注入的标签:输出变量功能tpssql语句fromurlhub表示连接

Donittouchmybottonline是什么意思

原文:Don"t touch my bottom line.译文:别触碰我的底线。语法考点:祈使句。

在mybatis里rownum怎么写

这应该sql语句中增加的 <select id="selectAll" parameterType="java.util.Map" resultType="user">select * from (select row_.*,rownum rownum_ from (select b.user_id,b.shremarkfrom xxxxx b ) row_ where rownum <= #{end}) WHERE rownum_ >= #{start}</select>给你了一个例子。希望能帮到你!

MyBatis知多少(14)分散的数据库系统

设计关系数据库的本意就是需要它遵守一系列严格的设计规则。出于各种原因,有时这些规则会被打破。如果某条规则被破坏、误解或者过度使用,就有可能导致出现复 杂的键和关系。关系数据库设计的规则要求,表中的每一条记录都应当通过一个主键来唯一地标 识。最简单的数据库设计可能会使用一个毫无意义的键作为主键。但也有一些数据库设计可能会 使用一种所谓的自然键,此时真实数据的一部分被用作了键。即使如此,更加复杂 的设计还可能会使用由两列或更多列组成的复合键。主键经常被用于在表与表之间创建关系。所 以任何复杂或错误的主键定义都会因为它与其他表之间存在的关系而被传播出去。有时,主键规则也可能没有被遵守。也就是说,有时数据根本就不存在主键。这就会使得数据库查询变得异常复杂,因为我们无法唯一地标识数据。这也会使得在表之间创建关系变得非常 困难和混乱。这还会对数据库性能造成不好的影响,因为我们往往会在主键上建立索引以提高性 能,且主键还被用来决定数据的物理顺序。在另外一些情况中,主键规则又可能被过度使用了。数据库可能毫无实际理由地使用了复合自然键。这样的设计就是过于认真地遵循规则和尽可能地用最严格的方式实现规则带来的结果。 使用自然键在表之间创建关系实际上会造成对一些真实数据的复制,这对于数据库的维护来说往 往是一件糟糕的事情。复合键用于关系时就会造成更多的冗余,因为这会用到关联表中的好几列, 只为了唯一地标识一条记录。在这两种情况下,由于自然键和复合键的使用,数据库的灵活性就 丧失了,因为自然键和复合键会给数据库维护造成极大的困难,当需要进行数据迁移时更像是一 场“噩梦”。MyBatis可以处理任何类型的复杂键定义和关系。虽然最好还是将数据库设计得更合理一些, 但MyBatis的确可以处理那些使用无意义键、自然键、复合键甚至根本没有键的表。数据模型的去规范化或过度规范化关系数据库的设计包括一个消除冗余的过程。冗余的消除非常重要,因为它保证了数据库能 够提供较好的性能且灵活而可维护。数据模型中消除冗余的过程称为规范化(normalization),规 范化的程度有好几个级别。没有经过任何处理的数据往往存在大量的数据冗余,因此也被认为是 未规范化的。规范化是一个复杂的话题,我们在此不会讨论过多细节。当一个数据库刚刚被设计出来时,我们常用那些未经加工的数据来分析冗余。数据库管理员、 数据建模人员甚至是开发人员都会分析这些数据,然后使用一些用于消除冗余的特定规则的集合 来对它们进行规范化。没有经过规范化的数据模型会存在一些数据冗余(即在不同的表中有相同 的数据),且每张表都有大量的记录和大量的列。经过规范化的数据模型的冗余就很少甚至没有 了,这时模型中会存在较多的表,但每张表中只有几列和几条记录。没有哪个级别的规范化是完美的。一个未经规范化的模型具有简单的优点,甚至有时在性能 上也会具有一些优势。这种模型的数据存取速度可能比经过规范化的模型还更快。造成这种现象 的原因是未经规范化的模型中需要执行的语句和关系演算更少,因此负担也就更少。也就是说, 去规范化应该总是例外而不能作为一条规则。良好的数据库设计往往开始于一个“教条化”的规 范化模型,然后再根据需要对其去规范化。经过规范化后再去规范化的过程总比没有规范化而需 要重新规范化来得简单得多。因此,总是从一个规范化的数据模型开始数据库设计吧。也存在数据库被过度规范化的情况,其结果也会带来很多问题。太多的表就需要创建太多的关系,以致难以维护。过度规范化的数据库会造成的问题包括:当查询数据库时,需要执行很多表连接操作;当更新关系紧密的数据时,需要执行很多更新语句。所有这些都会对数据库性能造成负面影响。还有一点,当需要把这样的数据模型映射到对象模型时,通常也会更加困难,因为你可能不希望你的对象模型拥有与数据模型一样的如此细粒度的类。去规范化的模型也可能存在问题,甚至可能比过度规范化的模型还要多。去规范化的模型容 易具有较多的记录和较多的列。过多的记录会对性能造成负面影响,原因是查找时需要扫描的数据更多了。过多的列也存在同样的问题,因为每条记录的内容都更多了,因此每次执行更新或查询时就需要更多的资源。对这样的大表执行某些操作(如更新或查询)时要格外小心,要保证只针对那些必要的列,切忌将那些无关列也搅和进来。还要说明的一点就是,对于去规范化的模型, 要创建有效的索引通常会很困难。MyBatis对去规范化的模型和过度规范化的模型都是适用的。因为它没有对你的对象模型或数 据模型的粒度做任何假设,它也没有要求两者之间必须相同或基本相似。MyBatis在分离对象模型 和关系模型这件事上,恐怕是做得最好的了。系列文章:MyBatis知多少(1)MyBatis知多少(2)MyBatis知多少(3)MyBatis知多少(4)MyBatis的优势MyBatis知多少(5)业务对象模型MyBatis知多少(6)表现层与业务逻辑层MyBatis知多少(7)持久层MyBatis知多少(8)关系型数据库MyBatis知多少(9)不同类型的数据库MyBatis知多少(10)应用程序数据库MyBatis知多少(11)企业数据库MyBatis知多少(12)私有数据库MyBatis知多少(14)分散的数据库系统标签:

spring mybatis 使用的是什么事务

spring,mybatis事务管理配置与@Transactional注解使用 spring支持编程式事务管理和声明式事务管理两种方式。编程式事务管理使用TransactionTemplate或者直接使用底层的PlatformTransactionManager。对于编程式事务管理,spring推荐使用TransactionTemplate。声明式事务管理建立在AOP之上的。其本质是对方法前后进行拦截,然后在目标方法开始之前创建或者加入一个事务,在执行完目标方法之后根据执行情况提交或者回滚事务。声明式事务最大的优点就是不需要通过编程的方式管理事务,这样就不需要在业务逻辑代码中掺杂事务管理的代码,只需在配置文件中做相关的事务规则声明(或通过基于@Transactional注解的方式),便可以将事务规则应用到业务逻辑中。显然声明式事务管理要优于编程式事务管理,这正是spring倡导的非侵入式的开发方式。声明式事务管理使业务代码不受污染,一个普通的POJO对象,只要加上注解就可以获得完全的事务支持。和编程式事务相比,声明式事务唯一不足地方是,后者的最细粒度只能作用到方法级别,无法做到像编程式事务那样可以作用到代码块级别。但是即便有这样的需求,也存在很多变通的方法,比如,可以将需要进行事务管理的代码块独立为方法等等。声明式事务管理也有两种常用的方式,一种是基于tx和aop名字空间的xml配置文件,另一种就是基于@Transactional注解。显然基于注解的方式更简单易用,更清爽。

英文“mybottle mycolor”是什么意思?

意思是我的瓶子,我的颜色。【英语】英语(English)属于印欧语系中日耳曼语族下的西日耳曼语支,由古代从欧洲大陆移民大不列颠岛的盎格鲁、撒克逊和朱特部落的日耳曼人所说的语言演变而来,并通过英国的殖民活动传播到世界各地。根据以英语作为母语的人数计算,英语是最多国家使用的官方语言,英语也是世界上最广泛的第二语言,也是欧盟,最多国际组织和英联邦国家的官方语言之一。但仅拥有世界第三位的母语使用者,少于官话汉语和西班牙语。上两个世纪英国和美国在文化、经济、军事、政治和科学上的领先地位使得英语成为一种国际语言。如今,许多国际场合都使用英语做为沟通媒介。英语也是与电脑联系最密切的语言,大多数编程语言都与英语有联系,而且随着网络的使用,使英文的使用更普及。英语是联合国的工作语言之一。

英文mybottle mycolor是什么意思

用英语怎么读我的杯孑,我的颜色。

mybottlemycolor保温杯是那产的

mybottlemycolor保温杯是那产的。韩国乐扣乐扣公司生产的,mybottle杯子真假鉴别,正品My bottle杯身非常通透,拿上去,也是十分轻盈的环保材质。而且仿货一般都没包装,最多带个低成本的布套包装,并且连最基本的说明书都没有,正品的尺寸是 195*65cm 耐热-40到100度之间,不可使用微波炉加热。

mybatis-generator 生成代码字段名默认按驼峰命名,可否设置

MyBatis中,可以使用Generator自动生成代码,包括DAO层、MODEL层、MAPPINGSQL映射文件。第一步:下载MyBatis的Generator工具第二步:配置自动生成代码所需的XML配置文件,例如(generator.xml)将这个文件保存至你下载的mybatis-generator-core-1.3.2文件夹下第三步:进入XML配置文件(generator.xml)所在的的目录并执行命令:Dos代码java-jarE:mybatis-generator-core-1.3.2libmybatis-generator-core-1.3.2.jar-configfilegenerator.xml-overwritemybatisgeneratoreclipse插件的安装打开eclipse,点击Help>SoftwareUpdate选择"AvailableSoftware"标签,点击"AddSite"按钮输入以下信息:Location:/svn/sub-projects/generator/trunk/eclipse/UpdateSite/点击ok,自动进入"mybatisgeneratorFeature"点击“install”按钮进行安装。。。。mybatisgenerator插件安装完成配置MybatisGenerator不要生成Example类MybatisGenerator默认设置会生成一大堆罗哩罗嗦的Example类,主要是用各种不同的条件来操作数据库,大部分是用不到的,用到的时候手工修改mapper和接口文件就行了。tableschema="general"tableName="tb_table_name"domainObjectName="EntityName"enableCountByExample="false"enableUpdateByExample="false"enableDeleteByExample="false"enableSelectByExample="false"selectByExampleQueryId="false">name="useActualColumnNames"value="true"/>table>这样生成的mapper和dao接口就清爽多了。

youaremybestgirifriend什么意思

you are my best girlfriend 全部释义和例句>>你是我最好的女朋友girlfriend 英[u02c8gu025c:lfrend] 美[u02c8gu025c:rlfrend] n. 女朋友; 女性朋友; [例句]He had been going out with his girlfriend for seven months.他同女朋友已经交往7个月了。[其他] 复数:girlfriends

mybatis不指定typehandler,使用哪个

TypeHandler写起来很容易,但是有一个很重要的点需要注意。你是否遇到过类似下面的错误:Caused by: java.lang.RuntimeException: 调用方法异常:java.lang.IllegalStateException: Type handler was null on parameter mapping for property "xxx". It was either not specified and/or could not be found for the javaType / jdbcType combination specified.1如果你遇到了这个问题,那么这篇博客正好适合你。如果你还没遇到,也可以避免遇到这个问题。先说错误的原因,MyBatis在查找类型的TypeHandler的时候,调用下面的方法:private <T> TypeHandler<T> getTypeHandler(Type type, JdbcType jdbcType) { Map<JdbcType, TypeHandler<?>> jdbcHandlerMap = TYPE_HANDLER_MAP.get(type); TypeHandler<?> handler = null; if (jdbcHandlerMap != null) { handler = jdbcHandlerMap.get(jdbcType); if (handler == null) { handler = jdbcHandlerMap.get(null); } } if (handler == null && type != null && type instanceof Class && Enum.class.isAssignableFrom((Class<?>) type)) { handler = new EnumTypeHandler((Class<?>) type); } // type drives generics here return (TypeHandler<T>) handler;}1234567891011121314151617一般情况下我们如果在Mapper.xml中使用的resultType,或者使用的resultMap但是resultMap的配置中没有指定特殊类型字段的jdbcType,就会出现上面的错误。从上面源码很容易能看出来,当jdbcType是null的时候:handler = jdbcHandlerMap.get(jdbcType);if (handler == null) { handler = jdbcHandlerMap.get(null);}1234jdbcHandlerMap.get(jdbcType)和jdbcHandlerMap.get(null)作用是一样的,结果都是null,因此就会报出上面提到的错误。这个错误如何解决呢?如果仅从上面错误的原因配置一个jdbcType也解决不了使用resultType时的问题。从源码handler = jdbcHandlerMap.get(null);这里可以看到,默认情况下如果有jdbcType,但是handler=null,也会尝试取出一个key为null的handler。也就是说一般情况下,我们自己配置的TypeHandler都需要有一个key=null的键值。如何设置一个null的key呢?如果你认为是枚举类型JdbcType.NULL那就错了。TypeHandler有两种设置null的方式:1. @MappedJdbcTypes注解@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.TYPE)public @interface MappedJdbcTypes { public JdbcType[] value(); boolean includeNullJdbcType() default false;}123456该注解包含一个属性includeNullJdbcType,将该属性设置为true即可。2. xml配置首先重点说明一下:如果使用了上面的注解配置,那么在xml中的jdbcType配置不会起作用,会完全使用注解中的配置。xml配置方法很简单,那就是不要配置jdbcType属性,例如:<!-- mybatis-config.xml --><typeHandlers> <typeHandler handler="org.mybatis.example.ExampleTypeHandler"/></typeHandlers>1234这种情况下就配置了一个只有null的jdbcType。实际上大多数人可能都是这么配置的,因此都没有遇到过这个异常。

TammyBason主要经历

TammyBasonTammyBason是一名演员,主要作品有《无家可归》。外文名:TammyBason职业:演员代表作品:《无家可归》合作人物:ClayRileyHassler
 1 2 3 4  下一页  尾页