Mybatis注解

Mybatis注解

映射器注解

基本注解

@Insert 类似 < insert > 完成新增 修改操作

@Update 类似 < update > 完成修改 删除操作

@Delete 类似 < delete > 完成删除 查询操作

@Select 类似 < select > 完成查询

@Options(useGeneratedKeys = true,keyProperty = " ") 主键回填

@Param("haha") String ssex 起别名 给ssex起别名haha

结果映射注解

@Results结果映射

@Results({ @Result(id = 是否为主键, column = "字段", property = "属性" ) }

一对一映射

学生{...班级{}}

学生和班级通过classid 联系

  1. 在实体类Student中加入外部属性

  2. 在班级接口类ClassMapper中写入方法(通过班级id查班级信息)​

        3. 在学生接口类StudentMapper中写入方法(查询所有学生信息)以及与班级表的映射关系(因为classid映射给了bj,导致查询结果中student的classid=0,所以需要再写一个映射,将student的classid再映射一下)

        4. 在测试类中调用方法名即可

一对多映射

班级{....学生{}}

班级和学生通过classid 联系

  1. 在实体类Class中加入外部属性

  2. 在班级接口类StudentMapper中写入方法(通过学生班级id查学生信息)

  3. 在学生接口类ClassMapper中写入方法(查询所有班级信息)以及与学生表的映射关系(因为classid映射给了stu对象列表,导致查询结果中class的classid=0,所以需要再写一个映射,将class的classid再映射一下,此处未写,跟1:1写法一致)

        4. 在测试类中调用方法名即可

动态SQL注解

方式一 :脚本sql注解

方式二:动态sql注解

在方法中构建动态sql语句

⭐️⭐️⭐️方式三:构造器注解

生成动态sql语句,将方式二进行封装-- 构造器(须创建内部类)

​​

 //内部类
 class StudentSql {
     //查询
     public String getGZQSelectStudentSql (Student s){
         return new SQL() {
             {
                 //字段名
                 SELECT("sid,sname");
                 SELECT("birthday");
                 SELECT("ssex,classid");
                 FROM("student");
 ​
                 if (s.getSsex() != null) {
                     WHERE("ssex=#{ssex}");
                 }
                 if (s.getClassid() != 0) {
                     WHERE("classid=#{classid}");
                 }
             }
         }.toString();
     }
     //新增
     public String getGZQAddStudentSql(Student s){
         return new SQL(){
             {
                 INSERT_INTO("student");
                 if (s.getSname() != null) {
                     VALUES("sname","#{sname}");
                 }
                 if (s.getBirthday() != null) {
                     VALUES("birthday","#{birthday}");
                 }
                 if (s.getClassid() != 0) {
                     VALUES("classid","#{classid}");
                 }
                 if (s.getSsex() != null) {
                     VALUES("ssex","#{ssex}");
                 }
             }
         }.toString();
     }
     //修改
     public String getGZQUpdateStudentSql(Student s){
         return new SQL(){
             {
                 UPDATE("student");
                 if (s.getSname() != null) {
                     SET("sname=#{sname}");
                 }
                 if (s.getBirthday() != null) {
                     SET("birthday=#{birthday}");
                 }
                 if (s.getClassid() != 0) {
                     SET("classid=#{classid}");
                 }
                 if (s.getSsex() != null) {
                     SET("ssex=#{ssex}");
                 }
                 WHERE("sid=#{sid}");
             }
         }.toString();
     }
     //删除
     public String getGZQDeleteStudentSql(Student s){
         return new SQL(){
             {
                 DELETE_FROM("student");
                 WHERE("sid=#{v}");
             }
         }.toString();
     }
 }
 }

@Insert ,@Delete,@Update,@Select 注解的功能

• 分别完成新增,删除,修改和查询操作;

@Results 注解和 @ResultMap 注解的功能

• @Results 定义结果映射,@ResultMap 调用对应的结果映射;

动态SQL的注解

