您的位置:首页 > 其它

mybatis第一个helloworld

2016-04-25 16:22 405 查看
hibernate和mybatis都是orm的框架,首先贴一波自己对于这两个框架的理解,如果有错误欢迎指正:
    使用hibernate可以轻松实现po类到数据库表的映射,而且hibernate封装了sql,将传统的数据库操作更加偏向于面向对象想,开发者在操作数据库时不需要对数据库知识有很多的了解,因为hibernate会自动生成sql语句,这是hibernate的优点同时也是他的缺点,毕竟框架是面向程序开发,考虑到的是大部分使用场景,不可能对于sql语句做很多的优化,但是如果开发者使用hibernate的方法执行自己的sql语句的话,这也不是不可以实现,但是也会和项目整体的架构会有冲突,这也就是hibernate失去了使用他的意义,而mybatis允许开发者使用自己的sql语句,而且用户可以自己调优.,而且hibernate在缓存方面的支持较mybatis更加丰富,hibernate还有自己得日志记录,而mybatis则需要使用第三方日志jar文件,常用的是log4j,个人认为,hibernate和mybatis的使用场景有很大差别,至于使用哪种,完全在于开发者来选择,至于目前软件开发领域极度鄙视ssh追捧springmvc+spring+mybatis,我觉得两者都是很好的框架,关键是在于使用场景,完成所需功能,其实使用哪种开发流程都是一样的.

下面在贴一波,别人关于hibernate和mybatis优缺点的描述:

著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

来源:知乎
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本身提供的缓存机制不佳。

个人觉得学习都要一个循序渐进的阶段,建议先学习mybatis,毕竟学习成本较低,而且官方有中文说明官方:说明地址:http://www.mybatis.org/mybatis-3/zh/getting-started.html

hibernate说明文档:就不贴了,很好找,直接百度即可

言归正传,第一个hibernate程序,由于我也刚学,网上也很少找到,mybatis关于数据库连接池的代码配置,这里就不贴,不使用数据库连接池了:

第一步:导入jar包:mybatis-3.2.3.jar,数据库驱动,这里采用的是MySQL数据库

第二步,编写po类和映射文件,可以使用映射文件操作数据库,也可使用接口实例实现操作:

po类:

package com.leige.domain;

public class Student {
private Integer sid;
private String name;
private Integer age;
setter..
getter...
}

sql映射文件:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--  命名空间就是实现sql的隔离,把对于一个对象的操作sql语句放在一个命名空间中
这里的调用查询就是Student.selectStudentById -->
<mapper namespace="Student">
<!--     按照sid查询数据库
注意在使用简单po类的简单名称时,前提是在configuration中配置了别名
<typeAliases>
<typeAlias alias="Student" type="com.leige.domain.Student"/>
</typeAliases>
-->
<select id="selectStudentById" parameterType="int" resultType="Student">
<![CDATA[
select * from student where sid = #{sid}
]]>

</select>
<select id="selectStudentByName" parameterType="java.lang.String" resultType="Student">
<!--     '%${value}%'表示字符串拼接,注意占位符的名称不能叫做po类的属性名,出了id除外,不然会报错
There is no getter for property named 'xxx' in 'class java.lang.String'
不过不建议使用,会产生sql注入
-->
<![CDATA[
select * from student where name like '%${value}%'
]]>

</select>

<!--    增加 -->
<insert id="insertStudent" parameterType="Student">
<!--     配置主键自增返回,必须和插入语句一起执行才能使用
order:表示语句相对于insert的执行顺序
resultType:返回结果类型,必须配置
mysql的函数SELECT LAST_INSERT_ID()可以查询 -->
<selectKey keyProperty="sid" order="AFTER" resultType="int">
<![CDATA[
SELECT LAST_INSERT_ID()
]]>
</selectKey>

<!--    非自增主键返回
<selectKey keyProperty="sid" order="AFTER" resultType="java.lang.String">
<![CDATA[
SELECT UUID()
]]>
</selectKey>
-->

