MyBatis第二天

知识点一.使用注解方式配置映射

CRUD

注意
1.results中的每个result需要用逗号分隔
2.查询所有的时候因为使用d_id,d_username这种列名,所以要有ResultMap,来知晓与User中的哪些属性来对应,否则查出来的都是null。

public interface UserMapper {
//    @Insert("insert into t_user(username,password,age) values (#{username},#{password},#{age})")
//    @Options(keyColumn = "id",keyProperty = "id",useGeneratedKeys = true)
    void save(User u);

//    @Update("update t_user set username=#{username},password=#{password},age=#{age} where id = #{id}")
    void update(User u);

//    @Select("select id,username,password,age from t_user where id = #{id}")
    User get(Long id);

//    @Select("select id as d_id,username as d_username,password as d_password,age as d_age from t_user")
//    @ResultMap("base_map")    用配置文件中的base_map
//    @Results({               //不用配置文件中的base_map
//            @Result(column = "d_id",property = "id"),
//            @Result(column = "d_username",property = "username"),
//            @Result(column = "d_password",property = "password"),
//            @Result(column = "d_age",property = "age"),
//    })
    List list();

//    @Delete("delete from t_user where id = #{id}")
    void delete(Long id);
    }

以上可替代下面的内容:

 

        
        
        
        
        
    
    
    
        insert into t_user(username,password,age) values (#{username},#{password},#{age})
    

    
        update t_user set username=#{username},password=#{password},age=#{age} where id = #{id}
    

    
    

    
    

    
        delete from t_user where id = #{id}
    

知识点二.使用@param的注解

问题:mybatis中的方法都是只支持传入一个参数。
如果想传入多个参数.

注意此处要指定resultType

 

mapper接口中常规如下
1.在方法参数定义Map集合,把需要传入的参数放入map中.

  User login(Map map);

测试类中常规:

        Map uMap = new HashMap();
        uMap.put("username","卡丁");
        uMap.put("password","66");
        User u = mapper.login(uMap);
        System.out.println(u);

使用了@param之后

mapper接口中如下:
2.使用@Param注解来解决.

 User login(@Param("username") String username,@Param("password") String password);

测试类中:

        User u = mapper.login("卡丁","66");
        System.out.println(u);

其原理:
MyBatis第二天_第1张图片

知识点三.MyBatis对象关系映射细节

1.Many2One员工2部门

员工(Employee)和部门(Department),多对一:员工表中含有外键(部门号)

domain包:

public class Employee {
    private Long id;
    private String name;
    private Department dept;
    public Employee() {
    }
    public Employee(String name) {
        this.name = name;
    }
//getter setter方法略
}
public class Department {
    private Long id;
    private String name;

    public Department() {
    }

    public Department(String name) {
        this.name = name;
    }
   
  //getter setter略去
}

主配置文件添加mapper,添加别名

 
        
        
        
    
 
        
        
        
    

两mapper接口

public interface EmployeeMapper {
    void save(Employee e);
    Employee get(Long id);
}
---------------------------
public interface DepartmentMapper {
    void save(Department d);
    Department get(Long id);
}

两mapper.xml文件

== 注意此处insert中部门号要#{dept.id},就是说从dept中找id==


    
        insert into t_employee(name,dept_id) values (#{name},#{dept.id})
    

    


    
        insert into t_department(name) values (#{name})
    
    

测试类:
注意:此处many2one的保存操作,要先保存one方,再保存many方
1.保存

    @Test
    public void testSave(){
        SqlSession session = MybatisUtils.openSession();
        EmployeeMapper eMapper = session.getMapper(EmployeeMapper.class);
        DepartmentMapper dMapper = session.getMapper(DepartmentMapper.class);
        Employee e = new Employee();
        Department d = new Department();
        d.setName("一号部门");
        e.setName("一号员工");
        e.setDept(d);
        dMapper.save(d);
        eMapper.save(e);
        session.commit();
        session.close();
    }
}

2.查询

这里有坑需要注意:
简单的查,是不能通过员工把部门也查询出来的,所以EmployeeMapper.xml要配置resultMap




    
    
        
        
        
        
    

    
        insert into t_employee(name,dept_id) values (#{name},#{dept.id})
    

    

myBatis中的延时加载.

1.在myBatis中默认的延时加载时禁用的.
在主配置文件中开启延时加载
lazyLoadingEnabled:默认为false,禁用延时加载.
2.many变成代理对象.
当调用many方的任意属性,都会触发one方的加载.
aggressiveLazyLoading:当启用时, 有延迟加载属性的对象在被调用时将会完全加载任意属性。否则, 每种属性将会按需要加载。
3.在many方默认的调用equals,clone,hashCode,toString 方法都会出发one方的加载
lazyLoadTriggerMethods
主配置文件中配置settings

   
        
        
        
        
        
        
    

N+1问题

在查询所有many记录,每个many对应的one都是不同,查询N个many对象,总共会发出N+1条SQL.(性能特别不友好)

使用leftJoin的方式来解决.

这里写于resultMap中,不采用发sql的方式
   
       
       
   
--------------------------
 

dept_ 采用 columnPrefix措施简化

 
       
       
   

一级缓存

生命周期:
和session一样的生命周期.
通过session.get(1L),session.get(1L),总共两次get方法只会发一条SQL.第二次使用的是一级缓存的内容

//清除一级缓存中内容
session.clearCache();

针对数据量大的时候,使用分页+clearCache()及时清除缓存

2.One2Many部门2员工

one需要处理外键关系
员工类中的dept_id属性删除,并在部门类中增加员工对象emps.

public class Department {
    private Long id;
    private String name;
    private List emps = new ArrayList();

    public Department() {
    }
    public Department(String name) {
        this.name = name;
    }
//getter setter方法
//toString方法(id,name)
}

主配置文件中定义别名,注册mapper:


        
        
    
 
        
        
        
    

两个mapper接口

public interface DepartmentMapper {
    void save(Department e);
    Department get(Long id);
    void handlerRelation(@Param("deptId")Long deptId,@Param("empId")Long empId);
}
----------------------------
public interface EmployeeMapper {
    void save(Employee e);
    Employee get(Long id);
}

两个mapper文件


    
        
        
        
        
            
        
    

    

    
        insert into t_department (name) values (#{name})
    
    
    
        update t_employee set dept_id = #{deptId} where id = #{empId}
    


    
        insert into t_employee (name) values (#{name})
    

    
    

测试:

public class TestOne2Many {
    @Test
    public void test01() {
        SqlSession session = MybatisUtils.openSession();
        EmployeeMapper eMapper = session.getMapper(EmployeeMapper.class);
        DepartmentMapper dMapper = session.getMapper(DepartmentMapper.class);
        Employee e1 = new Employee("一号员工");
        Employee e2 = new Employee("二号员工");
        Department d = new Department("一号部门");

        d.getEmps().add(e1);
        d.getEmps().add(e2);

        eMapper.save(e1);
        eMapper.save(e2);
        dMapper.save(d);
        //需要由one方去处理外键关系
        List es = d.getEmps();
        for (Employee e : es) {
            dMapper.handlerRelation(d.getId(),e.getId());
        }
        session.commit();
        session.close();
    }
    @Test
    public void testGet() {
    SqlSession session = MybatisUtils.openSession();
        DepartmentMapper dMapper = session.getMapper(DepartmentMapper.class);
        Department dept = dMapper.get(22L);
        System.out.println(dept);
        List emps = dept.getEmps();
        for (Employee emp : emps) {
            System.out.println(emp);
        }
        session.close();
    }
}

3.many2many(教师2学生)

在这个地方,犯了个错误,就是用insert,update,delete更改数据库中的内容的时候,切记session.commit操作,要不然数据库中内容不会改变.

保存操作如下:

1.建数据库表,学生表,教师表,中间表(学生id,教师id)
2.教师类学生类分别提供id,name属性,无参及有参(name)构造器,对应属性的getter,setter方法.
3.在主配置文件中定义别名,并注册对应mapper.xml.
4.两个mapper接口

public interface StudentMapper {
    void save(Student t);
}
---------------------------------
public interface TeacherMapper {
    void save(Teacher t);
    void handlerRelation(@Param("teaId")Long teaId,@Param("stuId")Long stuId);
}

两个mapper.xml文件,注意TeacherMapperz中的handlerRelation


	
        insert into t_student(name) values (#{name})
    


-------------------------------------------------------

    
        insert into t_teacher(name) values (#{name})
    
    
        insert into tea_stu (t_id,s_id) values (#{teaId},#{stuId})
    

测试类:

  @Test
    public void test(){
        Teacher t1 = new Teacher();
        t1.setName("老师一");
        Teacher t2 = new Teacher();
        t2.setName("老师二");

        Student s1 = new Student();
        s1.setName("学生一");
        Student s2 = new Student();
        s2.setName("学生二");

        t1.getStus().add(s1);
        t1.getStus().add(s2);
        t2.getStus().add(s1);
        t2.getStus().add(s2);

        SqlSession session = MybatisUtils.openSession();
        TeacherMapper tMapper = session.getMapper(TeacherMapper.class);
        StudentMapper sMapper = session.getMapper(StudentMapper.class);

        tMapper.save(t1);
        tMapper.save(t2);
        sMapper.save(s1);
        sMapper.save(s2);

        //来处理中间表的的关系
        List t1Stus = t1.getStus();
        for (Student student : t1Stus) {
            tMapper.handlerRelation(t1.getId(),student.getId());
            System.out.println(student);
        }
        List t2Stus = t2.getStus();
        for (Student student : t2Stus) {
            tMapper.handlerRelation(t2.getId(),student.getId());
            System.out.println(student);
        }
        session.commit();
        session.close();
    }

查询操作

注意
resuilMap代替resultType

mapper接口中提供get方法.

public interface StudentMapper {
    Student get(Long id);
}
---------------------------------------
public interface TeacherMapper {
    Teacher get(Long id);
}

mapper的xml文件中:
StudentMapper

 	

TeacherMapper

  
            
            
            
        
        

测试:

    @Test
    public void testQ(){
        SqlSession session = MybatisUtils.openSession();
        TeacherMapper tMapper = session.getMapper(TeacherMapper.class);
        Teacher teacher = tMapper.get(9L);
        List stus = teacher.getStus();
        for (Student student : stus) {
            System.out.println(student);
        }
        System.out.println(teacher);
        session.close();
    }

-----------------------分隔符---------------------------------------------------

spring与mybatis简单集成(jar):

Mapper的使用
1.把mapper当做是Dao辅助工具
2.直接将mapper当做是Dao.
步骤:
1.导入相关的资源包
1.myBatis自身的包
2.spring相关的包
3.spring-mybatis-plugins.jar整合
数据库连接池druid.
MyBatis第二天_第2张图片
2.创建resources添加配置文件
MyBatis第二天_第3张图片
3.编写配置文件
1.导入外部文件db.properties
2.配置数据源
3.配置sessionFactory
4.配置事务管理器
5.配置事务模板
6.AOP切面配置
定义service,Mapper对应bean.

application.xml中内容如下:



    
    

    
    
    
    
        
        
        
        
    
    
    
        
        
        
        
        
    
    
    
        
    
    
    
        
            
            
            
            
        
    
    
    
        
        
    

    
    
        
    

    
    
        
    
    
        
    

1.service全都变成注解配置的方式.

2.在配置文件中添加注解扫描的配置

    
    

3.添加扫描mapper的类

 
    
        
    

最后:二级缓存

1.回顾hibernate中的缓存
二级缓存的生命周期和sessionFactory一样的生命周期
什么样类型的对象适合放入二级缓存
读远远大于写的对象.
hibernate中的缓存:
1.一级缓存
2.二级缓存
3.查询缓存(限制很多,命中率比较低)
开启二级缓存后,get (),insert(),get(); 总共发2条sql


MyBatis中的二级缓存.
一般来说,我们将myBatis中二级缓存说成是myBatis缓存

步骤:
1.需要在mapper文件中添加
2.缓存的对象需要实现序列化接口

myBatis开启二级缓存后,get (),insert(),get(); 总共发3条sql

在mybatis中无论是selectOne还是selectList都是使用查询缓存.当对象新增,更新,删除的时候,都回去清空查询缓存
让myBatis的缓存和hibernate中的二级缓存靠近
步骤:
1.让所有list都不是缓存 userCache=false
在这里插入图片描述 2.让新增操作不清空缓存. flashCache=false

你可能感兴趣的:(My,Batis)