@SelectProvider 查询语句的动态SQL,@InsertProvider 新增语句的动态SQL, @DeleteProvider 删除语句的动态SQL,@UpdateProvider 修改语句的动态SQL;

SQL 语句构造器的功能

• 解决 Java 代码中嵌入 SQL 语句,通过简单地创建一个实例来调用方法生成SQL语句;

分页

方式1:物理分页

使用Map集合来保存分页需要数据,来进行分页

方式2: 逻辑分页

使用RowBounds集合来保存分页需要数据,来进行分页

⭐️⭐️⭐️方式3: 分页插件分页

  • 引入依赖

 <dependency>
        <groupId>com.github.pagehelper</groupId>
        <artifactId>pagehelper</artifactId>
        <version>4.1.3</version>
</dependency>
  • mybatis.xml配置

     <plugins>
         <plugin interceptor="com.github.pagehelper.PageHelper">
         </plugin>
     </plugins>
  • mapper接口

  • 测试类

 Page<Object> pageHeper = PageHelper.startPage(1, 10);
         //在查询前面加上PageHeper就可以
         List<StudentBean> list = studentMapper.seectAllOneofOne();
         //pageinfo更详细的分页信息
         PageInfo<StudentBean> studentBeanPageInfo = new PageInfo<>(list);
         list.forEach(System.out::println);
         //pageHeper分页信息
         System.out.println(pageHeper);
         System.out.println("------------------------------");
         //info详细信息
         System.out.println(studentBeanPageInfo);
  • 结果

    image-20240801114813455

延迟加载和立即加载

mybatis默认的立即加载

立即加载

不管用不用信息,只要调用,马上发起查询并进行加载

通常:当 一对一或者 多对一的时候需要立即加载

延迟加载

在真正使用数据时才发起查询,不用的时候不查询,按需加载(也叫懒加载)

通常: 一对多,或者多对多的是需要使用延迟加载

缓存

⭐️⭐️⭐️一级缓存

⭐️概念

缓存(cache),数据交换的缓冲区,当应用程序需要读取数据时,先从数据库中将数据取出,放置在 缓冲区中,应用程序从缓冲区读取数据

特点

数据库取出的数据保存在内存中,具备快速读取和使用。

限制

读取时无需再从数据库获取,数据可能不是最新的;

术语

什么是 MyBatis 缓存

通过配置和定制,减少 Java Application 与数 据库的交互次数,从而提升程 序的运行效率。

⭐️⭐️缓存的适用性

  • 适合用缓存

    • 经常查询并且不经常改变的

    • 数据的正确与否对最终结果影响不大的

比如:一个公司的介绍,新闻等

  • 不适合用缓存:

    • 经常改变的数据

    • 数据的正确与否对最终结果影响很大

比如:商品的库存,股市的牌价等

⭐️⭐️⭐️⭐️缓存分类
一级缓存 (sqlsession缓存)

会话 session 级别的缓存,针对一次会话操作内;

默认开启,一级缓存只是相对同一个 SqlSession 对象而言

image-20240801120846542

二级缓存

映射器级别的缓存,针对不同 Namespace 的映射器;

一个 namespace 下的所有操作语句,都影响着同一个Cache;

自定义缓存

根据各类不同的缓存机制,自定义 缓存的实现方式。

自定义缓存的方式

实现 org. apache. ibatis. cache. Cache 接口自定义缓存;

引入 Redis 等第三方内存库作为 MyBatis 缓存。

知识点

1. 补充一对一、一对多 resultMap的使用