<![CDATA[
insert into student(sid,name,age) values(#{sid},#{name},#{age})
]]>
</insert>

<!--   删除 -->
<delete id="deleteStudentById" parameterType="int">
<![CDATA[
delete from student where sid=#{sid}
]]>
</delete>

<!--   更新 -->
<delete id="updateStudent" parameterType="Student">
<![CDATA[
update student set name=#{name},age=#{age} where sid=#{sid}
]]>
</delete>
</mapper>


接口操作实例:
package com.leige.domain;

import java.util.List;

import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.SelectKey;
import org.apache.ibatis.annotations.Update;

public interface StudentMapper {
//id查找
@Select("select * from student where sid=#{sid}")
public Student selectStudent(Integer id);
//添加
@SelectKey(before=false,keyProperty="sid",statement="SELECT LAST_INSERT_ID()", resultType =int.class)
@Select("insert into student(sid,name,age) values(#{sid},#{name},#{age})")
public void addStudent(Student student);
//查找多个
@Select("select * from student where name like'%${value}%'")
public List<Student> selectStudentByName(String name);
//删除
@Delete("delete from student where sid=#{value}")
public void deleteStudentById(Integer sid);
//更新
@Update("update student set name=#{name},age=#{age} where sid=#{sid}")
public void update(Student student);
}


<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!-- 加载jdbcproperties
要写在configuration和environment之间
-->
<properties resource="com/leige/config/jdbcInfo.properties"></properties>
<!-- 别名声明,告诉mybatis,Student对应的类类型
使其能将Student这个字符和Student类对应起来
类型别名是为 Java 类型设置一个短的名字。它只和 XML 配置有关,存在的意义仅在于用来减少类完全限定名的冗余
即在任何需要使用com.leige.domain.Student的地方都可以使用Student
-->
<typeAliases>
<typeAlias alias="Student" type="com.leige.domain.Student"/>
</typeAliases>
<!-- 环境配置,数据库连接参数 -->
<environments default="development">
<environment id="development">

<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
</environments>

<!-- 将操作sql集合加入配置文件 -->
<mappers>
<mapper resource="com/leige/domain/StudentMapper.xml"/>
</mappers>
</configuration> jdbc配置参数:
driver=com.mysql.jdbc.Driver
url=jdbc\:mysql\:///test
username=root
password=
第三步编写工具类,减少代码,实现获取会话session和得到操作实例的功能:
package com.leige.test;

import java.io.IOException;
import java.io.InputStream;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Test;

/**
* @author sqlsession工具类
*
*/
public class SqlUtils {
static SqlSessionFactory factory;
//静态加载session工厂
static{
InputStream inputStream;
try {
inputStream = Resources.getResourceAsStream("com/leige/config/configuration.xml");
//1:实例化sqlsessionfactory工厂
factory= new SqlSessionFactoryBuilder().build(inputStream);
} catch (IOException e) {

}

}
public static SqlSession getSession() {
try{

//开启session
return factory.openSession();
}catch(Exception e){

throw new RuntimeException(e);
}
}
/**
* @param session
* @param mapper
* @return
* 保证会话session一致,所以当做参数传过来
*/
public static Object getmaMapper(SqlSession session,Class mapper){

//注册映射接口
factory.getConfiguration().addMapper(mapper);
//返回操作实例
return session.getMapper(mapper);
}

}


测试类:
package com.leige.test;

import java.io.InputStream;
import java.util.List;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Test;

import com.leige.domain.Student;
import com.leige.domain.StudentMapper;

public class App {
/**
* @throws 根据id查询单个对象
*/
@Test
public void fun() throws Exception{

InputStream inputStream=Resources.getResourceAsStream("configuration.xml");
//1:实例化sqlsessionfactory工厂
SqlSessionFactory factory= new SqlSessionFactoryBuilder().build(inputStream);
//2:注册接口
//factory.getConfiguration().addMapper(StudentMapper.class);
//3:开启session
SqlSession session=factory.openSession();
//4:1操作数据库有两种操作方式一种是,命名空间加命名语句执行
//System.out.println(session.selectOne("Student.selectStudent",1));

/*第二种是使用操作接口操作数据库
* 但是需要先注册接口,且接口需要用注解声明操作语句
* 即在接口上注册执行时所需要的语句@Select("select * from student where sid=#{id}")
* */
//注册接口
factory.getConfiguration().addMapper(StudentMapper.class);
//得到映射器实例
StudentMapper studentMapper=(StudentMapper) session.getMapper(StudentMapper.class);
//查询数据库
System.out.println(studentMapper.selectStudent(1));
session.close();

}
/**
* 测试查找多个
*/
@Test
public void testFindByName(){

try {
//通过工具类得到session
SqlSession session=SqlUtils.getSession();
List<Student> students=null;
//第一种方式:命名空间查找,也可以使用映射实例查找,selectList查找多个
// students=session.selectList("Student.selectStudentByName", "leige");
//第二种方式
StudentMapper mapper= (StudentMapper) SqlUtils.getmaMapper(session,StudentMapper.class);
students=mapper.selectStudentByName("leige");
//打印信息
for(Student stu:students)
System.out.println(stu);
} catch (Exception e) {
// TODO Auto-generated catch block
System.out.println(e);
}
}

/**
* 测试增加
*/
@Test
public void testInsert(){
//通过工具类得到session
SqlSession session=SqlUtils.getSession();
Student student=new Student();
student.setAge(22);
student.setName("leige3");

//第一種方式:执行插入,使用xml配置中sql参数
//session.insert("Student.insertStudent",student);
//第二種插入,使用接口文件中的sql参数
StudentMapper mapper=(StudentMapper) SqlUtils.getmaMapper(session, StudentMapper.class);
mapper.addStudent(student);
//输出返回的主键
System.out.println(student.getSid());
//注意查询的时候不需要提交,做增删改时需要提交才会生效
session.commit();
//关闭session
session.close();
}

/**
* 测试删除
*/
@Test
public void testDelete(){
//获得session
SqlSession session=SqlUtils.getSession();
//第一種方式:执行删除,使用xml配置中sql参数
session.delete("Student.deleteStudentById",12);
//第二種删除,使用接口文件中的sql参数
StudentMapper mapper=(StudentMapper) SqlUtils.getmaMapper(session, StudentMapper.class);
mapper.deleteStudentById(13);
//提交
session.commit();
//关闭
session.close();
}

/**
* 测试更新
*/
@Test
public void testupdate(){
//获得session
SqlSession session=SqlUtils.getSession();
//这里就不查询数据库了,直接修改得了
Student student=new Student();
student.setSid(1);
student.setAge(21);
student.setName("leige23");

//第一種方式:执行更新,使用xml配置中sql参数
//session.update("Student.updateStudent",student);
//第二中更新,使用接口文件中的sql参数
StudentMapper mapper=(StudentMapper) SqlUtils.getmaMapper(session, StudentMapper.class);
mapper.update(student);
//提交
session.commit();
//关闭
session.close();
}
}
创建数据库表,就不用说了
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: