1由来 |
是apache的一个开源项目iBatis,apache software foundation 迁移到了google code,并且改名为MyBatis 。2013年11月迁移到Github。
2是什么 |
是一个基于java的持久层框架,支持普通sql查询,存储过程和高级映射。MyBatis消除了几乎所有的JDBC代码和参数的手工设置以及对结果集的检索封装。MyBatis可使用简单的XML或注解用于配置和原始映射,将接口和java的映射成数据库中的记录
3什么时候用 |
当项目需求经常变时
4特点 |
- 专注sql本身,程序员可以自己编写sql语句,sql修改,优化比较方便
- 是一个不完全的ORM框架,虽然程序员自己写sql,但也实现了映射,如输入映射,输出映射
- 简单易学(亲身体会,比hibernate好学)
- 灵活(sql写在了xml文件中,便于管理和优化)
5配置文件讲解 |
1) SqlMapConfig.xml(MyBatis全局配置文件):
配置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>
<!-- 和spring整合后 environments配置将废除-->
<environments default="development">
<environment id="development">
<!-- 使用jdbc事务管理,事务控制由mybatis-->
<transactionManager type="JDBC" />
<!-- 数据库连接池,由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="sqlmap/User.xml"/>
</mappers>
</configuration>
【输入映射】
- properties属性:
- 将数据库连接参数单独配置在db.properties中,只需要在SqlMapConfig.xml中加载db.properties的属性值。在SqlMapConfig.xml中就不需要对数据库连接参数硬编码(注意属性加载顺序):
<properties resource="db.properties">
- 将数据库连接参数单独配置在db.properties中,只需要在SqlMapConfig.xml中加载db.properties的属性值。在SqlMapConfig.xml中就不需要对数据库连接参数硬编码(注意属性加载顺序):
- typeAliases(别名):分为单个别名定义,批量定义别名:如
<package name="cn.itcast.mybatis.po"/>
- typeHandlers(类型处理器):通常情况下,mybatis提供的类型处理器满足日常需要,不需要自定义
- mappers(映射配置):
- 通过resource加载单个映射文件:
<mapper resource="sqlmap/User.xml"/>
; - 通过mapper接口加载单个映射文件(规范:mapper接口类名和mapper.xml映射文件保持一致,且在同一个目录中,当然是使用了mapper代理方法):
<mapper class="cn.itcast.mybatis.mapper.UserMapper"/>
- 通过mapper 批量加载mapper:
<package name="cn.itcast.mybatis.mapper"/>
- 通过resource加载单个映射文件:
【输出映射】
- resultType
- resultMap
2) 映射文件 User.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">
<!-- namespace命名空间 -->
<mapper namespace="test">
<!-- 通过 select执行数据库查询 -->
<select id="findUserById" parameterType="int" resultType="cn.itcast.mybatis.po.User">
SELECT * FROM USER WHERE id=#{value}
</select>
<!-- 根据用户名称模糊查询用户信息,可能返回多条-->
<select id="findUserByName" parameterType="java.lang.String" resultType="cn.itcast.mybatis.po.User">
SELECT * FROM USER WHERE username LIKE '%${value}%'
</select>
<!-- 添加用户-->
<insert id="insertUser" parameterType="cn.itcast.mybatis.po.User">
<!-- 将插入数据的主键返回,返回到user对象中 -->
<selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer">
SELECT LAST_INSERT_ID()
</selectKey>
insert into user(username,birthday,sex,address) value(#{username},#{birthday},#{sex},#{address})
<!-- 使用mysql的uuid()生成主键 -->
<!-- <selectKey keyProperty="id" order="BEFORE" resultType="java.lang.String">
SELECT uuid()
</selectKey>
insert into user(id,username,birthday,sex,address) value(#{id},#{username},#{birthday},#{sex},#{address}) -->
</insert>
<!-- 删除 用户,根据id删除用户,需要输入 id值 -->
<delete id="deleteUser" parameterType="java.lang.Integer">
delete from user where id=#{id}
</delete>
<!-- 根据id更新用户 -->
<update id="updateUser" parameterType="cn.itcast.mybatis.po.User">
update user set username=#{username},birthday=#{birthday},sex=#{sex},address=#{address}
where id=#{id}
</update>
</mapper>
【讲解】
#{}
表示占位符;#{}中的参数可以是任意名称${}
表示拼接sql串,将接收到的参数值不叫任何修饰拼接到sql中,但使用拼接sql,会引起sql注入;如果输入参数值是简单类型,${}中只能使用value- 获取主键值:mysql自增主键,执行insert插入之后自动生成一个自增主键,通过SELECT LAST_INSERT_ID()得到主键,只适应与自增;mysql的uuid生成主键,执行insert插入之前自动生成一个自增主键,通过SELECT uuid()得到主键,将主键设置到user对象的id属性中,在insert执行时,从user对象中取出id
【输入映射】
- 传递基本属性
- 传递hashmap
- 传递pojo的包装对象
【输出映射】
- resultType
- resultMap
6MyBatis框架执行过程 |
- 引入MyBatis运行环境所依赖的jar包
- 配置MyBatis的配置文件,如SqlMapConfig.xml(名称不固定)
- 通过配置文件,加载MyBatis运行环境,创建SqlSessionFactory会话工厂(SqlSessionFactory使用单例模式生产)
// mybatis配置文件
String resource = "SqlMapConfig.xml";
// 得到配置文件流
InputStream inputStream = Resources.getResourceAsStream(resource);
// 创建会话工厂,传入mybatis的配置文件信息
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
- 通过SqlSessionFactory创建SqlSession(sqlsession是一个面向用户接[提供了操作数据库的方法]),实现对象是相称不安全的,建议sqlsession应用在方法体内[因为方法体内的私有变量会在栈中开辟新空间])
SqlSession sqlSession = sqlSessionFactory.openSession();
- 调用sqlsession的方法去操作数据库
//第一个参数:映射文件中statement的id,等于=namespace+"."+statement的id
// 第二个参数:指定和映射文件中所匹配的parameterType类型的参数
User user = sqlSession.selectOne("test.findUserById", 1);
查询:selectOne(id名,参数值)返回值接收类型:结果是与映射文件中匹配的resultType类型的对象,如果查询出一条结果(如根据主键查询),就用匹配的对象接收即可;如果返回多条对象,要用list<对象类型>接收
增加:sqlSession.insert("test.insertUser", user);
删除:sqlSession.delete("test.deleteUser", 39);
更新:sqlSession.update("test.updateUser", user);
(对象是配置文件中parameterType的类型,这是pojo对象)
- 释放资源,关闭sqlsessin
sqlSession.close();
7MyBatis开发DAO的方法 |
1) 原始DAO方法
- 需要程序员编写dao接口和实现类
- 需要在到到实现类注入SqlSessinFactory工厂
缺点:
- dao接口实现类出现大量的模板方法,如创建sqlSessionFactory,利用
sqlSessionFactory创建sqlSession - 调用sqlsession的方法是将statement的id硬编码了(因为id写死了)
- 调用sqlsession方法时传入的变量,由于sqlsession方法使用泛型object,所以在编码阶段如果传入的类型和prepareType不一致,也不会报错
2) mapper 代理开发方法
- 只需程序员编写mapper接口(可理解成dao接口)
但是编写mapper接口时就要遵循一些规范,这样mybatis就可自动生成mapper接口实现类代理对象,从而实现真正的执行操作,进行数据库操作:
规范:
- mapper.xml中namespace值等于mapper接口的地址
<mapper namespace="cn.itcast.mybatis.mapper.UserMapper">
- mapper.java接口中的方法名和mapper.xml中statement的id一致
- mapper.java接口中的方法输入参数类型和mapper.xml中statement的parameterType指定的类型一致
- mapper.java接口中的方法返回值类型和mapper.xml中statement的resultType指定的类型一致
优点:
- 解决了上面所说的原始DAO开发的缺点
- mapper接口的开发规范主要实现了对数据库操作的代码统一生成了:
User user = sqlSession.selectOne("test.findUserById", id);
sqlSession.insert("test.insertUser", user);
调用与实现变为了(省去了显示调用执行数据库的代码):
//创建UserMapper对象,mybatis自动生成mapper代理对象
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
//调用userMapper的方法
User user = userMapper.findUserById(1);
- 省去了接口实现类的编写