1、Mybatis与hibernate的区别
Mybatis技术特点:
1、  通过直接编写SQL语句,可以直接对SQL进行性能的优化;
2、  学习门槛低,学习成本低。只要有SQL基础,就可以学习mybatis,而且很容易上手;
3、  由于直接编写SQL语句,所以灵活多变,代码维护性更好。
4、  不能支持数据库无关性,即数据库发生变更,要写多套代码进行支持,移植性不好。
Hibernate技术特点:
1、 标准的orm框架,程序员不需要编写SQL语句。
2、  具有良好的数据库无关性,即数据库发生变化的话,代码无需再次编写。
3、  学习门槛高,需要对数据关系模型有良好的基础,而且在设置OR映射的时候,需要考虑好性能和对象模型的权衡。
4、  程序员不能自主的去进行SQL性能优化。
关于mybatis执行原理,网上一搜一大堆,此篇博客只讲述使用以及配置!!!!
2、Mybatis基本配置
在介绍配置之前,先来看看工程的目录图(此后的文件很多,如果对不上了来看看目录图)
再来看看mybatis遇到的jar包
其中junit为测试包,junit以上为mybatis必须的jar包
2.1 全局配置(SqlMapConfig.xml)
与hibernate类似,mybatis的配置也存在全局配置文件
<?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>
	<!-- mybatis的环境配置,此信息在开发中只需照搬即可 -->
	<environments default="development">
		<environment id="development">
			<!-- 配置JDBC事务,此事务由mybatis管理 -->
			<transactionManager type="JDBC"></transactionManager>
			<!-- 配置连接池,此连接池为mybatis连接池 -->
			<dataSource type="POOLED">
				<property name="driver" value="com.mysql.jdbc.Driver"/>
				<property name="url" value="jdbc:mysql://localhost:3306/mybatis"/>
				<property name="username" value="root"/>
				<property name="password" value="root"/>
			</dataSource>
		</environment>
	</environments>
	
	
<!-- 映射文件 (加载所需要的局部配置)
	Mappers
		<mapper resource=’’/>
		使用相对于类路径的资源
		如:<mapper resource="sqlmap/User.xml" />
		<mapper url=’’/>
                     使用完全限定路径
		如:<mapper url="file:///D:\workspace_spingmvc\mybatis_01\config\sqlmap\User.xml" />
        <mapper class=’’/>
		使用mapper接口的全限定名
		如:<mapper class="com.sjg.dao.UserMapper"/>
		注意:此种方法要求mapper接口和mapper映射文件要名称相同,且放到同一个目录下;
		
		<package name=’’/>(推荐)
		注册指定包下的所有映射文件
		如:<package name="com.sjg.dao"/>
		注意:此种方法要求mapper接口和mapper映射文件要名称相同,且放到同一个目录下;
	-->
	<mappers>
		<mapper resource="config/User.xml"/>
		<package name="com.sjg.dao"/>
	</mappers>
</configuration>
<environment>是通用的“套路”,<mapper>是为了加载上面的局部配置
我们在测试类中使用mybatis时,通常使用以下的套路
public static void main(String[] args) throws Exception {
		
//获取xml文件的路径
		String resource = "config/SqlMapConfig.xml";
		
//配置路径
		InputStream inputStream = Resources.getResourceAsStream(resource);
		
		
//创建SqlSessionFactory
		SqlSessionFactory sqlFactory = 
				new SqlSessionFactoryBuilder().build(inputStream);
		
//创建SqlSession
		SqlSession sqlSession = sqlFactory.openSession();
		
		
/*
		 * 你想做的操作
		 * */
		
		sqlSession.close();
	}
