原始dao开发方法
思路:编写
dao
和daoimpl
,向dao
注入SqlSessionFactory
,在方法体内通过SqlSessionFactory
创建SqlSession
。与spring整合之后,直接定义SqlSessionFactory
属性就可以了。
public class UserDaoImpl implements UserDao {
// 通过构造方法传入SqlSessionFactory
// 如果与Spring整合,直接通过注解和SqlSessionFactory属性就可以完成注入。
private SqlSessionFactory sqlSessionFactory;
public UserDaoImpl(SqlSessionFactory sqlSessionFactory) {
this.sqlSessionFactory = sqlSessionFactory;
}
public User findUserById(int id) throws Exception {
// SqlSession线程不安全,需要在内部创建。
SqlSession sqlSession = sqlSessionFactory.openSession();
/**
* @param 参数一:调用sqlSession方法时,statement id 属于硬编码,
* @param 参数二:类型属于泛型,在编译阶段不报错。,
*/
User user = sqlSession.selectOne("com.zd.user.dao.UserMapper.findUserById", id);
//session.commit();// 提交事务
sqlSession.close();
return user;
}
}
原始
dao
开发存在的问题:
-
dao
接口实现类存在大量模版方法,试图将这些代码提取出来。 - 调用
sqlSession
方法时将statement的id
硬编码了 - 调用
sqlSession
方法时传入了泛型变量,编译时不报错
使用mapper
代理方法(只需要提供mapper接口(相当于dao接口))
思路:
- 编写
mapper.xml
映射文件 - 编写
mapper
接口,需要遵循一些开发规范,就可以自动生成mapper
接口实现类代理对象。- 开发规范:
-
mapper.xml
中,namespace
等于mapper
接口地址 -
mapper.java
接口中方法名和mapper.xml
中的statement
的id
一致 -
mapper.java
接口中方法输入参数类型和mapper.xml
中的statement
的parameterType
指定的类型一致 -
mapper.java
接口中方法输入参数类型和mapper.xml
中的statement
的resultType
指定的类型一致
-
- 开发规范:
// 拿到mapper代理对象
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
User user = mapper.findUserById(1);
- 代理对象内部调用
selectOne
selectList
- 如
mapper
返回单个pojo
,代理对象内部通过调用selectOne
查询数据库 - 如
mapper
返回集合对象,代理对象内部通过调用selectList
查询数据库
- 如
- 系统框架中,
dao
层的代码是被业务层公用的。即使mapper
接口很自由一个参数,也可以通过包装类型pojo
满足不通的业务方法需求。
mybatis.xml
全局配置文件
- 将数据库的链接单独配置在
db.properties
中,只需要在mybatis.xml
中加载即可。 -
properties
:属性 -
typeHandler
: 类型处理器 -
typeAliases
类型别名 -
mapper
:映射器*(mapper
配置)- 通过
resource
或者url
加载 - 通过
mapper
接口加载映射文件
- 通过
<mappers>
<mapper class="com.zd.user.dao.UserMapper"></mapper>
<!--批量加载-->
<!--<package name="com.zd.user.dao" ></package>-->
</mappers>
vo po pojo指代的含义:
- vo:试图层面的对象
view object
- po:持久层的对象
- pojo:自定义的,类似po或vo的简单综合javabean
输入输出映射
- 输入映射,
pojo
的包装类型
动态sql
mybatis
对sql
语句灵活操作,通过表达式判断,对sql
进行灵活拼接、组装。
-
if
判断 -
sql
片段 foreach
需求:通过多个id查询用户。
<select id="queryUserWhere" parameterType="com.zd.user.vo.UserQueryVo" resultType="com.zd.user.entity.User">
select * from user where userCustom.sex = #{userCustom.sex} and user.name like '%${userCustom.name}%';
</select>
<select id="queryUsersByIds" >
SELECT * from USER where 1=1 and (id=1 or id=10 or id=15) and ...
</select>
<!--
id:sql片段的唯一标识
经验:是基于单表来定义sql片段,这样sql片段的重用性才高,在sql片段中不要包括where
-->
<!-- 使用foreach遍历传入的ids
collection:指定输入对象的集合
item:每次遍历生成的对象
open:开始遍历时拼接的串
close:结束遍历时拼接的串
separator:遍历的两个对象中需要拼接的串
-->
<sql id="query_user_where">
<if test="user!= null">
<if test="user.sex != null and user.sex!= ''">
and user.sex = #{user.sex}
</if>
<if test="user.name != null and user.name!=''">
and user.name like '%${user.name}%'
</if>
<if test="ids != null">
/*SELECT * from USER where 1=1 and (id=1 or id=10 or id=15) and ...*/
<foreach collection="ids" item="item_id" open="AND(" close=")" separator="or">
<!-- 每个遍历需要拼接的串-->
id=#{item_id}
</foreach>
</if>
</if>
</sql>
网友评论