Mybatis就是类似于hibernate的orm持久层框架。
一、Mybatis介绍
MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis 。2013年11月迁移到Github。
Mybatis是面向sql的持久层框架,他封装了jdbc访问数据库的过程,我们开发,只需专注于sql语句本身的拼装,其它复杂的过程全部可以交给mybatis去完成。
Mybatis根据id查询用户信息
1、导入Mybatis所需jar包 mybatis-3.2.7.jar
2、准备实体类User以及对应的数据库表
3、配置SqlMapConfig.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>
<!-- 和spring整合后 environments配置将废除 -->
<environments default="development">
<environment id="development">
<!-- 使用jdbc事务管理 -->
<transactionManager type="JDBC" />
<!-- 数据库连接池 -->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver" />
<property name="url"
value="jdbc:mysql:///hibernateDemo?characterEncoding=utf-8" />
<property name="username" value="root" />
<property name="password" value="xuyao" />
</dataSource>
</environment>
</environments>
<!-- 加载映射文件 -->
<mappers>
<mapper resource="User.xml"/>
</mappers>
</configuration>
4、配置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">
<mapper namespace="user">
<select id="findUserById" parameterType="int" resultType="com.wasion.domain.User" >
SELECT * FROM USER WHERE id = #{value}
</select>
</mapper>
5、测试类
@Test
@Override
public void findUserById() throws IOException {
// 创建SqlSessionFactoryBuilder对象
SqlSessionFactoryBuilder sfb = new SqlSessionFactoryBuilder();
// 查找配置文件创建输入流
InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
// 加载配置文件,创建SqlSessionFactory对象
SqlSessionFactory sqlSessionFactory = sfb.build(inputStream);
// 创建SqlSession对象
SqlSession sqlSession = sqlSessionFactory.openSession();
// 执行查询,参数一:要查询的statementId ,参数二:sql语句入参
User user = sqlSession.selectOne("user.findUserById", 16);
// 输出查询结果
System.out.println(user);
// 释放资源
sqlSession.close();
}
二、Mybatis Dao开发方式
1、原始Dao开发方法
(1)抽取Mybatis模板
public class MybatisUtil {
private static ThreadLocal<SqlSession> threadLocal = new ThreadLocal<SqlSession>();
private static SqlSessionFactory sqlSessionFactory;
// 加载位于src/SqlMapConfig.xml配置文件
static{
try {
Reader reader = Resources.getResourceAsReader("SqlMapConfig.xml");
sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
/**
* 禁止外界通过new方法创建
*/
private MybatisUtil(){}
/**
* 获取SqlSession
*/
public static SqlSession getSqlSession(){
//从当前线程中获取SqlSession对象
SqlSession sqlSession = threadLocal.get();
//如果SqlSession对象为空
if(sqlSession == null){
//在SqlSessionFactory非空的情况下,获取SqlSession对象
sqlSession = sqlSessionFactory.openSession();
//将SqlSession对象与当前线程绑定在一起
threadLocal.set(sqlSession);
}
//返回SqlSession对象
return sqlSession;
}
/**
* 关闭SqlSession与当前线程分开
*/
public static void closeSqlSession(){
//从当前线程中获取SqlSession对象
SqlSession sqlSession = threadLocal.get();
//如果SqlSession对象非空
if(sqlSession != null){
//关闭SqlSession对象
sqlSession.close();
//分开当前线程与SqlSession对象的关系,目的是让GC尽早回收
threadLocal.remove();
}
}
}
(2)用模板实现根据名字查找用户
public void findByName(){
SqlSession sqlSession = MybatisUtil.getSqlSession();
List<User> list = sqlSession.selectList("user.findUserByName", "a");
MybatisUtil.closeSqlSession();
for (User user:list){
System.out.println(user);
}
}
<select id="findUserByName" parameterType="java.lang.String" resultType="com.wasion.domain.User" >
SELECT * FROM USER WHERE username like '%${value}%'
</select>
(3)用模板实现根据插入用户
public void insertUser(){
SqlSession sqlSession = MybatisUtil.getSqlSession();
User user = new User(10, "张三", "123456", "1", null, "湖南长沙");
sqlSession.insert("test.insertUser",user);
sqlSession.commit();
MybatisUtil.closeSqlSession();
}
*注意:插入、删除、修改等操作,需要commit提交,不会报错,但数据库无变化
也可以将MybatisUtil 模板中的操作 sqlSession = sqlSessionFactory.openSession()
改为sqlSession = sqlSessionFactory.openSession(true)
2、接口动态代理
动态代理dao开发规则
- namespace必需是接口的全路径名
- 接口的方法名必需与映射文件的sql id一致
- 接口的输入参数必需与映射文件的parameterType类型一致
- 接口的返回类型必须与映射文件的resultType类型一致
(1)创建mapper目录,在目录下创建UserMapper接口和UserMapper.xml配置文件
(2)按动态代理dao开发规则修改UserMapper和UserMapper.xml
UserMapper:
UserMapper.xml:
(3)将配置文件引入SqlMapConfig.xml
<mappers>
<!-- 第一种方式,加载 resource-->
<!-- <mapper resource="com/wasion/domain/User.xml" /> -->
<mapper resource="com/wasion/mapper/UserMapper.xml" />
<!-- 第二种方式,class扫描器要求:
1、映射文件与接口同一目录下
2、映射文件名必需与接口文件名称一致 -->
<mapper class="com.wasion.mapper.UserMapper" />
<!-- 第三种方式,包扫描器要求(推荐使用此方式):
1、映射文件与接口同一目录下
2、映射文件名必需与接口文件名称一致 -->
<package name="com.wasion.mapper" />
</mappers>
(4)测试
public class UserServiceImpl{
@Test
public void testFindUserById(){
SqlSession sqlSession = MybatisUtil.getSqlSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
User user = userMapper.findUserById(3);
System.out.println(user);
sqlSession.close();
}
@Test
public void testFindUserByName(){
SqlSession sqlSession = MybatisUtil.getSqlSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
List<User> list = userMapper.findUserByName("lisi");
for (User user:list){
System.out.println(user);
}
sqlSession.close();
}
@Test
public void testDeleteUser(){
SqlSession sqlSession = MybatisUtil.getSqlSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
userMapper.deleteUser(22);
sqlSession.close();
}
@Test
public void testInsertUser(){
SqlSession sqlSession = MybatisUtil.getSqlSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
User user = new User(8, "赵华", "123456", "0", null, "湖南衡阳");
userMapper.insertUser(user);
sqlSession.close();
}
}
三、SqlMapConf.xml配置
1、properties
(1)抽取数据库配置到jdbc.properties
(2)加载jdbc.properties文件
<properties resource="jdbc.properties" />
(3)修改environments
<environments default="development">
<environment id="development">
<!-- 使用jdbc事务管理 -->
<transactionManager type="JDBC" />
<!-- 数据库连接池 -->
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driverClass}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</dataSource>
</environment>
</environments>
2、typeAliases
(1)自定义别名
<typeAliases>
<!-- 单个别名定义 -->
<!--<typeAlias type="com.wasion.domain.User" alias="user"/>-->
<!-- 别名包扫描器(推荐使用此方式),整个包下的类都被定义别名,别名为类名,不区分大小写-->
<package name="com.wasion.domain"/>
</typeAliases>
(2)UserMapper.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="test">
<select id="findUserById" parameterType="java.lang.Integer" resultType="user" >
SELECT * FROM user WHERE id = #{id}
</select>
</mapper>
* resultType不用写实体类的全路径, 使用别名即可
3、mappers
<mappers>
<!-- 第一种方式,加载 resource-->
<mapper resource="com/wasion/domain/User.xml" />
<!--<mapper resource="com/wasion/mapper/UserMapper.xml" />-->
<!-- 第二种方式,class扫描器要求:
1、映射文件与接口同一目录下
2、映射文件名必需与接口文件名称一致 -->
<!--<mapper class="com.wasion.mapper.UserMapper" />-->
<!-- 第三种方式,包扫描器要求(推荐使用此方式):
1、映射文件与接口同一目录下
2、映射文件名必需与接口文件名称一致 -->
<package name="com.wasion.mapper" />
</mappers>
* 注意:第三种方法要求mapper接口名称和mapper映射文件名称相同,且放在同一个目录中。并且还有一个前提是:使用的是mapper代理方法
四、小结
1.parameterType和resultType
parameterType:在映射文件中通过parameterType指定输入 参数的类型。
resultType:在映射文件中通过resultType指定输出结果的类型
2.#{}和${}
#{}表示一个占位符号,#{}接收输入参数,类型可以是简单类型,pojo、hashmap;
如果接收简单类型,#{}中可以写成value或其它名称;
#{}接收pojo对象值,通过OGNL读取对象中的属性值,通过属性.属性.属性...的方式获取对象属性值。
表示一个拼接符号,会引用sql注入,所以不建议使用表示一个拼接符号,会引用sql注入,所以不建议使用{};
${}接收输入参数,类型可以是简单类型,pojo、hashmap;
如果接收简单类型,${}中只能写成value;
${}接收pojo对象值,通过OGNL读取对象中的属性值,通过属性.属性.属性...的方式获取对象属性值。
3.selectOne()和selectList()
selectOne表示查询出一条记录进行映射。如果使用selectOne可以实现使用selectList也可以实现(list中只有一个对象)。
selectList表示查询出一个列表(多条记录)进行映射。如果使用selectList查询多条记录,不能使用selectOne。