2.2 Mybatis开发dao(dao包下的局部配置)
在介绍dao之前,必须先引入User的model(省略set/get方法)和数据表字段
package com.sjg.model;
import java.util.Date;
public class User {
	private Integer id;
	private String username;
	private String sex;
	private Date birthday;
	private String address;
在了解了基本的model和数据表之后,直接上相应的xml配置文件和相应的dao(也就是所谓的mapper映射文件)
UserMapper.xml
<?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">
<!-- mapper接口(UserMapper类)的全限定名要和mapper映射文件的namespace值一致。 -->
<mapper namespace="com.sjg.dao.UserMapper">
	
<!-- 
		mapper接口的方法名称要和mapper映射文件的statement的id一致。
		mapper接口的方法参数类型要和mapper映射文件的statement的parameterType的值一致,而且它的参数是一个。
		mapper接口的方法返回值类型要和mapper映射文件的statement的resultType的值一致。
	 -->
	<select id="getUserById" parameterType="int" resultType="com.sjg.model.User">
		SELECT
		* FROM USER WHERE id =#{id}
	</select>
	
<!-- 添加用户 -->
	<!-- selectKey:查询主键,在标签内需要输入查询主键的sql -->
	<!-- order:指定查询主键的sql和insert语句的执行顺序,相当于insert语句来说,对于
			    此时先进行插入,再获得主键,逻辑上也是成立的 -->
	<!-- LAST_INSERT_ID:该函数是mysql的函数,获取自增主键的ID,它必须配合insert语句一起使用 -->
	<insert id="insertUser" parameterType="com.sjg.model.User">
		<selectKey keyProperty="id" resultType="int" order="AFTER">
			SELECT
			LAST_INSERT_ID()
		</selectKey>
		INSERT INTO USER
		(username,birthday,sex,address)
		VALUES(#{username},#{birthday},#{sex},#{address})
	</insert>
	
<!-- 	#{}和${}
		#{}表示占位符?,#{}接收简单类型的参数时,里面的名称可以任意
		${}表示拼接符,${}接收简单类型的参数时,里面的名称必须是value
		${}里面的值会原样输出,不加解析(如果该参数值是字符串,有不会添加引号)
		${}存在sql注入的风险,但是有些场景下必须使用,比如排序后面会动态传入排序的列名
	 -->
</mapper>
UserMapper
package com.sjg.dao;
import com.sjg.model.User;
//注意定义的是接口,此类为所谓的Mapper接口
public interface UserMapper {
	
//插入一个学生的信息,方法名要与UserMapper.xml中的insert标签的id相一致
	void insertinsertUser();
	
//查询某个学生的信息,方法名要与UserMapper.xml中的select标签的id相一致
	User getUserById();
}
测试类
	public static void main(String[] args) throws Exception {
		//获取xml文件的路径
		String resource = "config/SqlMapConfig.xml";
		//配置路径
		InputStream inputStream = Resources.getResourceAsStream(resource);
		
		//创建SqlSessionFactory
		SqlSessionFactory sqlFactory = 
				new SqlSessionFactoryBuilder().build(inputStream);
		//创建SqlSession
		SqlSession sqlSession = sqlFactory.openSession();
		//获得相应的mapper映射文件
		UserMapper dao = sqlSession.getMapper(UserMapper.class);
		//取得id为1的用户信息
		User user = dao.getUserById(1);
		System.out.println(user);
		/*id=1, username=jack, sex=1, 
		 * birthday=Wed Apr 25 00:00:00 CST 2018, address=政府
		 */
		
		User user1 = new User();
		user1.setUsername("eee");
		
		dao.insertUser(user1);
		//提交事务
		sqlSession.commit();
		sqlSession.close();
	}
}
在数据库中也是成功插入了,在此就不截图了。
如果想进行更多的基本操作,只需要仿照xml中的配置,写入相应的select或者insert等等语句,进行测试和使用
3.Mybatis的一对一、一对多、多对多
与hibernate一样,持久层的框架都离不开上述三个关系,mybatis给出了一个特别好的解决办法,就是在xml文件中加入<resultMap>标签,这个标签十分强大,利用xml文件具有标签中套有标签,层次性非常强的特点,将上述三种关系完美的表达出来,具体使用在例子中进行详细的讲解。
3.1 一对一
我们举个例子,学生和学生对应的学生号,是一一对应的。当然,在讲述之前,先列出model(无set/get)和数据表
StudentInfo(model)
package com.sjg.model;
public class StudentInfo {
	private Integer studentId;
	private String card;
student_info(表)
Student(model)
package com.sjg.model;
import java.util.List;
public class Student {
	private Integer studentId;
	private String studentName;
	private Integer age;
	private Integer classId;
	
