Mybatis框架学习笔记入门详细(二)

通过接口绑定解决多参数的传递

1 方式一

a) 接口中定义方法

User selByUP(String username, String password);
b) 映射文件中提供对应的标签. 此时, SQL 语句中获取方式有两种, 通过 #{index} #{param+数字} 的方式.不能通过username password来取,因为配置文件识别不到
2 方式二
 
a) 接口中定义方法, 参数中使用 @Param 注解设定参数名用于在 SQL 语句中使用.
 
User selByUP(@Param("username") String username, @Param("password") String password);
b) 映射文件中提供对应的标签. 此时, SQL 语句中获取方式有两种, 通过 #{参数名称} #{param+数字} 的方式.不能通过索引,因为封装成为了一个map对象,没有0和1
 

动态 SQL

 

根据条件的不同, SQL 语句也会随之动态的改变. MyBatis中, 提供了一组标签用于实现动态 SQL.
 
1
用于进行条件判断, test 属性用于指定判断条件. 为了拼接条件, 在 SQL 语句后强行添加 1=1 的恒成立条件.
 
2
用于管理 where 子句. 有如下功能:
a)如果没有条件, 不会生成 where 关键字
b)如果有条件, 会自动添加 where 关键字
c)如果第一个条件中有 and, 去除之

 

3
这是一套标签, 功能类似于 switch...case...
 
4
用于维护 update 语句中的 set 子句. 功能如下:
a)满足条件时, 会自动添加 set 关键字
b)会去除 set 子句中多余的逗号
c)不满足条件时, 不会生成 set 关键字
 
int updUser(User user); 

 
    update t_user 
    
        id=#{id}, 
         
        
            username=#{username}, 
         
         
            password=#{password}, 
         
     
    where id=#{id} 
5
用于在前后添加或删除一些内容
a)prefix, 在前面添加内容
b)prefixOverrides, 从前面去除内容
c)suffix, 向后面添加内容
d)suffixOverrides, 从后面去除内容
 
 
    update t_user 
     
     
        username=#{username}, 
     
    where id=#{id} 

 

6
用于对数据进行再加工, 用于模糊查询
 
7
用于在 SQL 语句中遍历集合参数, 在 in 查询中使用
a)collection: 待遍历的集合
b)open: 设置开始符号
c)item: 迭代变量
d)separator: 项目分隔符
e)close: 设置结束符号
 
 

List selIn(@Param("list") List list);
8
用于提取 SQL 语句, 用于引用 SQL 语句
 

    id,username,password



MyBatis 的缓存机制

a)缓存用于提高查询的效率.
b)MyBatis 的缓存是使用 SQL 标签的ID 作为缓存的唯一标识的. 执行相同的标签可以使用缓存. 不同的标签不能使用缓存.
c) MyBatis 中有两种缓存机制.
 
1 一级缓存
 
a)默认开启. 线程级别的缓存, SqlSession 的缓存
b)在一个 SqlSession 生命周期中有效. SqlSession 关闭,缓存清空.
2 二级缓存
 
a)进程级别的缓存, SqlSessionFactory 的缓存
b)在一个SqlSessionFactory生命周期中有效. 可以在多个SqlSession 生命中期中共享.
c)默认关闭, 需要使用的时候, 要为某个命名空间开启二级缓存(在 mapper.xml 中配置).
d)实体类应该序列化  或者在
 
 

解决列名和属性名不一致问题

如果查询时使用 resultType 属性, 表示采用 MyBatis 的Auto-Mapping(自动映射)机制, 即相同的列名和属性名会自动匹配. 因此, 当数据库表的列名和类的属性名不一致时, 会导致查不到数据. 解决该问题可以有两种方式:
 
1 列别名
 
查询时, 可以通过列别名的方式将列名和属性名保持一致,继续使用自动映射, 从而解决该问题. 但是较为麻烦.
 
2 使用
 
用于自定义映射关系, 可以由程序员自主制定列名和属性名的映射关系. 一旦使用 resultMap, 表示不再采用自动映射机制.
 
 
     
     
     
     
     
 

业务装配实现多表查询(多对一)

mapper 层只做单表查询操作, 在 service 层进行手动装配,实现关联查询的结果.
 
create table t_class(
    id int(3) primary key auto_increment,
	name varchar(20) not null,
    room varchar(20)
)

create table t_student(
	id int(5) primary key auto_increment,
    name varchar(30) not null,
    age int(3),
    gender char(3),
    cid int(3) REFERENCES t_class (id)
)

select * from t_student  s left join t_class c on s.cid=c.id;
1 实体类
 
创建班级类(Clazz)和学生类(Student), 并在 Student 中添加一个 Clazz 类型的属性, 用于表示学生的班级信息.

 

2 mapper
 
提供 StudentMapper 和 ClazzMapper, StudentMapper 查询所有学生信息, ClazzMapper 根据编号查询班级信息.
 
 
     
 


 
     
3 service
 
