mybatis dao实现类之#和$的区别及其实现方式

trackbacks-0
#相当于对数据 加上 双引号,$相当于直接显示数据
1. #将传入的数据都当成一个字符串,会对自动传入的数据加一个双引号。如:order by #user_id#,如果传入的值是111,那么解析成sql时的值为order by "111", 如果传入的值是id,则解析成的sql为order by "id".
2. $将传入的数据直接显示生成在sql中。如:order by $user_id$,如果传入的值是111,那么解析成sql时的值为order by user_id,& 如果传入的值是id,则解析成的sql为order
3. #方式能够很大程度防止sql注入。
4.$方式无法防止Sql注入。
5.$方式一般用于传入数据库对象,例如传入表名.
6.一般能用#的就别用$.
MyBatis排序时使用order by 动态参数时需要注意,用$而不是#
字符串替换
默认情况下,使用#{}格式的语法会导致MyBatis创建预处理语句属性并以它为背景设置安全的值(比如?)。这样做很安全,很迅速也是首选做法,有时你只是想直接在SQL语句中插入一个不改变的字符串。比如,像ORDER BY,你可以这样来使用:
ORDER BY ${columnName}
这里MyBatis不会修改或转义字符串。
重要:接受从用户输出的内容并提供给语句中不变的字符串,这样做是不安全的。这会导致潜在的SQL注入攻击,因此你不应该允许用户输入这些字段,或者通常自行转义并检查。
阅读(...) 评论()1.PreparedStatement是预编译的,对于批量处理可以大大提高效率. 也叫JDBC存储过程2.使用 Statement 对象。在对数据库只执行一次性存取的时侯,用 Statement 对象进行处理。PreparedStatement 对象的开销比Statement大,对于一次性操作并不会带来额外的好处。3.statement每次执行sql语句,相关数据库都要执行sql语句的编译,preparedstatement是预编译得, preparedstatement支持批处理4.Code Fragment 1:String updateString = "UPDATE COFFEES SET SALES = 75 " + "WHERE COF_NAME LIKE &Colombian&";stmt.executeUpdate(updateString);Code Fragment 2:PreparedStatement updateSales = con.prepareStatement("UPDATE COFFEES SET SALES = ? WHERE COF_NAME LIKE ? ");updateSales.setInt(1, 75);updateSales.setString(2, "Colombian");updateSales.executeUpdate();片断2和片断1的区别在于,后者使用了PreparedStatement对象,而前者是普通的Statement对象。PreparedStatement对象不仅包含了SQL语句,而且大多数情况下这个语句已经被预编译过,因而当其执行时,只需DBMS运行SQL语句,而不必先编译。当你需要执行Statement对象多次的时候,PreparedStatement对象将会大大降低运行时间,当然也加快了访问数据库的速度。这种转换也给你带来很大的便利,不必重复SQL语句的句法,而只需更改其中变量的值,便可重新执行SQL语句。选择PreparedStatement对象与否,在于相同句法的SQL语句是否执行了多次,而且两次之间的差别仅仅是变量的不同。如果仅仅执行了一次的话,它应该和普通的对象毫无差异,体现不出它预编译的优越性。5.执行许多SQL语句的JDBC程序产生大量的Statement和PreparedStatement对象。通常认为PreparedStatement对象比Statement对象更有效,特别是如果带有不同参数的同一SQL语句被多次执行的时候。PreparedStatement对象允许数据库预编译SQL语句,这样在随后的运行中可以节省时间并增加代码的可读性。然而,在Oracle环境中,开发人员实际上有更大的灵活性。当使用Statement或PreparedStatement对象时,Oracle数据库会缓存SQL语句以便以后使用。在一些情况下,由于驱动器自身需要额外的处理和在Java应用程序和Oracle服务器间增加的网络活动,执行PreparedStatement对象实际上会花更长的时间。然而,除了缓冲的问题之外,至少还有一个更好的原因使我们在企业应用程序中更喜欢使用PreparedStatement对象,那就是安全性。传递给PreparedStatement对象的参数可以被强制进行类型转换,使开发人员可以确保在插入或查询数据时与底层的数据库格式匹配。当处理公共Web站点上的用户传来的数据的时候,安全性的问题就变得极为重要。传递给PreparedStatement的字符串参数会自动被驱动器忽略。最简单的情况下,这就意味着当你的程序试着将字符串&D'Angelo&插入到VARCHAR2中时,该语句将不会识别第一个&,&,从而导致悲惨的失败。几乎很少有必要创建你自己的字符串忽略代码。在Web环境中,有恶意的用户会利用那些设计不完善的、不能正确处理字符串的应用程序。特别是在公共Web站点上,在没有首先通过PreparedStatement对象处理的情况下,所有的用户输入都不应该传递给SQL语句。此外,在用户有机会修改SQL语句的地方,如HTML的隐藏区域或一个查询字符串上,SQL语句都不应该被显示出来。在执行SQL命令时,我们有二种选择:可以使用PreparedStatement对象,也可以使用Statement对象。无论多少次地使用同一个SQL命令,PreparedStatement都只对它解析和编译一次。当使用Statement对象时,每次执行一个SQL命令时,都会对它进行解析和编译。&&&第一:prepareStatement会先初始化SQL,先把这个SQL提交到数据库中进行预处理,多次使用可提高效率。&&createStatement不会初始化,没有预处理,没次都是从0开始执行SQL第二:prepareStatement可以替换变量&&在SQL语句中可以包含?,可以用ps=conn.prepareStatement("select * from Cust where ID=?");&&int sid=1001;&&ps.setInt(1, sid);&&rs = ps.executeQuery();&&可以把?替换成变量。&&而Statement只能用&&int sid=1001;&&Statement stmt = conn.createStatement();&&ResultSet rs = stmt.executeQuery("select * from Cust where ID="+sid);&&来实现。第三:prepareStatement会先初始化SQL,先把这个SQL提交到数据库中进行预处理,多次使用可提高效率。&&createStatement不会初始化,没有预处理,没次都是从0开始执行SQL
-------------------------------------------------------------------------------------------------------------------------转载内容
在mybatis接口mapper文件中引用传入的参数是通过#{param}或者${param}来使用的。
至于mybatisl中#{}和${}的区别其实很简单,但是之前一直没有理解清楚,网上一堆错误的理解。所以在这里记录一下
其实这个问题很简单。
select * from t_user where name = #{param}
使用#{}就等于使用了PrepareStatement这种占位符的形式。可以防止sql注入等等问题。
select count(*), from t_user group by ${param}
这种group by 字段 ,order by 字段,表名,字段名等没法使用占位符的就需要使用${}
阅读(...) 评论()12337人阅读
最近在用mybatis,之前用过ibatis,总体来说差不多,不过还是遇到了不少问题,再次记录下,
比如说用#{},和 ${}传参的区别,
使用#传入参数是,sql语句解析是会加上&&,比如 &select * from table where name = #{name} ,传入的name为小李,那么最后打印出来的就是
&select * from table where name = ‘小李’,就是会当成字符串来解析,这样相比于$的好处是比较明显对的吧,#{}传参能防止sql注入,如果你传入的参数为 单引号',那么如果使用${},这种方式 那么是会报错的,
另外一种场景是,如果你要做动态的排序,比如 &order by & column,这个时候务必要用${},因为如果你使用了#{},那么打印出来的将会是
select * from table order by &'name' &,这样是没用,
目前来看,能用#就不要用$,
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:423927次
积分:4012
积分:4012
排名:第5282名
原创:44篇
转载:41篇
评论:49条
(1)(1)(3)(1)(2)(3)(1)(1)(4)(3)(3)(4)(9)(5)(1)(2)(2)(8)(12)(1)(2)(1)(4)(1)(1)(3)(7)mybatis中的#和$的区别_百度知道
mybatis中的#和$的区别
html" target="_blank">http请参考文章
<a href="/view/dfc9a1e7ec3a87c:///view/dfc9a1e7ec3a87c://wenku.baidu
知道智能回答机器人
我是知道站内的人工智能,可高效智能地为您解答问题。很高兴为您服务。
为您推荐:
mybatis的相关知识
等待您来回答
下载知道APP
随时随地咨询
出门在外也不愁MyBatis和Hibernate相比,优势在哪里?
看到现在好多Web项目用了MyBatis,没感觉MyBatis好到哪里了,从开发效率上讲,不管是Hibernate的反向工程,还是自动建表,关联映射都比MyBatis方便得多。难道仅仅是因为运行速度,Hibernate也有缓存啊。或者,二者适用场合不同,再或者,MyBatis就是比Hibernate出现晚,晚的就是好么。
按投票排序
1、开发对比开发速度Hibernate的真正掌握要比Mybatis来得难些。Mybatis框架相对简单很容易上手,但也相对简陋些。个人觉得要用好Mybatis还是首先要先理解好Hibernate。开发社区Hibernate 与Mybatis都是流行的持久层开发框架,但Hibernate开发社区相对多热闹些,支持的工具也多,更新也快,当前最高版本4.1.8。而Mybatis相对平静,工具较少,当前最高版本3.2。开发工作量Hibernate和MyBatis都有相应的代码生成工具。可以生成简单基本的DAO层方法。针对高级查询,Mybatis需要手动编写SQL语句,以及ResultMap。而Hibernate有良好的映射机制,开发者无需关心SQL的生成与结果映射,可以更专注于业务流程。2、系统调优对比Hibernate的调优方案制定合理的缓存策略;尽量使用延迟加载特性;采用合理的Session管理机制;使用批量抓取,设定合理的批处理参数(batch_size);进行合理的O/R映射设计Mybatis调优方案MyBatis在Session方面和Hibernate的Session生命周期是一致的,同样需要合理的Session管理机制。MyBatis同样具有二级缓存机制。 MyBatis可以进行详细的SQL优化设计。SQL优化方面Hibernate的查询会将表中的所有字段查询出来,这一点会有性能消耗。Hibernate也可以自己写SQL来指定需要查询的字段,但这样就破坏了Hibernate开发的简洁性。而Mybatis的SQL是手动编写的,所以可以按需求指定查询的字段。Hibernate HQL语句的调优需要将SQL打印出来,而Hibernate的SQL被很多人嫌弃因为太丑了。MyBatis的SQL是自己手动写的所以调整方便。但Hibernate具有自己的日志统计。Mybatis本身不带日志统计,使用Log4j进行日志记录。扩展性方面Hibernate与具体数据库的关联只需在XML文件中配置即可,所有的HQL语句与具体使用的数据库无关,移植性很好。MyBatis项目中所有的SQL语句都是依赖所用的数据库的,所以不同数据库类型的支持不好。3、对象管理与抓取策略对象管理Hibernate 是完整的对象/关系映射解决方案,它提供了对象状态管理(state management)的功能,使开发者不再需要理会底层数据库系统的细节。也就是说,相对于常见的 JDBC/SQL 持久层方案中需要管理 SQL 语句,Hibernate采用了更自然的面向对象的视角来持久化 Java 应用中的数据。换句话说,使用 Hibernate 的开发者应该总是关注对象的状态(state),不必考虑 SQL 语句的执行。这部分细节已经由 Hibernate 掌管妥当,只有开发者在进行系统性能调优的时候才需要进行了解。而MyBatis在这一块没有文档说明,用户需要对对象自己进行详细的管理。抓取策略Hibernate对实体关联对象的抓取有着良好的机制。对于每一个关联关系都可以详细地设置是否延迟加载,并且提供关联抓取、查询抓取、子查询抓取、批量抓取四种模式。 它是详细配置和处理的。而Mybatis的延迟加载是全局配置的。4、缓存机制对比Hibernate缓存Hibernate一级缓存是Session缓存,利用好一级缓存就需要对Session的生命周期进行管理好。建议在一个Action操作中使用一个Session。一级缓存需要对Session进行严格管理。Hibernate二级缓存是SessionFactory级的缓存。 SessionFactory的缓存分为内置缓存和外置缓存。内置缓存中存放的是SessionFactory对象的一些集合属性包含的数据(映射元素据及预定SQL语句等),对于应用程序来说,它是只读的。外置缓存中存放的是数据库数据的副本,其作用和一级缓存类似.二级缓存除了以内存作为存储介质外,还可以选用硬盘等外部存储设备。二级缓存称为进程级缓存或SessionFactory级缓存,它可以被所有session共享,它的生命周期伴随着SessionFactory的生命周期存在和消亡。5、优势对比Mybatis优势MyBatis可以进行更为细致的SQL优化,可以减少查询字段。MyBatis容易掌握,而Hibernate门槛较高。Hibernate优势Hibernate的DAO层开发比MyBatis简单,Mybatis需要维护SQL和结果映射。Hibernate对对象的维护和缓存要比MyBatis好,对增删改查的对象的维护要方便。Hibernate数据库移植性很好,MyBatis的数据库移植性不好,不同的数据库需要写不同SQL。Hibernate有更好的二级缓存机制,可以使用第三方缓存。MyBatis本身提供的缓存机制不佳。来源:麦子学院
通过各种实验,测出两个在相同情景下的性能相关的指数,供大家参考。
测试目标以下测试需要确定几点内容:性能差异的场景;性能不在同场景下差异比;找出各架框优劣,各种情况下的表现,适用场景。测试思路测试总体分成:单表插入,关联插入,单表查询,多表查询。测试分两轮,同场景下默认参数做一轮,调优做强一轮,横纵对比分析了。测试中尽保证输入输出的一致性。样本量尽可能大,达到10万级别以上,减少统计误差。测试提纲具体的场景情况下插入测试1:10万条记录插入。查询测试1:100万数据中单表通过id查询100000次,无关联字段。
查询测试2:100万数据中单表通过id查询100000次,输出关联对象字段。
查询测试3:100万*50万关联数据中查询100000次,两者输出相同字段。准备数据库:mysql 5.6表格设计:twitter:推特Sql代码
CREATE TABLE `twitter` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`add_date` datetime DEFAULT NULL,
`modify_date` datetime DEFAULT NULL,
`ctx` varchar(255) NOT NULL,
`add_user_id` bigint(20) DEFAULT NULL,
`modify_user_id` bigint(20) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `UPDATE_USER_FORI` (`modify_user_id`),
KEY `ADD_USER_FORI` (`add_user_id`),
CONSTRAINT `ADD_USER_FORI` FOREIGN KEY (`add_user_id`) REFERENCES `user` (`id`) ON DELETE SET NULL,
CONSTRAINT `UPDATE_USER_FORI` FOREIGN KEY (`modify_user_id`) REFERENCES `user` (`id`) ON DELETE SET NULL
) ENGINE=InnoDB AUTO_INCREMENT=1048561 DEFAULT CHARSET=utf8
user: 用户Sql代码
CREATE TABLE `user` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`name` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=524281 DEFAULT CHARSET=utf8
测试数据准备:twitter无数据。user50万个随机的用户名。随机内容推特表(material_twitter)无id,仅有随机字符串内容,共10万条。用于插入控推特表。生成数据代码,关联100个用户:Java代码
insert into twitter(ctx,add_user_id,modify_user_id,add_date,modify_date)
SELECT name,ROUND(RAND()*100)+1,ROUND(RAND()*100)+1,'',''
from MATERIAL
生成数据代码,关联500000个用户:Java代码
insert into twitter(ctx,add_user_id,modify_user_id,add_date,modify_date)
SELECT name,ROUND(RAND()*,ROUND(RAND()*,'',''
from MATERIAL
实体代码Java代码
@Table(name = "twitter")
public class Twitter implements java.io.Serializable{
private Date add_
private Date modify_
private User add_
private User modify_
private String createUserN
@GeneratedValue(strategy = IDENTITY)
@Column(name = "id", unique = true, nullable = false)
public Long getId() {
public void setId(Long id) {
@Temporal(TemporalType.DATE)
@Column(name = "add_date")
public Date getAddDate() {
return add_
public void setAddDate(Date add_date) {
this.add_date = add_
@Temporal(TemporalType.DATE)
@Column(name = "modify_date")
public Date getModifyDate() {
return modify_
public void setModifyDate(Date modify_date) {
this.modify_date = modify_
@Column(name = "ctx")
public String getCtx() {
public void setCtx(String ctx) {
this.ctx =
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "add_user_id")
public User getAddUser() {
return add_
public void setAddUser(User add_user) {
this.add_user = add_
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "modify_user_id")
public User getModifyUser() {
return modify_
public void setModifyUser(User modify_user) {
this.modify_user = modify_
@Transient
public String getCreateUserName() {
return createUserN
public void setCreateUserName(String createUserName) {
this.createUserName = createUserN
开始插入测试1代码操作:将随机内容推特表的数据加载到内存中,然后一条条加入到推特表中,共10万条。关键代码:hibernate:Java代码
Session session = factory.openSession();
session.beginTransaction();
Twitter t =
Date now = new Date();
for(String materialTwitter : materialTwitters){
System.out.println("materialTwitter="+materialTwitter);
t = new Twitter();
t.setCtx(materialTwitter);
t.setAddDate(now);
t.setModifyDate(now);
t.setAddUser(null);
t.setModifyUser(null);
session.save(t);
session.getTransaction().commit();
mybatis:Java代码
Twitter t =
Date now = new Date();
for(String materialTwitter : materialTwitters){
System.out.println("materialTwitter="+materialTwitter);
t = new Twitter();
t.setCtx(materialTwitter);
t.setAddDate(now);
t.setModifyDate(now);
t.setAddUser(null);
t.setModifyUser(null);
msession.insert("insertTwitter", t);
TwitterMapper.xml,插入代码片段:Xml代码
&insert id="insertTwitter" keyProperty="id" parameterType="org.pushio.test.show1.entity.Twitter" useGeneratedKeys="true"&
insert into twitter(ctx, add_date,modify_date) values (#{ctx},#{add_date},#{modify_date})
查询测试1通过id从1递增到10万依次进行查询推特内容,仅输出微博内容。关键代码:hibernate:Java代码
long cnt = 100000;
for(long i = 1; i &= ++i){
Twitter t = (Twitter)session.get(Twitter.class, i);
//System.out.println("t.getCtx="+ t.getCtx() + " t.getUser.getName=" + t.getAddUser().getName());
mybatis:Java代码
long cnt = 100000;
for(long i = 1; i &= ++i){
Twitter t = (Twitter)msession.selectOne("getTwitter", i);
//System.out.println("t.getCtx="+ t.getCtx() + " t.getUser.getName=" + t.getAddUser().getName());
查询测试2与查询测试1总体一样,增加微博的创建人名称字段,此处需要关联。其中微博对应有10万个用户。可能一部份用户重复。这里对应的用户数可能与hibernate配懒加载的情况有影响。此处体现了hibernate的一个方便处,可以直接通过getAddUser()可以取得user相关的字段。
然而myBatis则需要编写新的vo,因此在测试batis时则直接在Twitter实体中增加创建人员名字成员(createUserName)。
此处hibernate则会分别测试有懒加载,无懒加载。mybatis会测有默认与有缓存两者情况。其中mybatis的缓存机制比较难有效配置,不适用于真实业务(可能会有脏数据),在此仅供参考。测试时,对推特关联的用户数做了两种情况,一种是推特共关联了100个用户,也就是不同的推特也就是在100个用户内,这里的关联关系随机生成。另外一种是推特共关联了50万个用户,基本上50个用户的信息都会被查询出来。
在上文“准备”中可以看到关联数据生成方式。
hibernate:Java代码
long cnt = 100000;
for(long i = 1; i &= ++i){
Twitter t = (Twitter)session.get(Twitter.class, i);
t.getAddUser().getName();//加载相应字段
//System.out.println("t.getCtx="+ t.getCtx() + " t.getUser.getName=" + t.getAddUser().getName());
急懒加载配置更改处,Twitter.java:Java代码
@ManyToOne(fetch = FetchType.EAGER)//急加载
//@ManyToOne(fetch = FetchType.LAZY)//懒加载
@JoinColumn(name = "add_user_id")
public User getAddUser() {
return add_
mybatis:Java代码
for(long i = 1; i &= ++i){
Twitter t = (Twitter)msession.selectOne("getTwitterHasUser", i);
//System.out.println("t.getCtx="+ t.getCtx() + " t.getUser.getName=" + t.getCreateUserName());
TwitterMapper.xml配置:Xml代码
&select id="getTwitterHasUser" parameterType="long"
resultType="org.pushio.test.show1.entity.Twitter"&
select twitter.*,user.name as creteUserName from twitter,user
where twitter.id=#{id}
AND twitter.add_user_id=user.id
测试结果测试分析测试分成了插入,单表查询,关联查询。关联查询中hibernate分成三种情况进行配置。其中在关联字段查询中,hibernate在两种情况下,性能差异比较大。 都是在懒加载的情况下,如果推特对应的用户比较多时,则性能会比仅映射100个用户的情况要差很多。换而言之,如果用户数量少(关联的总用户数)时,也就是会重复查询同一个用户的情况下,则不需要对用户表做太多的查询。其中通过查询文档后,证明使用懒加载时,对象会以id为key做缓存,也就是查询了100个用户后,后续的用户信息使用了缓存,使性能有根本性的提高。甚至要比myBatis更高。如果是关联50万用户的情况下,则hibernate需要去查询50万次用户信息,并组装这50万个用户,此时性能要比myBatis性能要差,不过差异不算大,小于1ms,表示可以接受。其中hibernate非懒加载情况下与myBatis性能差异也是相对其他测试较大,平均值小于1ms。这个差异的原因主要在于,myBatis加载的字段很干净,没有太多多余的字段,直接映身入关联中。反观hibernate则将整个表的字都会加载到对象中,其中还包括关联的user字段。hibernate这种情况下有好有坏,要看具体的场景,对于管理平台,需要展现的信息较多,并发要求不高时,hibernate比较有优势。然而在一些小活动,互联网网站,高并发情况下,hibernate的方案太不太适合,myBatis+VO则是首选。测试总结总体初观,myBatis在所有情况下,特别是插入与单表查询,都会微微优于hibernate。不过差异情况并不明显,可以基本忽略差异。差异比较大的是关联查询时,hibernate为了保证POJO的数据完整性,需要将关联的数据加载,需要额外地查询更多的数据。这里hibernate并没有提供相应的灵活性。关联时一个差异比较大的地方则是懒加载特性。其中hibernate可以特别地利用POJO完整性来进行缓存,可以在一级与二级缓存上保存对象,如果对单一个对象查询比较多的话,会有很明显的性能效益。以后关于单对象关联时,可以通过懒加载加二级缓存的方式来提升性能。最后,数据查询的性能与orm框架关无太大的关系,因为orm主要帮助开发人员将关系数据转化成对象型数据模型,对代码的深析上来
看,hibernate设计得比较重量级,对开发来说可以算是重新开发了一个数据库,不让开发去过多关心数据库的特性,直接在hibernate基础上进
行开发,执行上分为了sql生成,数据封装等过程,这里花了大量的时间。然而myBatis则比直接,主要是做关联与输出字段之间的一个映射。其中sql
基本是已经写好,直接做替换则可,不需要像hibernate那样去动态生成整条sql语句。好在hibernate在这阶段已经优化得比较好,没有比myBatis在性能上差异太多,但是在开发效率上,可扩展性上相对myBatis来说好太多。最后的最后,关于myBatis缓存,hibernate查询缓等,后续会再专门做一篇测试。关于缓存配置myBatis相对Hibernate 等封装较为严密的ORM 实现而言,因为hibernate对数据对象的操作实现了较为严密的封装,可以保证其作用范围内的缓存同步,而ibatis 提供的是半封闭的封装实现,因此对缓存的操作难以做到完全的自动化同步。以上的缓存配置测试仅为性能上的分析,没有加入可用性上的情况,因为myBatis直接配置缓存的话,可能会出现脏数据,。在关联查询数据的情况下,hiberntae的懒加载配二级缓存是个比较好的方案(无脏数据),也是与myBatis相比有比较明显的优势。此情景下,性能与myBatis持平。在真实情况下,myBatis可能不会在这个地方上配置缓存,会出现脏数据的情况,因而很有可能在此hibernate性能会更好。
Hibernate没有你说的这么简单和方便,如果是很简单的增删改查,而且不牵涉到多表关联,Hibernate会是好的选择,但是这样的情况很少吧。我觉得HIbernate的有一下几个严重的缺点:1. 多表关联等比较复杂,使用的成本并不低2. 效率比较低,在大型项目中很少会使用到它,因为sql都是自动生成的,不太好进行人工的优化。调优需要丰富的经验,这些经验可能是需要被坑过很多次才知道等等吧
Hibernate写好实体类后,基本不需要做太多东西了,但是比较麻烦的是它的关联配置,很多时候是个难题,在就是查询语句自动生成不够灵活和高效,对一些dba不太友好。mybatis可控性比较好,你说的实体和映射以及配置文件可以通过官网提供的工具自动生成,学习成本相比hibernate要低很多。另外spring推出的spring data jpa跟hibernate相结合后虽然能解决查询灵活度问题,但是相对于mybatis来说还是不方便,建议你使用一下它们,自己就更能体会出其中的差异,从而在项目选型时,更贴近实际。
hibernate的门槛比较高.老实说,真的会用hibernate,并且能在产品里驾驭的人很少很少.___________补充一下,hibernate的sql是可控的。调优也和sql没有什么大区别。觉得关联查询控制不住的,是因为不太会用。
一遍看下来,没看到特别满意的答案,作为mybatis支持者我来写几句。首先是运行速度,hibernate是在jdbc上进行了一次封装,而mybatis基于原生的jdbc,因此mybatis天生就有运行速度上的优势。然后mybatis开放了插件接口。也许mybatis团队知道自己人少力单,索性把很多功能接口都开放了。不好分页?网上大神写的分页插件多得很;需要手写sql?按注解生成自动生成sql的插件早就有了;还有缓存的插件等等。可以说,只要肯在mybatis上花时间,你会发现orm这一块的所有问题它都有解决方案。这方面不是说hibernate不好,但是我还真没听说过hibernate有插件了。还有就是对遗留系统的支持。很多系统在设计之初还没有orm思想,现在想“抢救”一下,用mybatis就比hibernate更合适。因为mybatis可以很容易做到不规范的映射对象和规范的映射对象共存,如果这种系统中再需要增加个需要复杂sql的功能,mybatis只需要把sql手写出来,先把功能运行起来后再看看能不能变成自动生成的sql,而对hibernate来说就很困难了。
Hibernate理念不错,完全的ORMapping,MyBatis只是个SQL Mapper理想和现实是有差距的,把不是object的数据库结构映射,是一种leak abstractionHibernate用来做学校项目级别的不错,真正的项目一般都用mybatis,毕竟控制能力,调优成本更重要
hibernate在实际项目开发中,前期很顺利后期每个人都恨不得杀了hi
我的经验是主要看这3个指标来确定,第一个因素权重最大。1、数据量、有以下情况的最好就用MyBatis
如果有超过千万级别的表,
如果有单次业务大批量数据提交的需求(百万条及其以上的),这个尤其不建议用hibernate
如果有单次业务大批量数据读取需求(百万条及其以上的)2、表关联复杂度
如果主要业务表的关联表超过20个的(大概数量,根据表的大小不同有差异)不建议用hibernate3、人员
如果开发成员多数不是多年使用hibernate的情况(一般开发水平评估),建议使用MyBatis
刚刚spring-data-jpa 用就遇到两个问题:1,数据的分表用不了(select * from user_?%10 分了十个表,按id取模来决定查哪个表)
2.自带的过滤查询只支持常规的大小比较,不支持在字段上的运算(where propery*3=?
或者 propery&?!=0 ),感觉好不灵活,有大神指导吗
已有帐号?
无法登录?
社交帐号登录

我要回帖

更多关于 mybatis dao实现类 的文章

 

随机推荐