	private StudentInfo stuInfo;//此为一对一的关键
student(表)
重点在于两个xml配置文件
StudentDao.xml
<?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" > 
<mapper namespace="com.sjg.dao.StudentDao">
	
<!-- 
		id:这个resultMap的id,便于其他标签引用
		type:输入指定的model全限定名(student中的字段包含了studentInfo)
		那么以student为主,自然type填写student
	 -->
	<resultMap type="com.sjg.model.Student" id="StudentMap">
		
<!-- id标签为相应的id字段
			 result为model对应的属性名称	
			 property:model中的字段
			 column:数据表中的对应字段
		 -->
		<id property="studentId" column="student_id"/>
		<result property="studentName" column="stu_name"/>
		<result property="age" column="age"/>
		<result property="classId" column="class_id"/>
		
<!-- association标签表示一对一引用的另一个对象
			 即student这个model中的stuInfo字段要对应的内容
			 resultMap:引用了StudentInfoDao.xml中的StudentInfoMap这个resultMap
		 -->
		<association property="stuInfo" resultMap="com.sjg.dao.StudentInfoDao.StudentInfoMap"></association>
	</resultMap>
	
	
<!-- resultMap:引用了上面的resultMap,与其id对应
		其他的已经解释过,sql语句不解释		
	 -->
	<select id="selectAllStudent" resultMap="StudentMap">
		SELECT  
        t.student_id,  
        t.stu_name,  
        t.age,  
        t.class_id,  
        t2.card  
        FROM student t  
        LEFT JOIN student_info t2 ON t.student_id = t2.student_id
	</select>
</mapper>
StudentInfo.xml
<?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" > 
<mapper namespace="com.sjg.dao.StudentInfoDao">
	<resultMap id="StudentInfoMap" type="com.sjg.model.StudentInfo">
		<id property="studentId" column="student_id"/>
		<result property="card" column="card"/>
	</resultMap>
	
	<select id="getStudentInfo" parameterType="java.lang.Integer" resultMap="StudentInfoMap">
		SELECT
		t.student_id
		t.card
		FROM student_info t
		WHERE t.student_id = #{studentId}
	</select>
</mapper>
最后,列出相应的dao文件
StudentDao
package com.sjg.dao;
import java.util.List;
import com.sjg.model.Student;
public interface StudentDao {
	
//方法名与StudentDao.xml中select标签的id一致,此后不再提示
	List<Student> selectAllStudent();
}
测试类
	public static void main(String[] args) throws Exception {
		//获取xml文件的路径
		String resource = "config/SqlMapConfig.xml";
		//配置路径
		InputStream inputStream = Resources.getResourceAsStream(resource);
		
		//创建SqlSessionFactory
		SqlSessionFactory sqlFactory = 
				new SqlSessionFactoryBuilder().build(inputStream);
		//创建SqlSession
		SqlSession sqlSession = sqlFactory.openSession();
		//获得相应的mapper映射文件
		StudentDao dao = sqlSession.getMapper(StudentDao.class);
		//取得id为1的用户信息
		List<Student> list = dao.selectAllStudent();
		System.out.println(list);
		/*
		 * [
studentId=10001, studentName=张三, age=20, classId=1001, stuInfo=studentId=10001, 
card=12345
, 
studentId=10002, studentName=李四, age=21, classId=1001, stuInfo=studentId=10002, 
card=54321
, 
studentId=10003, studentName=王五, age=22, classId=1002, stuInfo=studentId=10003, 
card=23233
]
		 * */
		
		sqlSession.close();
	}
}
可以看出,我们查出了StudentInfo中的card
3.2 一对多
我们假设一个同学只能选择一门课程,那么对于课程来说,就是“一”,而学生就是“多”
Classes(model)
package com.sjg.model;
import java.util.List;
public class Classes {
	private Integer classId;
	private String className;
	