调用 mapper 层, 先查询所有学生, 再根据每个学生的班级编号查询班级信息, 手动进行组装, 称之为业务装配.
public class StudentServiceImpl implements StudentService {
    @Override
    public List selAll() {
        SqlSession session= MyBatisUtil.getSession();

        StudentMapper studentMapper = session.getMapper(StudentMapper.class);
        ClazzMapper clazzMapper=session.getMapper(ClazzMapper.class);
        List list=studentMapper.selAll();
        
        for(Student student:list){
            student.setClazz(clazzMapper.selById(student.getCid()));
        }

        session.close();
        return list;
    }
}
4 测试代码
 
public class testStudentAndClass {
    public static void main(String[] args) {
        StudentServiceImpl studentService=new StudentServiceImpl();
        List list = studentService.selAll();
        for(Student student:list){
            System.out.println(student);
        }
    }
}
sql语句简单,但是组装麻烦

resultMap N+1 方式实现多表查询(多对)

1 实体类

创建班级类(Clazz)和学生类(Student), 并在 Student 中添加一个 Clazz 类型的属性, 用于表示学生的班级信息.
 
2 mapper
 
提供 StudentMapper 和 ClazzMapper, StudentMapper 查询所有学生信息, ClazzMapper 根据编号查询班级信息. 再 StudentMapper 中使用设置装配.
a) 用于关联一个对象
    property: 指定要关联的属性名
    select: 设定要继续引用的查询, namespace+id
    column: 查询时需要传递的列
 

        
        
        
        
        
        
        
    
    

    

 

 
3 service
由于装配已经完成, service 层只需要调用 mapper 即可, 不需要再进行装配了.

 

public List selAll2(){
        SqlSession session= MyBatisUtil.getSession();

        StudentMapper studentMapper = session.getMapper(StudentMapper.class);
        List list=studentMapper.selAll2();

        session.close();
        return list;
    }

 

上面的方式执行的sql语句很多,因此有了接下来的关联方式实现多表查询


resultMap 的关联方式实现多表查询(对一)

 1 mapper

a)在 StudentMapper.xml 中定义多表连接查询 SQL 语句, 一次性查到需要的所有数据, 包括对应班级的信息.
b)通过定义映射关系, 并通过指定对象属性的映射关系. 可以把看成一个使用. javaType 属性表示当前对象, 可以写全限定路径或别名.

 


        
        
        
        
        
        
            
            
            
        
    
    
    

resultMap N+1 方式实现多表查询(一对)

1 实体类
在班级类中定义一个学生集合, 用于存放该班级的所有学生信息.

 

2 mapper
提供 ClazzMapper 和 StudentMapper, ClazzMapper 查询所有班级信息, StudentMapper 根据班级编号查询学生信息.在 ClazzMapper 中使用设置装配.
a) 用于关联一个集合
    property: 指定要关联的属性名
    select: 设定要继续引用的查询, namespace+id
    column: 查询时需要传递的列
 



    
        
        
        
        
    
    

 

 
3 service
public class ClazzServiceImpl implements ClazzSercive {

    @Override
    public List selAll() {
        SqlSession session= MyBatisUtil.getSession();
        ClazzMapper clazzMapper=session.getMapper(ClazzMapper.class);
        List list=clazzMapper.selAll();
        session.close();
        return list;
    }
}

 


resultMap 的关联方式实现多表查询(一对)

a)在 ClazzMapper.xml 中定义多表连接查询 SQL 语句, 一次性查到需要的所有数据, 包括对应学生的信息.
b)通过定义映射关系, 并通过指定集合属性泛型的映射关系. 可以把看成一个使用. ofType 属性表示集合的泛型, 可以写全限定路径或别名.
 
 
     
         
         
         
         
             
             
             
             
             
         
     

     

通过 Auto-Mapping 实现多表查询

a)通过 MyBatis 的 Auto-Mapping 机制及数据库查询时的别名结合, 可以方便的实现多表查询.不使用resultMap了
b)SQL 语句中, 别名出现特殊符号时, 必须进行处理.MySQL 可以使用(``)符号, Oracle 可以使用("")符号.
 
 
     

注解开发

a)注解是用于描述代码的代码.
例如:
@Test(用于描述方法进行 junit 测试),
@Override(用于描述方法的重写),
@Param(用于描述属性的名称)
 
b)注解的使用风格:
@xxx(属性), 使用前必须先导包
 
c)使用注解一般用于简化配置文件. 但是, 注解有时候也不是很友好(有时候反而更麻烦), 例如动态 SQL.
 
d)关于注解的属性
属性的设定方式是: 属性名=属性值
 
e)关于属性值的类型
基本类型和 String, 可以直接使用双引号的形式
数组类型, name={值 1, 值 2, ...}; 如果数组元素只有一个, 可以省略大括号
对象类型, name=@对象名(属性)
如果属性是该注解的默认属性, 而且该注解只配置这一个属性, 可以将属性名省略
 
f)注解和配置文件可以配合使用

MyBatis 中常用的注解

1 CRUD 注解

@Select: 类似于