【南京校区】非诚勿扰《mybatis》之再判断 德艺双馨杨老师
哈喽我又来了,上次咱们介绍到了mybatis的基本用法,接下来要介绍一些的动态代理,关联关系映射,
一、首先呢说一说mybatis里的事物控制,当你单纯在使用mybatis的时候会是什么样子的呢
1.mybatis里查询动作不会触发事务提交动作,即便定义了session.commit()也不会触发,除非明确
提出session.commit(true).
2.默认情况下,mybatis不会对insert update delete做事务提交,如果需要真正完成数据库更新操作
则需要在代码中明确写出session.commit();
二、Mapper动态代理方式是干什么的?
Mapper接口开发方法只需要程序员编写Mapper接口(相当于Dao接口),由Mybatis框架根据接口定义创建接口的动态代理对象,
代理对象的方法体同上边Dao接口实现类方法。
Mapper接口开发需要遵循以下规范:
1、 Mapper.xml文件中的namespace与mapper接口的类路径相同。
2、 Mapper接口方法名和Mapper.xml中定义的每个statement的id相同
3、 Mapper接口方法的输入参数类型和mapper.xml中定义的每个sql 的parameterType的类型相同
4、 Mapper接口方法的输出参数类型和mapper.xml中定义的每个sql的resultType的类型相同
定义mapper映射文件UserMapper.xml(内容同Users.xml),需要修改namespace的值为 UserMapper接口路径。
将UserMapper.xml放在classpath 下mapper目录下。
接口定义有如下特点:
1、 Mapper接口方法名和Mapper.xml中定义的statement的id相同
2、 Mapper接口方法的输入参数类型和mapper.xml中定义的statement的parameterType的类型相同
3、 Mapper接口方法的输出参数类型和mapper.xml中定义的statement的resultType的类型相同
使用:
//获取mapper接口的代理对象
UserMapper userMapper = session.getMapper(UserMapper.class);
//调用代理对象方法
User user = userMapper.findUserById(1);
selectOne和selectList
动态代理对象调用sqlSession.selectOne()和sqlSession.selectList()是根据mapper接口方法的返回值决定,
如果返回list则调用selectList方法,如果返回单个对象则调用selectOne方法。
namespace
mybatis官方推荐使用mapper代理方法开发mapper接口,程序员不用编写mapper接口实现类,
使用mapper代理方法时,输入参数可以使用pojo包装对象或map对象,保证dao的通用性。
三、接下来就是最最重要的时刻了 关联关系映射它是我们数据库表和实体之最重要的关系了
一对一 :
1)数据库里建表: db里表示数据间的一对一关系,需要选择一方建立外键,同时在fk上添加uk
create table person(
id number(7) primary key,
name varchar2(15) not null,
email varchar2(30) not null,
cid number(7) references IdentifyCard(id) unique
);
create table IdentifyCard(
id number(7) primary key,
serial varchar2(18) not null check(length(serial)=18),
expire number(2)
);
2)java程序里描述数据
双向一对一:互相保留对方的一个引用
单向一对一:只在关系主要方保留对方的一个引用(尽量与db里表关系的方向保持一致)
class Person{
private Integer id;
private String name;
private String email;
private IdentifyCard card; //关系属性
}
class IndentifyCard{
private Integer id;
private String serial;
private int expire;
private Person Person; //关系属性
}
3)写dao(PersonDao,IndentifyCardDao)
PersonDaoImpl.xml映射文件
<resultMap type="实体的全限定名" id="该resultMap的唯一标识">
<id property="属性名" column="数据库字段名"></id>
<result property="属性名" column="数据库字段名"></result>
<association property="实体类里关系属性名" javaType="关系属性的类型">
<id property="属性名" column="数据库字段名"></id>
<result property="属性名" column="数据库字段名"></result>
</association>
</resultMap>
一对多:
1)数据库里建表 :一对多是db最擅长描述的关系,只需要在“多的一方”建立外键即可
create table dept( //一
id number(7) primary key,
name varchar2(15) not null
);
create table emp( //多
id number(7) primary key,
name varchar2(15) not null,
salary number(5),
did number(7) references dept(id)
);
2)java程序里定义实体类
双向一对多:一的一方(保留多的一个集合) 多的一方(保留一的一个引用)
单项一对多:通常都是多到一的单向
class Dept{
private Integer id;
private String name;
private List<Emp> emps = new ArrayList<Emp>();
}
class Emp{
private Integer id;
private String name;
private double salary;
private Dept dept;
}
3)dao(DeptDao EmpDao)
<resultMap type="实体的全限定名" id="该resultMap的唯一标识">
<id property="" column=""></id>
<result property="" column=""></result>
<collection property="实体类里关系属性名" ofType="集合里元素的类型">
<id property="" column=""></id>
<result property="" column=""></result>
</collection>
</resultMap>
四、动态sql
动态sql。通过mybatis提供的各种标签方法实现动态拼接sql。
1. if
<select id="findUserList" parameterType="user" resultType="user">
select * from user
where 1=1
<if test="id!=null">
and id=#{id}
</if>
<if test="username!=null and username!=''">
and username like '%${username}%'
</if>
</select>
注意要做不等于空字符串校验。
<!-- 多条件使用 and 而不是 && -->
<if test="username!=null and username!='' ">
and username LIKE '%${username}%'
</if>
2. where
<select id="findUserList" parameterType="user" resultType="user">
select * from user
<where>
<if test="id!=null and id!=''">
and id=#{id}
</if>
<if test="username!=null and username!=''">
and username like '%${username}%'
</if>
</where>
</select>
注意:<where />可以自动处理第一个and。
3. foreach 向sql传递数组或List,mybatis使用foreach解析
例如;
传入多个id查询用户信息,用下边两个sql实现:
SELECT * FROM USERS WHERE username LIKE '%张%' AND (id =10 OR id =89 OR id=16)
SELECT * FROM USERS WHERE username LIKE '%张%' id IN (10,89,16)
<if test="ids!=null and ids.size>0">
<foreach collection="ids" open=" and id in(" close=")" item="id" separator="," >
#{id}
</foreach>
</if>
4. choose
<select id="findActiveBlogLike" resultType="Blog">
SELECT * FROM BLOG WHERE state = ‘ACTIVE'
<choose>
<when test="title != null">
AND title like #{title}
</when>
<when test="author != null and author.name != null">
AND author_name like #{author.name}
</when>
<otherwise>
AND featured = 1
</otherwise>
</choose>
</select>
以上例子中: 当title和author都不为null的时候, 那么选择二选一(前者优先), 如果都为null, 那么就选择 otherwise中的, 如果tilte和author只有一个不为null, 那么就选择不为null的那个
5. trim
<trim prefix="WHERE" prefixOverrides="AND |OR ">
...
</trim>
它的意思就是: 当WHERE后紧随AND或则OR的时候,就去除AND或者OR。 除了WHERE以外, 其实还有一个比较经典的实现,那就是SET。
6 set
<update id="updateUser" parameterType="com.dy.entity.User">
update user set
<if test="name != null">
name = #{name},
</if>
<if test="password != null">
password = #{password},
</if>
<if test="age != null">
age = #{age}
</if>
<where>
<if test="id != null">
id = #{id}
</if>
and deleteFlag = 0;
</where>
</update>
问题又来了: “如果我只有name不为null, 那么这SQL不就成了 update set name = #{name}, where ........ ?
你那name后面那逗号会导致出错啊!”
正解:
<update id="updateUser" parameterType="com.dy.entity.User">
update user set
<set>
<if test="name != null">name = #{name},</if>
<if test="password != null">password = #{password},</if>
<if test="age != null">age = #{age},</if>
</set>
<where>
<if test="id != null">
id = #{id}
</if>
and deleteFlag = 0;
</where>
</update>
用trim
<trim prefix="SET" suffixOverrides=",">
...
</trim>
WHERE是使用的 prefixOverrides(前缀), SET是使用的 suffixOverrides (后缀), 看明白了吧!
7. sql片段 Sql中可将重复的sql提取出来,使用时用include引用即可,最终达到sql重用的目的,
<!-- 传递pojo综合查询用户信息 -->
<select id="findUserList" parameterType="user" resultType="user">
select * from user
<where>
<if test="id!=null and id!=''">
and id=#{id}
</if>
<if test="username!=null and username!=''">
and username like '%${username}%'
</if>
</where>
</select>
将where条件抽取出来:
<sql id="query_user_where">
<if test="id!=null and id!=''">
and id=#{id}
</if>
<if test="username!=null and username!=''">
and username like '%${username}%'
</if>
</sql>
使用include引用:
<select id="findUserList" parameterType="user" resultType="user">
select * from user
<where>
<include refid="query_user_where"/>
</where>
</select>
注意:如果引用其它mapper.xml的sql片段,则在引用时需要加上namespace,如下:
<include refid="namespace.sql片段”/>
以上就是mybatis的一些高级的理念和比较实际的用法,敬请等待后续非诚勿扰《mybatis》之终觉定。
|
|