	private List<Student> studentList;//一对多的关键
classes(表)
student的model和表参考上面给出的
重点依旧是xml文件的配置
ClassesDao.xml
<?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" > 
<mapper namespace="com.sjg.dao.ClassesDao">
	<!-- collection : 用于一对多和多对多
		 association : 用于一对一
		  其他属性都一致,仔细观察就能发现collection与Student的model中的字段一致
		  在这里就能很明显的看出,利用xml文件的层次结构体现了一对多以及下面会出现的多对多
		 的关系
	-->
	<resultMap type="com.sjg.model.Classes" id="ClassesMap">
		<id property="classId" column="class_id"/>
		<result property="className" column="class_name"/>
		<!-- ofType:collection标签内的model类全限定名
			 studentList里面当时就是student类型咯
			 column="关联主键ID(用于嵌套查询SQL语句传入参数,多个用逗号分开)" 
		 -->
		<collection property="studentList" ofType="com.sjg.model.Student" column="classesId">
			<id property="studentId" column="student_id"/>
			<result property="studentName" column="stu_name"/>
			<result property="age" column="age"/>
			<result property="classId" column="class_id"/>
			<association property="stuInfo" 
				resultMap="com.sjg.dao.StudentInfoDao.StudentInfoMap">
			</association>
		</collection>
	</resultMap>
	
	<select id="selectAllClasses" resultMap="ClassesMap">
		SELECT  
        t.student_id,  
        t.stu_name,  
        t.age,  
        t.class_id,  
        t2.class_name 
        FROM student t  
        LEFT JOIN classes t2 ON t.class_id = t2.class_id
	</select>
</mapper>
测试类
	public static void main(String[] args) throws Exception {
		//获取xml文件的路径
		String resource = "config/SqlMapConfig.xml";
		//配置路径
		InputStream inputStream = Resources.getResourceAsStream(resource);
		
		//创建SqlSessionFactory
		SqlSessionFactory sqlFactory = 
				new SqlSessionFactoryBuilder().build(inputStream);
		//创建SqlSession
		SqlSession sqlSession = sqlFactory.openSession();
		//获得相应的mapper映射文件
		ClassesDao dao = sqlSession.getMapper(ClassesDao.class);
		//取得id为1的用户信息
		List<Classes> list = dao.selectAllClasses();
		System.out.println(list);
		/*
		 * [classId=1001, className=语文, studentList=[
studentId=10001, studentName=张三, age=20, classId=1001, stuInfo=studentId=10001, card=null
, 
studentId=10002, studentName=李四, age=21, classId=1001, stuInfo=studentId=10002, card=null
], classId=1002, className=数学, studentList=[
studentId=10003, studentName=王五, age=22, classId=1002, stuInfo=studentId=10003, card=null
]]
		 * */
		
		sqlSession.close();
	}
}
结果与数据库结果相一致
3.3 多对多
一个老师可以有多个学生,一个学生也可以有多个老师,体现多对多的关系,中间还需要一个中间表
在多对多先列出数据表
teacher(表)
ts_relation(关系表)
student的依旧参考上面的
认清了表之后,我们来看一下model
Teacher(model)
package com.sjg.model;
import java.util.List;
public class Teacher {
	private Integer teacherId;
	private String teacherName;
	
	private List<Student> stuList;//多对多TSRelation(model)
package com.sjg.model;
public class TSRelation {
	private Teacher teacher;
	private Student student;Student(model)
 package com.sjg.model;
import java.util.List;
public class Student {
	private Integer studentId;
	private String studentName;
	private Integer age;
	private Integer classId;
	
	private StudentInfo stuInfo;
	private List<Teacher> teacherList;//多对多可以看到,多对多就是在一对多的基础上,在“一”的那一方加入了相应的集合元素
 重点还是在xml
 
 
TeacherDao.xml
<?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" > 
<mapper namespace="com.sjg.dao.TeacherDao">
	<resultMap type="com.sjg.model.Teacher" id="TeacherMap">
		<id property="teacherId" column="teacher_id"/>
		<result property="teacherName" column="tea_name"/>
		<collection property="stuList" ofType="com.sjg.model.Student">
			<id property="studentId" column="student_id"/>
			<result property="studentName" column="stu_name"/>
			<result property="age" column="age"/>
			<result property="classId" column="class_id"/>
			<association property="stuInfo" 
				resultMap="com.sjg.dao.StudentInfoDao.StudentInfoMap">
			</association>
		</collection>
	</resultMap>
	
