想必很多学习过hibernate的朋友们;都感觉到它的麻烦吧,而且学习的内容也特别的多;然而mybatis给我们带来了另一种体验;我们不再为hibernate中的关联关系、多表查询、到底是数据库还是实体类分不清而担忧了。我们只需要写出简简单单的SQL语句就OK了;
首先我们来看一下mybatis的主配置文件 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">
<!--
environments:用于配置多个数据环境
environment:是具体数据库的具体配置;包括数据连接信息和事务管理信息
transactionManager:事务管理器,mybatis有两种事务管理器(即:type="[JDBC|MANAGED]");
JDBC:直接使用jdbc控制事物。它依赖从数据源得到的连接来管理事物。
MANAGED:mybatis自己不负责控制事物,它会让spring或javaee服务器来管理事物的整个生命周期。
dataSource:数据源有三种:UNPOOLED、POOLED、JNDI
UNPOOLED:它实现每次请求简单打开和关闭连接。有点慢!
POOLED:采用连接池以避免创建新的连接实例时必要的初始连接和认证时间。这是当前web应用程序快速响应很流行的方式。
JNDI:它的实现是为了使用如spring或引用服务器。mybatis可以通过JNDI获取外部配置的数据源。
mappers:包含所有的mapper列表。让mybatis知道在哪儿找到SQL语句。
mapper:主要定义SQL映射文件。
<span style="white-space:pre"> </span>mybatis中别名的配置:
<span style="white-space:pre"> </span><typeAliases>
<span style="white-space:pre"> </span><typeAlias alias="Emp" type="cn.ygs.entity.Emp"/>
<span style="white-space:pre"> </span></typeAliases>
-->
<configuration>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="oracle.jdbc.driver.OracleDriver"/>
<property name="url" value="jdbc:oracle:thin:"/>
<property name="username" value="system"/>
<property name="password" value="orcl"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="cn/user/dao/EmpDaoMaper.xml"/>
</mappers>
</configuration>
下面我们在来看一下mapper.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">
<!--
首先:<!DOCTYPE mapper PUBLIC
"-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">一定要配置正确;
不然会报Error parsing SQL Mapper Configuration;这样的错误
mapper文件中就是写真删改查的SQL语句了;
语句中常见的一些属性:
id:命名空间的唯一标识符。可以别用来引用这条SQL语句;不能重复。
parameterType:语句中需要传入的参数类型的全限定名或别名例如:可以传入int 或者 Java.lang.Integer;
其中int就是 Java.lang.Integer的别名<span style="font-family: Arial, Helvetica, sans-serif;">(别名要在主配置文件中配置)</span>。
resultType:语句返回的结果类型的全限定名或别名。
resultMap:可以在mapper文件中的mapper里面创建resultMap标签。resultMap可以使用在很多复杂映射的情景中。
例如: <mapper namespace="cn.ygs.dao.EmpDao">
<resultMap type="cn.ygs.dao.EmpDao" id="queryMap">
<id property="empNo" column="empno"/>
<result property="empName" column="empname"/>
</resultMap>
说道这,我们又看到了resultMap中也有很多属性,那resultMap种的属性是什么含义和作用呢?
<span style="white-space:pre"> </span>property:数据库映射到实体类中的字段或属性的名称。
<span style="white-space:pre"> </span>column:从数据库中得到的列名
<span style="white-space:pre"> </span>JavaType:一个Java类的全限定名称或别名。
<span style="white-space:pre"> </span>jdbcType:在使用jdbc编程时,需要指定这个类型。
<select id="queryEmp" resultMap="queryMap">
select * from emp
</select>
</mapper>
注意:这儿SQL语句不能结束不能加“;”不然会报 java.sql.SQLSyntaxErrorException: ORA-00911: 无效字符的错误。
flushCache:默认值是false;执行语句调用后都会导致缓存清空。
useCache:将导致本条语句的结果缓存。默认值是true;值有查询语句中才用着属性
-->
<mapper namespace="cn.ygs.dao.EmpDao">
<select id="count" resultType="int" >
select count(*) from emp
</select>
<insert id="inertEmp" parameterType="cn.ygs.entity.Emp" flushCache="true" >
insert into emp(empno,ename) values(#{empno},#{ename})
</insert>
<select id="queryEmp" resultType="cn.ygs.entity.Emp">
select * from emp
</select>
</mapper>
下面,我们就来看一下mybatis是怎样实现业务操作的:
首先:我们定义一个接口:
public interface EmpDao {
//查询数据库中有多少条数据。
public int count();//count要和mapper.xml中的具体操作的语句的id一致。
}
然后:我们来实现这个接口
public class EmpDaoImpl implements EmpDao {
@Override
public int count() {
int count = 0;
SqlSession session = null;
try {
session = new SqlSessionFactoryBuilder().build(
Resources.getResourceAsReader("mybatis-config.xml"))
.openSession();
count = session.selectOne("cn.ygs.dao.EmpDao.count");
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
} finally {
if (session != null) {
session.close();
}
}
return count;
}
}
同时我们也可以得到一个empDao的代理类,代理类值通过jdk的动态代理实现的,主要定义接口及接口的方法;mybatis就会动态的实现EmpDao接口的代理,由代理解析XML,调用SQL;
所以;上面的放我们可以用代理类来实现:
@Override
public int count() {
int count = 0;
SqlSession session = null;
try {
session = new SqlSessionFactoryBuilder().build(
Resources.getResourceAsReader("mybatis-config.xml"))
.openSession();
EmpDao empDao = session.getMapper(EmpDao.class);
count = empDao.count();
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
} finally {
if (session != null) {
session.close();
}
}
return count;
}
这两个方法的到的结果都是一样的。