Mybatis关联映射
将数据库中有关联关系的表,以实体对象引用的方式体现出来
关联方式:
- 关联单个对象
- 关联多个对象
class User{
private List
}
class Book{
private User user;
}
什么时候用
业务需要对数据库进行关联查询的时候
可以通过一条SQL语句完成关联查询。也可以通过两条SQL语句进行关联查询
案例:通过userId查询用户信息和关联的笔记本信息
1.User 实体类
2.定义Dao接口,配置Mapper文件
3.定义测试类验证查询结果
2个SQL语句:语句简单,但是配置繁琐,与DB两次交互
<!-- 使用两条SQL语句加载数据 -->
<select id="findUserAndBook" parameterType="String" resultMap="userMap1">
select * from cn_user where cn_user_id=#{id}
</select>
<resultMap type="io.codegitz.cloud_note.entity.User" id="userMap1">
<id property="cn_user_id" column="cn_user_id" />
<result property="cn_user_name" column="cn_user_name" />
<!-- 指定books属性是List集合,泛型为Book -->
<!-- javaType是返回类型 -->
<collection property="books" javaType="java.util.List"
ofType="io.codegitz.cloud_note.entity.Book" select="findBooks"
column="cn_user_id">
</collection>
</resultMap>
<select id="findBooks" parameterType="String"
resultType="io.codegitz.cloud_note.entity.Book">
select * from cn_user where cn_user_id=#{userId}
</select>
1个SQL语句:语句复杂,配置较简单,与DB交互一次
<!-- 一条SQL加载user -->
<select id="findUserAndBook1" parameterType="String" resultMap="userMap2">
select * from cn_user u join cn_notebook b
on(u.cn_user_id=b.cn_user_id) where u.cn_user_id=#{userId}
</select>
<resultMap type="io.codegitz.cloud_note.entity.User" id="userMap2">
<!-- 定义cn_user 字段装载,不能忽略 -->
<id property="cn_user_id" column="cn_user_id" />
<result property="cn_user_name" column="cn_user_name" />
<result property="cn_user_nick" column="cn_user_nick" />
<result property="cn_user_password" column="cn_user_password" />
<result property="cn_user_token" column="cn_user_token" />
<collection property="books"
javaType="java.util.List"
ofType="io.codegitz.cloud_note.entity.Book">
<id property="cn_notebook_id" column="cn_notebook_id"/>
<result property="cn_user_id" column="cn_user_id"/>
<result property="cn_notebook_type_id" column="cn_notebook_type_id"/>
<result property="cn_notebook_name" column="cn_notebook_name"/>
<result property="cn_notebook_desc" column="cn_notebook_desc"/>
<result property="cn_notebook_createtime" column="cn_notebook_createtime"/>
</collection>
</resultMap>
案例:通过查询笔记信息,关联用户信息
用一条查询语句实现
主键的字段处理
在数据库使用自增列或序列作为主键值时,如何在insert执行后、立刻获取id值
属性增加
useGeneratedKeys=”true” keyProperty=”id”
-Mysql
create table t_emp(id int primary key auto_increment,name varchar(20),age int)
<mapper namespace="io.codegitz.cloud_note.dao.EmpDao">
<!-- mysql:数据库自动生成主键值,获取主键值放入对象的id属性中 -->
<insert id="save" parameterType="io.codegitz.cloud_note.entity.Emp"
useGeneratedKeys="true" keyProperty="id">
insert into t_emp (name,age) values (#{name},#{age})
</insert>
</mapper>
spring事务管理
什么是事务?程序为了保证业务处理的完整性,执行一个或多个SQL语句
管理:对事务中的Sql语句进行提交或回滚,叫做事务管理
什么时候用?作用于Service的方法上
事务回顾:
转账:A账户转1000到B账户
通过spring进行事务管理
步骤:
1.配置Spring-transaction.xml
- 使用@Transactional标记
可读可写
select操作时,可采用只读事务
@Transaction(readOnly=true)
回滚特性
默认RuntimeException回滚,其他异常不回滚
@Transaction(rollbackFor=IOException.class)
public void f1(){
//db操作(insert)
//IOException
}
public void deleteNote(String… ids) {
//String... 就是String[] 数组
}
传播特性
默认类型:REQUIRED
传播行为 描述
PROPAGATION_REQUIRED 如果没有,就开启一个事务;如果有,就加入当前事务(方法B看到自己已经运行在 方法A的事务内部,就不再起新的事务,直接加入方法A)
RROPAGATION_REQUIRES_NEW 如果没有,就开启一个事务;如果有,就将当前事务挂起。(方法A所在的事务就会挂起,方法B会起一个新的事务,等待方法B的事务完成以后,方法A才继续执行)
PROPAGATION_NESTED 如果没有,就开启一个事务;如果有,就在当前事务中嵌套其他事务
PROPAGATION_SUPPORTS 如果没有,就以非事务方式执行;如果有,就加入当前事务(方法B看到自己已经运行在 方法A的事务内部,就不再起新的事务,直接加入方法A)
PROPAGATION_NOT_SUPPORTED 如果没有,就以非事务方式执行;如果有,就将当前事务挂起,(方法A所在的事务就会挂起,而方法B以非事务的状态运行完,再继续方法A的事务)
PROPAGATION_NEVER 如果没有,就以非事务方式执行;如果有,就抛出异常。
PROPAGATION_MANDATORY 如果没有,就抛出异常;如果有,就使用当前事务
隔离特性
默认属性:READ_COMMITED
针对事务并发进行处理
脏读/幻读
动态SQL
使用
public int updateNoteByMap(Map<String,Object> map);
<update id="updateNoteByMap" parameterType="Map">
update cn_note set
<trim suffixOverrides=",">
<if test="title!=null"> cn_note_title=#{title},</if>
<if test="body!=null">cn_note_body=#{body},</if>
<choose>
<when test="time!=null">
cn_note_last_modify_time=#{time}
</when>
<otherwise>
cn_note_last_modify_time=unix_timestamp()
</otherwise>
</choose>
<!-- <if test="time!=null">cn_note_last_modify_time=#{time}</if> -->
</trim>
where cn_note_id=#{noteId}
</update>