	<select id="selectAllTeacher" resultMap="TeacherMap">
		select
		t.teacher_id,
        t.tea_name,
        s.student_id,
        s.stu_name,
        s.class_id,
        s.age
        from
        teacher t, student s, ts_relation ts
        where t.teacher_id = ts.tea_id
        and s.student_id = ts.stu_id
	</select>
</mapper>
和一对多很相似,那么接下来进行测试
测试类
	public static void main(String[] args) throws Exception {
		//获取xml文件的路径
		String resource = "config/SqlMapConfig.xml";
		//配置路径
		InputStream inputStream = Resources.getResourceAsStream(resource);
		
		//创建SqlSessionFactory
		SqlSessionFactory sqlFactory = 
				new SqlSessionFactoryBuilder().build(inputStream);
		//创建SqlSession
		SqlSession sqlSession = sqlFactory.openSession();
		//获得相应的mapper映射文件
		TeacherDao dao = sqlSession.getMapper(TeacherDao.class);
		//取得id为1的用户信息
		List<Teacher> list = dao.selectAllTeacher();
		System.out.println(list);
		/*
		 * [teacherId=1, teachername=张老师, stuList=[
studentId=10001, studentName=张三, age=20, classId=1001, stuInfo=studentId=10001, card=null
, 
studentId=10002, studentName=李四, age=21, classId=1001, stuInfo=studentId=10002, card=null
, 
studentId=10003, studentName=王五, age=22, classId=1002, stuInfo=studentId=10003, card=null
], teacherId=2, teachername=李老师, stuList=[
studentId=10001, studentName=张三, age=20, classId=1001, stuInfo=studentId=10001, card=null
, 
studentId=10003, studentName=王五, age=22, classId=1002, stuInfo=studentId=10003, card=null
]]
		 * */
		
		sqlSession.close();
	}
}
此时输出结果以老师的角度来看各个老师又多少个学生,如果想从学生的角度来看有多少老师,只需要更改一下xml文件中的resultMap标签中的内容即可
修改后的Teacher.xml
<?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" > 
<mapper namespace="com.sjg.dao.TeacherDao">
	<resultMap type="com.sjg.model.Student" id="TeacherMap">
		<id property="studentId" column="student_id"/>
		<result property="studentName" column="stu_name"/>
		<result property="age" column="age"/>
		<result property="classId" column="class_id"/>
		<collection property="teacherList" ofType="com.sjg.model.Teacher">
			<id property="teacherId" column="teacher_id"/>
			<result property="teacherName" column="tea_name"/>
		</collection>
	</resultMap>
	
	<select id="selectAllTeacher" resultMap="TeacherMap">
		select
		t.teacher_id,
        t.tea_name,
        s.student_id,
        s.stu_name,
        s.class_id,
        s.age
        from
        teacher t, student s, ts_relation ts
        where t.teacher_id = ts.tea_id
        and s.student_id = ts.stu_id
	</select>
</mapper>
测试类
	public static void main(String[] args) throws Exception {
		//获取xml文件的路径
		String resource = "config/SqlMapConfig.xml";
		//配置路径
		InputStream inputStream = Resources.getResourceAsStream(resource);
		
		//创建SqlSessionFactory
		SqlSessionFactory sqlFactory = 
				new SqlSessionFactoryBuilder().build(inputStream);
		//创建SqlSession
		SqlSession sqlSession = sqlFactory.openSession();
		//获得相应的mapper映射文件
		TeacherDao dao = sqlSession.getMapper(TeacherDao.class);
		//取得id为1的用户信息
		List<Teacher> list = dao.selectAllTeacher();
		System.out.println(list);
		/*
		 * [
studentId=10001, studentName=张三, age=20, classId=1001, stuInfo=null
,teacherList=[teacherId=1, teachername=张老师, stuList=null, teacherId=2, teachername=李老师, stuList=null], 
studentId=10002, studentName=李四, age=21, classId=1001, stuInfo=null
,teacherList=[teacherId=1, teachername=张老师, stuList=null], 
studentId=10003, studentName=王五, age=22, classId=1002, stuInfo=null
,teacherList=[teacherId=2, teachername=李老师, stuList=null, teacherId=1, teachername=张老师, stuList=null]
]
		 */
		
		sqlSession.close();
	}
}
4.总结
至此,mybatis最基本的使用和配置已经介绍完毕了,mybatis的使用和细节还有很多,在实际开发中遇到了才会知道。关于mybatis的缓存,有精力了再往下写一些,本篇侧重于最基本的使用和配置。
如需转载请注明出处。
Mybatis官方技术文档:点击打开链接
  http://www.mybatis.org/mybatis-3/zh/sqlmap-xml.html