1、Mybatis框架的介绍
MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis 。2013年11月迁移到Github。
MyBatis是一个优秀的持久层框架,它对jdbc的操作数据库的过程进行封装,使开发者只需要关注 SQL 本身,而不需要花费精力去处理例如注册驱动、创建connection、创建statement、手动设置参数、结果集检索等jdbc繁杂的过程代码。
Mybatis通过xml或注解的方式将要执行的各种statement(statement、preparedStatemnt、CallableStatement)配置起来,并通过java对象和statement中的sql进行映射生成最终执行的sql语句,最后由mybatis框架执行sql并将结果映射成java对象并返回。
2、Mybatis基于Mapper动态代理的方式实现DAO层
用Mapper动态代理的方式实现DAO层有点类似于spring data JPA的方式,都只需要写一个接口,在接口中写操作数据库的方法就可以,不同的是Mapper接口中的方法需要搭配配置文件中的sql语句生成一个动态代理对象,这个对象由底层自动生成,而程序员只需要配置接口对应的xxxMapper.xml文件就可以了。
2.1 XXXMapper.xml(映射文件)的配置
- Mapper.xml文件中的namespace与mapper接口的类路径相同。
- Mapper接口方法名和Mapper.xml中定义的每个statement的id相同
- Mapper接口方法的输入参数类型和mapper.xml中定义的每个sql 的parameterType的类型相同
- Mapper接口方法的输出参数类型和mapper.xml中定义的每个sql的resultType的类型相同
<?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是命名空间,作用sql语句的隔离,后面还有重要作用
#{}作用就是占位符,相当于jdbc的“?”
parameterType:查询的参数类型
resultType:查询结果的数据类型,如果是pojo应该给全路径。
-->
<!-- mapper代理的开发规则:
1、namespace必须时候接口的全限定名
2、Statementid必须和接口的方法名称一致
3、接口方法的参数类型要和parameterType要一致
4、接口方法的返回值类型要和resultType一致
-->
<mapper namespace="com.liu.usermapper.UserMapper">
<!-- 别名不区分大小写 -->
<select id="getUserById" parameterType="int" resultType="USer">
SELECT * FROM `user` WHERE id=#{id};
</select>
<!-- 如果查询结果返回list, resultType设置为list中一个元素的数据类型
${}字符串拼接指令
-->
<select id="getUserByName" parameterType="string" resultType="cn.itheima.mybatis.po.User">
SELECT * FROM `user` WHERE username LIKE '%${value}%'
</select>
<!-- 参数是pojo时,#{}中的名称就是pojo的属性 -->
<insert id="insertUser" parameterType="cn.itheima.mybatis.po.User">
<!-- keyProperty:对于pojo的主键属性
resultType:对应主键的数据类型
order:是在insert语句执行之前或者之后。
如果使用uuid做主键,应该先生成主键然后插入数据,此时应该使用Before
-->
<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>
</mapper>
2.2 Mapper接口
public interface UserMapper {
User getUserById(Integer id);
List<User> getUserByName(String name);
void saveUser(User user);
}
2.3 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>
<!-- 配置属性
先加载内部属性,再加载外部属性,如果有同名属性会覆盖。
-->
<properties resource="db.properties">
<property name="jdbc.driver" value="com.mysql.jdbc.Driver"/>
<property name="jdbc.url" value="jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8"/>
<property name="jdbc.username" value="root"/>
<property name="jdbc.password" value="jiangyan"/>
</properties>
<!-- 配置pojo别名 -->
<typeAliases>
<!-- 别名不区分大小写 -->
<!-- <typeAlias type="cn.liu.mybatis.po.User" alias="user"/> -->
<!-- 扫描包的形式创建别名,别名就是类名,不区分大小写 -->
<package name="cn.liu.mybatis.po"/>
</typeAliases>
<!-- 和spring整合后 environments配置将废除-->
<environments default="development">
<environment id="development">
<!-- 使用jdbc事务管理-->
<transactionManager type="JDBC" />
<!-- 数据库连接池-->
<dataSource type="POOLED" >
<property name="driver" value="${jdbc.driver}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</dataSource>
</environment>
</environments>
<!-- 加载mapper文件 -->
<mappers>
<!-- resource基于classpath查找
<mapper resource="sqlmap/user.xml"/>
<mapper resource="mapper/mapper.xml"/> -->
<!-- 根据接口名称加载mapper文件
要求:1、mapper映射文件和接口在同一个目录下
2、mapper映射文件的名称和接口名称一致。
3、class就是接口的全限定名
-->
<!-- <mapper class="cn.liu.mybatis.mapper.UserMapper"/> -->
<!-- 使用扫描包的形式加载mapper文件【推荐使用】
要求:1、mapper映射文件和接口在同一个目录下
2、mapper映射文件的名称和接口名称一致。
-->
<package name="cn.liu.mybatis.mapper"/>
</mappers>
</configuration>
在mybatis的配置文件中,配置mapper映射文件有三种方式:
(1)<mapper resource=" " />
使用相对于类路径的资源
如:<mapper resource="sqlmap/User.xml" />
(2)<mapper class=" " />
使用mapper接口类路径
如:<mapper class="cn.itcast.mybatis.mapper.UserMapper"/>
注意:此方式需要mapper接口名称和mapper映射文件名称一致并且两者在同一目录下
(3)<package name=" "/>
注册指定包下的所有mapper接口
如:<package name="cn.itcast.mybatis.mapper"/>
注意:此种方法要求mapper接口名称和mapper映射文件名称相同,且放在同一个目录中。
2.4 测试类
Public class UserMapperTest extends TestCase {
private SqlSessionFactory sqlSessionFactory;
protected void setUp() throws Exception {
//mybatis配置文件
String resource = "sqlMapConfig.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
//使用SqlSessionFactoryBuilder创建sessionFactory
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
}
Public void testFindUserById() throws Exception {
//获取session
SqlSession session = sqlSessionFactory.openSession();
//获取mapper接口的代理对象
UserMapper userMapper = session.getMapper(UserMapper.class);
//调用代理对象方法
User user = userMapper.findUserById(1);
System.out.println(user);
//关闭session
session.close();
}
@Test
public void testFindUserByUsername() throws Exception {
SqlSession sqlSession = sqlSessionFactory.openSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
List<User> list = userMapper.findUserByUsername("张");
System.out.println(list.size());
}
Public void testInsertUser() throws Exception {
//获取session
SqlSession session = sqlSessionFactory.openSession();
//获取mapper接口的代理对象
UserMapper userMapper = session.getMapper(UserMapper.class);
//要添加的数据
User user = new User();
user.setUsername("张三");
user.setBirthday(new Date());
user.setSex("1");
user.setAddress("北京市");
//通过mapper接口添加用户
userMapper.insertUser(user);
//提交
session.commit();
//关闭session
session.close();
}
}