1.Hibernate和Mybatis简单对比
Hibernate
适用于需求变化不大的中小型项目,比如:后台管理系统,ERP,OA系统等。适用于数据库变更频繁,或者要求支持多数据库的情况。
出现bug调试时,要求技术人员对Hibernate有较深的立即。
Mybatis:
适用于需求变化较多的项目,比如新出的系统等。
适合于性能要求,数据库单一的情况。
框架简单,出问题好修改,要求开发人员对sql有掌握。
2.使用Mybatis利用传统DAO开发的问题
1. SqlSession是线程不安全的,只能作为局部变量使用,DAO实现方法中存在大量的重复代码,获取sqlSession,关闭sqlSession等。2.调用sqlSession执行SQL操作时,将statement的ID直接写到代码中。硬编码不利于维护。
3.调用sqlSession方法时传入的变量是Object泛型参数,在编译阶段不会报错。
3.使用Mapper代理
Mapper代理方法规范总结:1.xxxMapper.xml中namespace必须是xxxMapper.java的全类名。
2.xxxMapper.xml中Statement的id需要和xxxMapper.java中方法名保持一致。
3.xxxMapper.xml中statement的parameterType指定输入参数的类型和xxxMapper.java的方法输入参数类型保持一致。
4.xxxMapper.xml中的statement的resultType指定的类型和xxxMapper.java的方法返回值类型一致。
sqlMapConfig.xml 整体环境配置,mapper文件指定
<?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>
<!-- 与Spring整合后environment将不需要再配置 -->
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/high"/>
<property name="username" value="root"/>
<property name="password" value="1234"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="mapper/studentMapper.xml"/>
</mappers>
</configuration>
Mapper接口根据一定的规范,通过对应的mapper.xml映射文件来自动实现代理对象。通过以下两个步骤实现:
1)编写mapper.xml
规则:配置文件中的mapper的namespace必须是mapper接口的全类名。
2)编写mapper接口
mapper接口中的方法名必须是配置文件中定义的statement id,接口方法的参数类型必须是配置文件中指定的parameterType返回值类型必须是resultType的类型。
studentMapper.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="dao.StudentMapper">
<!-- id可以理解为标识sql statement的唯一标识 -->
<!--
MyBatis中占位符的表达方式同SpringMVC的EL表达式类似,#{}中可以使用任意的形参。
resultType指定需要映射的类型。
-->
<select id="findStudentByName" parameterType="String" resultType="mybatis.Student">
select * from student where name = #{value}
</select>
<!-- 注意 parameterType仍然是Student,通过ONGL来解析对应的属性 -->
<!-- selectKey 将插入操作生成的自增主键值设定到parameterType的属性中。 -->
<insert id="insertStudent" parameterType="mybatis.Student">
<selectKey keyProperty="id" order="AFTER" resultType="int">
select last_insert_id();
</selectKey>
insert into student(name, age) values(#{name}, #{age});
</insert>
<update id="updateStudent" parameterType="mybatis.Student">
update student set name=#{name} where id=#{id};
</update>
<delete id="deleteStudentById" parameterType="java.lang.Integer">
delete from student where id=#{id};
</delete>
</mapper>
StudentMapper.java 根据studentMapper.xml中定义的statement语句来写Mapper接口
package dao;
import java.util.List;
import mybatis.Student;
//注意Mapper方法中的参数只能有一个,如果有多种数据时,可以通过POJO进行包装一个。
//即定义一个类,专门用来作为参数,这个参数的属性就是想操作的数据。
public interface StudentMapper {
public List<Student> findStudentByName(String name) throws Exception;
public void insertStudent(Student student) throws Exception;
public void updateStudent(Student student) throws Exception;
public void deleteStudentById(int id) throws Exception;
}
接口写完后,可以通过MyBatis自动生成代理类。这样不需要手动些Impl类,即可直接使用。
MybatisTest.java
package mybatis;
import java.io.IOException;
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 dao.StudentMapper;
public class MybatisTest {
public static void main(String[] args) throws IOException{
//指定mybatis的配置文件
InputStream is = Resources.getResourceAsStream("sqlMapConfig.xml");
//得到 SqlSessionFactory接口引用 用来创建SqlSession接口引用
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
SqlSession sqlSession = sqlSessionFactory.openSession(true);
StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);
Student forInsert = new Student(0, "Lucy", 20); //追加新用户Lucy,Id自动生成
Student forUpdate = new Student(33, "Lily", 20); //将ID为33的学生,更名为Lily
try {
studentMapper.insertStudent(forInsert); //插入数据
studentMapper.deleteStudentById(22); //删除ID为22的数据
studentMapper.updateStudent(forUpdate); //将ID为forUpdate的数据的名字更新为forUpdate的名字。
List<Student> list = studentMapper.findStudentByName("Lily"); //查询
System.out.println(list);
} catch (Exception e) {
e.printStackTrace();
}
}
}
<完>