首先打个广告,我是一名Java架构师,每天都会分享我认为有价值的技术文章,感兴趣的朋友可以关注我,另外,文末有免费的技术资料领取
其实,一开始直接写SQL用JDBC去连数据库,简单且性能高。但是,随着集成开发对效率和模块化的追求,渐渐形成了框架,目前还在持续发展中。
正如,一开始人是吃生肉的,后来会烤肉,再发展出鲁、川、粤、苏、闽、浙、湘、徽八大菜系。Mybatis就正如粤菜,还保持一点原汁原味;Hibernate就像川菜,只看到辣椒,都看不到肉了。
分析问题,要从概念出发。
它山之石,可以攻玉。
做过一段时间的"无代码"开发,即用第三方图形工具进行编码,这些工具更能把概念形象化,以下带着一些问题,去寻找答案。
一、Hibernate和Mybatis,都在做什么?
我们先看看定义:
Hibernate对JDBC进行了非常轻量级的对象封装,它将POJO与数据库表建立映射关系,是一个全自动的ORM框架,hibernate可以自动生成SQL语句,自动执行。
MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。
所以,关键就是映射(Mapping),将一个数据结构映射到数据库中。
二、何谓数据结构?
1.在java的Hibernate,Mybatis中理解,数据结构我理解为Java Bean。有4个特点:
(1)公有的类
(2)私有属性
(3)提供公有的,不带参数的构造方法
(4)属性geter/seter封装
其实,创建不带参数的构造方法,只是为了方便在创建的时候,提供一个空的实例。
Student s = new Student();
而你也可以创建带1个,2个或更多参数的构造方法,你可以通过这个方法在创建对象时,先装填几个值,后面的值用set放进去。
Student s = new Student(1, "张三", "男", new Date(), "武当山");
s.setPicture(image);
2.换一个开发工具去理解数据结构
做过2个图形化软件的开发(Webmethods,Kettle),通过图形的拖拉完成程序的开发。两个工具都是基于Java开发的,所以能很形象地理解一些概念。以下,用Webmethods的图形,解释数据结构的概念:
(1)数据库映射成数据结构
如图,一个异常表。我们可以很方便地从主表到子表,层层关联,形成一个树状结构。
这个数据结构,不用多解释,你可以很形象得理解,一个数据结构就是一个document的图标,document中可以包含string,int,甚至是object,还可以是一个set<document>的集合。
往数据结构的赋值,与java就是geter,seter方法,而在图形中就是简单的拉线,可以拉一个或多个值。
(2)SAP Idoc映射成数据结构
IDOC是SAP R/3于SAP R/3或其他外部系统交换数据用过的文件格式,可以类似XML的格式存在。通过图形,我们可以很方便理解,数据如何从SAP,XML,数据结构一步步转换的。
(3)Flat File映射成数据结构
Flat File即平面文件,可以是txt,csv,json等,如下面的例子:
name:张三*sex:男*birth:1970-01-01*address:广东省+中山市+火炬区!
name:李四*sex:男*birth:1980-01-01*address:广东省+中山市+石歧区!
name:王五*sex:女*birth:1990-01-01*address:广东省+中山市+南朗镇!
记录中以(!)叹号分隔,字段以(*)星号分隔,子记录以(+)分隔,这样的格式和json差不多,体积小方便在网络传输。同样,我们可以为其定义一个数据结构,然后通过字段的分割,写入文档中的信息装入数据结构中。
(4)MIME映射成数据结构
MIME(Multipurpose Internet Mail Extensions)多用途互联网邮件扩展类型,在互联网传输的数据,都是用这个数据结构。它通过Content-type去识别是什么类型的数据:
•HTML文档标记:text/html;
•普通ASCII文档标记:text/html;
•JPEG图片标记:image/jpeg;
•GIF图片标记:image/gif;
•js文档标记:application/javascript;
•xml文件标记:application/xml;
也就是说,我们可以把任何形状的数据都放进一个数据结构中去,就像JSP页面的请求一样,只是处理的部分都被一些框架封装了,不用我们手工处理而已。
三、如何实现映射?
在Hibernate和Mybatis中,所谓映射,就是通过一些配置,把SQL查出来的字段名称和Java Bean的数据结构进行关联。
1.Hibernate例子
(1)建立JavaBean,和数据表
(2)建立数据库配置,及引入相关jar包
这里有个设定比较重要,当hbm2ddl.auto 为 create的时候,每次自动重建表。
<property name="hbm2ddl.auto">create</property>
(3)建立数据库与JavaBean关联
(4)实现功能
public class StudentTest {
private SessionFactory sessionFactory;
private Session session;
private Transaction transaction;
@Before
public void init() {
//创建服务注册对象,会直接去读配置文档
ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder().configure().build();
//创建会话工厂对象
sessionFactory = new MetadataSources(serviceRegistry).buildMetadata().buildSessionFactory();
//会话对象
session = sessionFactory.openSession();
//开启事物
transaction = session.beginTransaction();
}
@After
public void destory() {
//提交事物
transaction.commit();
//关闭会话
session.close();
//关闭会话工厂
sessionFactory.close();
}
@Test
public void testSaveStudents() {
//生成学生对象
Student student=new Student(1, "张三", "男", "中山");
session.save(student);
}
}
(5)改进
除了直接配置数据库字段与JavaBean关联外,还可以通过HQL和注解(Annotation)的方式实现关联。
•HQL
public void test01_seller() {
String hql = " from Seller ";
Query<Seller> query = session.createQuery(hql);
List<Seller> sellers = query.list();
for (Seller seller : sellers) {
System.out.println(seller);
}
}
•Annotation
@Entity
@Table(name = "T_Students03", schema = "demo")
public class Students03 {
@Id
@GeneratedValue(generator = "sid")
@GenericGenerator(name = "sid", strategy = "assigned")
@Column(length = 10)
private String sid;
@Column(length = 10)
private String name;
@Column(length = 10)
private String gender;
private Date birthday;
@Column(length = 10)
private String major;
@Embedded
private Address address;
...
2.mybatis例子
(1)建立JavaBean,和数据表
(2)建立数据库配置,及引入相关jar包
(3)建立数据库与JavaBean关联
这个关联比Hibernate要复杂一点,它是通过解析SQL的字段名称(可以是别名),来匹配JavaBean的字段。但是,要灵活很多,因为可以直接写SQL,可以使用很多高级的SQL算法,也方便调优。
(4)实现功能
在实现功能的时候,需要知道配置文件的路径,需要根据配置文件找到SQL所在的XML文件,需要根据XML文件找到对应的方法,所以命名空间等要设置好,思路要清晰。
而相对于hibernate来说,实现比较简单,这些都是由框架来实现,只要根据它提供的规则来做事即可。
(5)改进
观察以下代码:
comandlist = sqlSession.selectList("Command.queryCommandList",command);
Command和queryCommandList分别都是XML里面的配置信息,很容易写错,为了强化管理,还可以引入动态代理,接口式编程来完成,此处不再累述。
四、Hibernate和Mybatis,折射出何种逻辑?
1.全自动,还是半自动?
正如,开车一样,Hibernate是全自动,Mybatis是半自动,总有你喜欢的。
•场景要求。开自动挡的车,对技术的要求比较低,但是适合比较平坦的路面。
正如前面讲的4个场景,数据库对数据库的插入,SAP对数据库的插入,双方都是结构化的而且,尤其是对于SAP这么致密的数据库结构,很少改动。如果你需要用Java从SAP转换数据到Oracle,那用hibernate,开发是非常快的。
但是,如果遇到一些莫可名状的数据结构,为分析这些数据而建很多表,你的表结构有可能整天改,用mybatis比较合适,改SQL要方便一点。
•逻辑要求。Hibernate适合数据结构和数据库结构一对一的关联,如果想做ETL分析,数十张表在一起的,逻辑非常复杂,与其在Java bean建立多种关联关系,不如用Mybatis直接写SQL。
•性能要求。如果单表数据超过千万,还要进行表关联,就不适合把数据都抽出来让Java处理,而是把逻辑写入SQL,进行调优,这时用mybatis就比较合适。
(2)设计理念
这里引入,ASP.net中EF三种编程方式Database first ,Model first ,Code first,无谓谁好谁不好,还是要看场景。
•Database First:根据业务需求把表设计好,然后写逻辑,写代码,如早期银行的DB2数据库,信息固定,数据量大,数据库设计非常重要。Mybatis贴近这种模式。
•Model First:先把数据模型设计好,通过模型建表,再写代码。如ETL分析,先用PowerDesigner把数据仓库建好,字段错了马上改,马上更新数据库,数据可以删掉再抽取。
•Code First:先把代码写好,通过工具生成表。目前,ASP.NET就推荐这种模式,而Hibernate也贴近这种模式,业务逻辑优先,对数据库技术依赖少,而作为搞数据库出身的人,比较难接受。
(3)无代码,还是有代码?
近期,看到一篇文章说,为什么国外少用Mybatis,多用Hibernate。我们先看2款国外的软件,webmethods,kettle,他们都基于Java开发的可视化变成工具,都是用hibernate做数据操作的。为何?
因为,hibernate很方便就把数据库的字段对象,转化为业务流中的字段对象。而这些对象,又很容易和图形结合在一起,于是就形成无代码的拖拉式开发。
•webmethods
•Kettle
这要求对规范的恪守。而从实际上看,webmethods,kettle这两款软件,它们底层维持自身运作的数据库结构,经历多年的版本升级,几乎没变。
而国内的开发,数据库的搭建,对业务的梳理无章可循,喜欢拍脑袋,说改就改,所以用mybatis比较合适,但是,就出不了像SAP,Webmethods,Kettle这样的专业软件。
(4)趋于业务,还是趋于技术?
在无代码和有代码之后,战略布局的问题。
一个问题:Java开发难,还是SAP开发难?
我觉得是Java更难一点。因为SAP已经形成一套标准,开发人员更多的是从编程中解放出来,去思考业务逻辑的问题。只是,SAP的费用比较高。你想把钱花在软件上,还是花在培养人上。
而Java就是不停地重复造轮子,从零搭建系统。但Java的整个生态也在不断推进,从JSP+Servlet,生成Struts2这样的框架,大大加快了开发效率。
讲到最后,我觉得Hibernate是基于规则的编程,而Mybatis是基于配置的编程。你又喜欢哪个呢?
免费分享Java技术资料,关注我后在后台私信我即可免费获得你需要的Java技术资料
原文:https://zhuanlan.zhihu.com/p/74262926作者:白天不懂夜的黑来源:知乎
网友评论