一对多(一个班级对应多个学生)
  <collection/>标签完成一对多映射
  ofType="" 指定要创建的类型
  
  <resultMap id="class_stu_map" type="Classbean">
         <result column="classid" property="classid"/>
         <result column="classname" property="classname"/>
         <!--
             一对多(一个班级对应多个学生)
              <collection/>标签完成一对多映射
              ofType="" 指定要创建的类型
         -->
         <collection property="stu" ofType="Student">
             <result column="sid" property="sid"/>
             <result column="sname" property="sname"/>
             <result column="birthday" property="birthday"/>
             <result column="ssex" property="ssex"/>
             <result column="classid" property="classid"/>
         </collection>
     </resultMap>
     <select id="findClassAndStu" resultMap="class_stu_map">
         select * from class
             left join student on class.classid = student.classid
     </select>
 <!--   一对一 : 查询课程和老师信息-->
     <resultMap id="course_tea_map" type="Course">
         <result column="cid" property="cid"/>
         <result column="cname" property="cname"/>
         <result column="tid" property="tid"/>
         <association property="teacher" >
                 <result column="tid" property="tid"/>
                 <result column="tname" property="tname"/>
                 <result column="tsex" property="tsex"/>
                 <result column="tbirthday" property="tbirthday"/>
                 <result column="taddress" property="taddress"/>
                 <result column="temail" property="temail"/>
                 <result column="tmoney" property="tmoney"/>
         </association>
     </resultMap>
 ​
     <select id="findCourseAndTeacher" resultMap="course_tea_map">
         select * from course
             left join teacher on course.tid=teacher.tid
     </select>
 单表  resultmap可以只写映射不上的
 ​
 <resultMap type="SMaster" id="sm_map">
         <result column="sm_name" property="smname"/>
     </resultMap>
     <select id="findSmasterAll" resultMap="sm_map">
         select * from schoolmaster
     </select>

2. 查询多参的方式

 //查询 某个班的某个性别的学生 mybatis只能传一个参  
 //传递多参的方式一: javaBean对象(推荐)  
public List<Student> findStudentByclassidAndssex(Student s);  
 //传递多参的方式二+分页: Map(不推荐,耦合度高)  
public List<Student> findStudentByclassidAndssexLimit(Map<String,Object> map);  
//传递多参的方式三+分页: param数(数是从1开始 推荐使用)  
//按照顺序 和接口输入参数的顺序要保持一致  
public List<Student> findStudentByclassidAndssexLimitParam(int classid,String ssex,int ys,int bc);  
//传递多参的方式四+分页:arg(数是从0开始 不推荐 )  
public List<Student> findStudentByclassidAndssexLimitArg(int classid,String ssex,int ys,int bc);

3. 主键回填

主键回填:新增的时候,mybatis会获取主键的值,传回给Java对象和主键的属性中
 useGeneratedKeys="true" 开启主键回填
 keyProperty="sid" 回填的主键要给哪个属性

 4. choose和set标签

​​​​​​​choos标签
         相当于java中的 switch 结构
         条件有先后顺序,越优先越要写,一旦匹配到了,后面的条件将不会再执行
         when是条件,自带break
         otherwise是当所有的when都不执行,才会匹配
  set标签
         1.添加set关键词
         2.去掉最后一个逗号

5. 模糊查询

 (1)方案一 concat 推荐
 select * from where sname like concat('%',#{v},'%')

 (2)方案二 业务层解决模糊符号 不推荐
 select * from student where sname like #{v}

 (3)方案三 sql语法
 select * from student where sname like "%"#{v}"%"

 (4)方案四 ${} 不推荐
 select * from student where sname like '%${v}%'
 #{} 预处理sql语句 ?占位 preparedstatment 进行防止sql注入
 ${} 字符串的替换 不能防止sql注入

 (5)方案五 bind标签 用来定义变量
 <bind name="keyn" value="'%'+_parameter+'%'"/>
     select * from student where sname like #{keyn}

6. 二级缓存为什么用不了?

虽然实现了缓存数据的共享,但是在分布式环境(数据部署在多台服务器中)下会导致数据不一致。

7. 缓存失效

​​​​​​​​​​​​​​
  1. 同一个SqlSession两次查询期间手动clearcaChe(清空缓存)

  2. 同一个SqlSession两次查询期间执行了任何一次增删改操作

  3. 不使用同一个sqlSeession进行查询

  4. 同一个sqlsession查询条件不同

  • 13
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值