一个简单的MyBatis实例
在学习MyBatis之前,我们需要先了解一下传统的JDBC编程,整个过程分为以下几步;
1,使用JDBC编程需要连接数据库,注册驱动和数据信息;
2,操作Connection,打开Statement对象;
3,通过Statement执行SQL,返回结果到ResultSet对象;
4,使用ResultSet读取资源,然后通过代码转化为具体的POJO对象;
5,关闭数据库相关资源;
使用传统的JDBC方式存在一些弊端,其一,工作量相对较大,我们需要先连接,然后处理JDBC事务, 还要负责数据类型转换,操作Connection对象,Statement对象,其二,我们要对JDBC编程可能产生的异常进行捕捉和处理;
而作为改进版的ROM框架,则是将数据库中的表和简单的JAVA 对象进行映射,这样的话,我们就无需对数据库的相关知识深入了解,便可以写出通俗易懂的程序,ORM还提供了同一的规则使得数据库的数据通过配置便可轻易映射到POJO上;
而作为ORM框架中的经典框架:Hibernate和MyBatis,这篇主要讲一下MyBatist框架,先说明一下为什么要用MyBatis而不用Hibernate,Hibernate的缺点:
1,全表映射带来的不便,比如更新时需要发送所有的字段;
2,无法根据不同的条件组装不同的SQL;
3,对多表关联和复杂SQL查询支持较差,需要自己写SQL,返回后,需要自己将数据组装为POJO;
4,不能有效支持存储过程;
5,虽然有HQL,但是性能较差,大型互联网系统往往需要优化SQL,而Hibernate做不到;
总结:对复杂的查询支持较差,不支持存储过程,很难优化;
下面是关于MyBatis的一个简单实例;
1,首先,我们需要有一个SqlSessionFactory来实现生成一个SqlSession会话,相当于一个工厂,我们知道,作为数据库连接框架,不管如何,我们都需要有一个数据连接源,里面存储着连接这个项目的数据库的相关参数信息,然后,我们把这些信息配置在xml文件中,然后用一个SqlSessionFactoryUtils工具类去把信息配置到SqlSessionFactory中,也就是说,将SqlSessionFactoryUtils比作一个是工厂的话,那么参数信息就相当于工厂的位置信息了,
2,然后,我们还需要通过你这个SqlSessionFactory工厂类来创建一个SqlSession会话,这个会话相当于JDBC中的connection对象,用来将你在项目中的操作信息进行会话式的保存,以及最后的提交和关闭。
3,最后,我们说了,ORM是基于面向对象的编程,所以我们还要有一个对象映射器来将数据库的对象与POJO数据模型进行映射来达到ORM的效果,同时,我们还需要定义接口来对应映射器中的每一次SQL操作,而这个接口是不需要有实现类的,可以看作,通过xml配置的映射器其实已经转化为了这些接口的实现类,所以我们还需要一些对应关系,像是哪一个映射器对应哪一个接口,如果接口要传入参数,映射器也要有相应类型的参数,返回什么类型的参数这三个方面要做好对应关系;
废话不多说,直接上代码;
首先是数据库信息源配置信息;
mybatis-config.xml
<?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>
<typeAliases>
<typeAlias alias = "role" type = "com.learn.chapter2.po.Role"/>
</typeAliases>
<environments default = "development">
<environment id = "development">
<transactionManager type = "JDBC">
<property name = "autoCommit" value = "false"/>
</transactionManager>
<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 = "learn"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource = "com/learn/chapter2/mapper/roleMapper.xml"/>
</mappers>
</configuration>
下面这个是SqlSessionFactory类的底层实现原理;里面提到了如何通过SqlSessionFactory类创建SqlSession类;
public class SqlSessionFactoryUtil{
private static SqlSessionFactory sqlSessionFactory = null;
private static final Class CLASS_LOCK = SqlSessionFactoryUtil.class;
private SqlSessionFactoryUtil(){}
public static SqlSessionFactory initSqlSessionFactory(){
String resource = "mybatis-config.xml";
InputStream inputStream = null;
try{
inputStream = Resources.getResourceAsStream(resource);
}catch(IOException e){
Logger.getLogger(SqlSessionFactoryUtil.class.getName()).log(Level.SEVERE,null,ex);
}
synchronized(CLASS_LOCK){
if(sqlSessionFactory == null){
sqlSessionFactory = new SqlSessionFactoryBuilder().build(input Stream);
}
}
return sqlSessionFactory;
public static SqlSession openSqlSession(){
if(sqlSessionFactory == null){
initSqlSessionFactory();
}
return SqlSessionFactory.openSession();
}
}
}
接下来是一个POJO类,用来做映射用的;
public class Role{
private long id;
private String roleName;
private String note;
public Long getId(){
return id;
}
public void setId(Long id){
this.id = id;
}
public String getRoleName(){
return roleName;
}
public void setRoleName(String roleName){
this.roleName = roleName;
}
public String getNote(){
return note;
}
public void setNote(){
this.note = note;
}
}
接下来我们还需要一个映射器;RoleMapper.xml;
<?xml version = "1.0" encoding = "UTF-8">
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper.dtd">
<mapper namespace = "com.learn.chapter2.mapper.RoleMapper">
<select id = "getRole" parameterType = "long" resultType = "role">
select id ,role_name as roleName,note from t_role where id = #{id}
</select>
<insert id = "insertRole" parameterType = "role">
insert into t_role(role_name,note) values (#{roleName},#{note})
</insert>
<delete id = "deleteRole" parameterType = "long">
delete from t_role where id = #{id}
</delete>
</mapper>
然后,我们还需要一个接口,注意接口的方法要和XML映射文件的id保持一致;
public interface RoleMapper{
public Role getRole(Long id);
public int deleteRole(Long id);
public int insertRole(Role role);
}
而最后,我们只需要一个Main方法来调用整合就行了;
public class Chapter2Main{
public static void main(String[] args) throws Exception{
SqlSession sqlSession = null;
try{
sqlSession = SqlSessionFactoryUtils.openSqlSession();
//这里的RoleMapper.class是一个接口类来的;
RoleMapper roleMapper = sqlSession.getMapper(RoleMapper.class);
Role role = new Role();
role.setRoleName("testName");
role.setNote("testnote");
roleMapper.insertRole(role);
roleMapper.deleteRole(1L);
sqlSession.commit();
}catch(Exception e){
System.err.println(ex.getMessage());
sqlSession.rollback();
}
finally{
if(sqlSession != null)
sqlSession.close();
}
}
}
浙公网安备 33010602011771号