Mybatis03学习笔记

news2024/10/5 20:25:22

目录

使用注解开发

设置事务自动提交

mybatis运行原理

注解CRUD

lombok使用(偷懒神器,大神都不建议使用)

复杂查询环境(多对一)

复杂查询环境(一对多)

动态sql环境搭建

动态sql常用标签

    


使用注解开发

注解本质是反射机制,使用注解可以使得代码内容得到简化,注解可以取代注册文件UUserMapper.xml

如下面定义接口,在接口上方定义注解写sql语句

public interface UserMapper {
    @Select("select * from user")
    List<User> getUsers();
}

需要在核心配置文件绑定接口

设置事务自动提交

基于源码

 

我们可以设置事务自动提交

SqlSession  sqlSession=sqlSessionFactory.openSession(true);

mybatis运行原理

 

注解CRUD

查询所有用户

接口

@Select("select * from user")
List<User> getUsers();

测试

@Test
public void getUsers(){
    SqlSession sqlSession= MybatisUtils.getSqlSession();
    UserMapper mapper=sqlSession.getMapper(UserMapper.class);
    List<User> users=mapper.getUsers();
    for(User user:users){
        System.out.println(user);
    }
    sqlSession.close();
}

根据id查询用户

接口

@Select("select * from user where id=#{35342}")
    User getUserById(@Param("35342") int id);

测试

public void getUsers(){
    SqlSession sqlSession= MybatisUtils.getSqlSession();
    UserMapper mapper=sqlSession.getMapper(UserMapper.class);

    User userById=mapper.getUserById(1);
    System.out.println(userById);
    sqlSession.close();
}

增加用户

接口

@Insert("insert into user(id,name,pwd) values(#{id},#{name},#{pwd})")
    int addUser(User user);

测试

SqlSession sqlSession= MybatisUtils.getSqlSession();
UserMapper mapper=sqlSession.getMapper(UserMapper.class);
mapper.addUser(new User(12,"hello","Ssdd"));


修改用户信息

接口

@Update("UPDATE USER set NAME=#{name},PWD=#{pwd} where id=#{id}")
int updateUser(User user);

测试

SqlSession sqlSession= MybatisUtils.getSqlSession();
UserMapper mapper=sqlSession.getMapper(UserMapper.class);
mapper.updateUser(new User(12,"ttt","12443"));

删除用户

接口

@Delete("delete from user where id=#{id}")
int delUser(int id);

测试

SqlSession sqlSession= MybatisUtils.getSqlSession();
UserMapper mapper=sqlSession.getMapper(UserMapper.class);
mapper.delUser(12);

接口总的代码:

package com.dao;

import com.pojo.User;
import org.apache.ibatis.annotations.*;

import java.util.List;
import java.util.Map;

public interface UserMapper { 
    @Select("select * from user")
    List<User> getUsers();
//    通过id查询
@Select("select * from user where id=#{35342}")
    User getUserById(@Param("35342") int id);
@Insert("insert into user(id,name,pwd) values(#{id},#{name},#{pwd})")
    int addUser(User user);
@Update("UPDATE USER set NAME=#{name},PWD=#{pwd} where id=#{id}")
int updateUser(User user);
@Delete("delete from user where id=#{id}")
int delUser(int id);
}

测试总的代码:

import com.dao.UserMapper;
import com.pojo.User;
import com.utils.MybatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
import java.util.List;
public class test {
    @Test
    public void getUsers(){
        SqlSession sqlSession= MybatisUtils.getSqlSession();
        UserMapper mapper=sqlSession.getMapper(UserMapper.class);
        List<User> users=mapper.getUsers();
        for(User user:users){
            System.out.println(user);
        }
        User userById=mapper.getUserById(1);
        System.out.println(userById);
        mapper.updateUser(new User(12,"ttt","12443"));
        mapper.addUser(new User(12,"hello","Ssdd"));
        mapper.delUser(12);
        sqlSession.close();
    }
}

关于@Params()注解:

有多个参数则所有参数前一定要加上@Params()

lombok使用(偷懒神器,大神都不建议使用)

自动帮我们优化一些变量,但是会淡化我们对源码的理解

使用:导入jar包,在实体类上方加注解即可

@Data取代getter和setter方法

@AllArgsConstructor生成所有有参构造

@NoArgsConstructor生成所有无参构造

@ToString

如可以帮助我们写get,set,toString方法等

 

复杂查询环境(多对一)

实体类准备

//多对一
@Data
@ToString
public class Student {
    private int id;
    private String name;
    private Teacher teacher;
}
@Data
@ToString
public class Teacher {
    private int id;
    private String name;
   
}

tid是一个外键,用通常的方法:写接口-配置的xml文件-测试类查询student表信息,,这种方法查出来无法查到具有复制属性的tid

因此我们应该在Student.xml文件中通过某种方式关联上复杂属性tid才能查出来,下面有两种方式:

1.类似子查询方式

 Test.java代码:

public void testStudent(){
    SqlSession sqlSession=MybatisUtils.getSqlSession();
    StudentMapper mapper1=sqlSession.getMapper(StudentMapper.class);
    List<Student> studentList=mapper1.getStudent();
    for(Student student:studentList){
        System.out.println(student);
    }
    sqlSession.close();

}

Student.xml代码:

<!--通过子查询方式-->
    <select id="getStudent" resultMap="StudentTeacher" >
        select * from student
    </select>
    <!--    结果集查询-->
    <resultMap id="StudentTeacher" type="com.pojo.Student">
        <result property="id" column="id"/>
        <result property="name" column="name"/>
    <!--        复制的属性tid是外键,要单独处理-->
        <association property="teacher" column="tid" javaType="com.pojo.Teacher" select="getTeacher"/>
    </resultMap>
    <select id="getTeacher" resultType="com.pojo.Teacher">
        select * from teacher where id=#{id}
    </select>

2.结果集映射方式

 Test.java代码不变,Student.xml代码:

<!--    通过结果嵌套处理-->
    <select id="getStudent" resultMap="StudentTeacher2">
        select s.id sid,s.name sname,t.name tname
        from student s,teacher t where s.tid=t.id;
    </select>
    <resultMap id="StudentTeacher2" type="com.pojo.Student">
        <result property="id" column="sid"/>
        <result property="name" column="sname"/>
        <association property="teacher" javaType="com.pojo.Teacher">
            <result property="name" column="tname"/>
        </association>
    </resultMap>

查询结果:

 

复杂查询环境(一对多)

实体类准备

//一对多
@Data
@ToString
public class Student {
    private int id;
    private String name;
    private int tid;
}

@Data
@ToString
public class Teacher {
    private int id;
    private String name;
    //一个老师拥有的学生集合
    private List<Student> students;
}

   TeacherMapper接口代码:

//获取指定老师下的所有学生
Teacher getTeacher(@Param("tid") int id);

  TeacherMapper.xml代码

<!--    方式一按结果嵌套查询-->
    <select id="getTeacher" resultMap="TeacherStudent">
        select s.id sid,s.name sname,t.name tname,t.id tid
        from student s,teacher t
        where s.tid=t.id and t.id=#{tid}
    </select>

    <resultMap id="TeacherStudent" type="com.pojo.Teacher">
        <result property="id" column="tid"/>
        <result property="name" column="tname"/>
<!--        实体类teacher还有一个学生集合的属性,javaType指定属性的类型
复杂属性我们要单独处理,集合中泛型得到信息用ofType获取, private List<Student>-->
        <collection property="students" ofType="com.pojo.Student">
            <result property="id" column="sid"/>
            <result property="name" column="sname"/>
            <result property="tid" column="tid"/>
        </collection>
    </resultMap>
<!--    方式二按子查询-->
    <select id="getTeacher" resultMap="TeacherStudent">
        select * from mybatis.teacher where id=#{tid}
    </select>
    <resultMap id="TeacherStudent" type="com.pojo.Teacher">
        <collection property="students" javaType="ArrayList" ofType="Student" select="getStudentByTeacherId" column="id"/>
    </resultMap>

    <select id="getStudentByTeacherId" resultType="com.pojo.Student">
        select * from mybatis.student where tid=#{tid}
    </select>

测试代码

public void test() {
    SqlSession sqlSession = MybatisUtils.getSqlSession();
    TeacherMapper mapper = sqlSession.getMapper(TeacherMapper.class);
    Teacher teacher = mapper.getTeacher(1);
    System.out.println(teacher);
    sqlSession.close();
}

查询结果:

 关于type,resultType, ofType,javaType:

1.type在resultMap标签中使用

2.resultType用于select标签中,表示sql语句返回的对应在Java中的类型

2.ofType用来指定映射到List或集合中的pojo的类型,泛型中的约束类型

3.javaType是用来指定实体类的属性的类型

动态sql环境搭建

这部分相当于回顾之前所学

编写获取UUID的工具类

public class IDutils {
    public static String getId(){
        return UUID.randomUUID().toString().replaceAll("-","");
    }
//    @Test
//    public void test(){
//        System.out.println(IDutils.getId());
//    }
}

编写java映射数据库ORM实体类

public class Blog {
    private String id;
    private String title;
    private String author;
    private Date createTime; //属性和字段不一致
    private int views;
}

编写添加接口BlogMapper

public interface BlogMapper {
    int addBlog(Blog blog);
}

BlogMapper.xml注册sql文件

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.dao.BlogMapper">
    <insert id="addBlog" parameterType="com.pojo.Blog">
        insert into mybatis.blog(id,title,author,create_time,views)
        values(#{id},#{title},#{author},#{createTime},#{views});
    </insert>
</mapper>

测试代码:

public class Test {
    @org.junit.Test
    public void addInitBlog(){
        SqlSession sqlSession= MybatisUtils.getSqlSession();
        BlogMapper mapper=sqlSession.getMapper(BlogMapper.class);
        Blog blog=new Blog();
        blog.setId(IDutils.getId());
        blog.setTitle("MyBATIS如此简单");
        blog.setAuthor("狂");
        blog.setCreateTime(new Date());
        blog.setViews(9999);
        mapper.addBlog(blog);

        blog.setId(IDutils.getId());
        blog.setTitle("java如此简单");
        mapper.addBlog(blog);
        
        blog.setId(IDutils.getId());
        blog.setTitle("spring如此简单");
        mapper.addBlog(blog);

        blog.setId(IDutils.getId());
        blog.setTitle("vue如此简单");
        mapper.addBlog(blog);

        sqlSession.close();
    }
}

测试结果:

 

动态sql常用标签

<if>标签测试

接口

List<Blog> queryBlogIF(Map map);

对应注册文件

if标签如果满足标签内部的条件,就执行

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.dao.BlogMapper">
    <insert id="addBlog" parameterType="com.pojo.Blog">
        insert into mybatis.blog(id,title,author,create_time,views)
        values(#{id},#{title},#{author},#{createTime},#{views});
    </insert>
    <select id="queryBlogIF" parameterType="map" resultType="com.pojo.Blog">
        select * from mybatis.blog where 1=1
        <if test="title !=null">
            and title=#{title}
        </if>
        <if test="author !=null">
            and author=#{author}
        </if>
    </select>
</mapper>

测试代码

public class Test {
    @org.junit.Test
    public  void queryBlogIF(){
        SqlSession sqlSession=MybatisUtils.getSqlSession();
        BlogMapper mapper=sqlSession.getMapper(BlogMapper.class);
        List<Blog> blogs=mapper.queryBlogIF(new HashMap());
        for(Blog blog:blogs){
            System.out.println(blog);
        }
    }
}

choose(when,otherwise)

<select id="queryBlogChoose" parameterType="map" resultType="com.pojo.Blog">
    select * from mybatis.blog
    <choose>
        <when test="title!=null">
            title=#{title}
        </when>
        <when test="author!=null">
            and author=#{author}
        </when>
        <otherwise>
            and views=#{views}
        </otherwise>
    </choose>
</select>

测试代码

@org.junit.Test
public void queryBlogChoose(){
    SqlSession sqlSession=MybatisUtils.getSqlSession();
    BlogMapper mapper=sqlSession.getMapper(BlogMapper.class);
    Map map=new HashMap();
    List<Blog> blogs=mapper.queryBlogIF(map);
    for(Blog blog:blogs){
        System.out.println(blog);
    }
    sqlSession.close();

}

trim(where,set)

1.where元素只会在至少一个子元素的条件返回sql子句的情况下才去插入where子句,而且若语句开头为and或者or,where元素会自动将其去掉,如:

 

2.set+<update>标签

接口

int updateBlog(Map map);

xml代码

<update id="updateBlog" parameterType="map">
    update mybatis.blog
    <set>
        <if test="title!=null">
            title=#{title},
        </if>
        <if test="author!=null">
            author=#{author}
        </if>
    </set>
    where id=#{id}
</update>

测试代码

public void updateBlog(){
    SqlSession sqlSession=MybatisUtils.getSqlSession();
    BlogMapper mapper=sqlSession.getMapper(BlogMapper.class);
    Map map=new HashMap();
    map.put("title","vue如此简单2"); //相当于显示条件,只查找title="java如此简单"的记录
    map.put("id","0ae64f7aa9c94d2e8b10046d902dc4cd");
    mapper.updateBlog(map);
    sqlSession.close();
}

运行结果:

 解决代码冗余<sql>标签和<include>标签

将重复的代码提取出来用sql标签包装,在需要使用的地方用include标签使用

<foreach>标签

接口

List<Blog> queryBlogForEach(Map map);

xml代码

<select id="queryBlogForEach" parameterType="map" resultType="com.pojo.Blog">
    select * from mybatis.blog
    <where>
        <foreach collection="ids" item="id" open="and (" close=")" separator="or">
            id=#{id}
        </foreach>
    </where>
</select>

测试代码

@org.junit.Test
public void queryBlogForEach(){
    SqlSession sqlSession=MybatisUtils.getSqlSession();
    BlogMapper mapper=sqlSession.getMapper(BlogMapper.class);
    Map map=new HashMap();
    ArrayList<Integer> ids=new ArrayList<Integer>();//存放interger的一个列表list
    ids.add(1);
    ids.add(2);
    map.put("ids",ids);
    List<Blog> blogs=mapper.queryBlogForEach(map);
    for(Blog blog:blogs){
        System.out.println(blog);
    }
    sqlSession.close();
}

    

运行结果

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/416521.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Unity Game FrameWork—模块使用—对象池分析

官方说明&#xff1a;提供对象缓存池的功能&#xff0c;避免频繁地创建和销毁各种游戏对象&#xff0c;提高游戏性能。除了 Game Framework 自身使用了对象池&#xff0c;用户还可以很方便地创建和管理自己的对象池。 下图是Demo中用到的对象池&#xff0c;所有的实体以及UI都使…

SpringBoot集成ChatGPT实现AI聊天

前言 ChatGPT已经组件放开了&#xff0c;现在都可以基于它写插件了。但是说实话我还真没想到可以用它干嘛&#xff0c;也许可以用它结合文字语音开发一个老人小孩需要的智能的说话陪伴啥的。 今天我就先分享下SpringBoot结合ChatGPT&#xff0c;先看看对话效果。 一、依…

清明-前端

明天面快手前端&#xff0c;正好借这个机会&#xff0c;做做毕设吧。顺便整理一下前端的面试内容。 何良蓉说&#xff0c;他觉得学的时候开心&#xff0c;玩的时候也开心。我觉得不开心。可能他掌握生活的秘密了吧。 如果他没对我撒谎的话。 看了眼别人的面经&#xff0c;就知…

一键禁用系统防火墙

你也可以通过批处理命令来实现 桌面空白地方右键选择新建记事本将下面代码复制到记事本里&#xff0c;然后保存为.bat类型的文件&#xff1b;保存完成运行即可。 Echo off Echo -------------------------------------------------------------------------- Echo 禁用系统防火…

【CSS】定位 ② ( 静态定位 | 相对定位 )

文章目录一、静态定位二、相对定位1、标准流下的盒子模型代码示例2、相对定位下的盒子模型代码示例一、静态定位 CSS 中的 静态定位 是 默认的定位方式 , 就是无定位 , 设置该定位方式 , 定位盒子不生效 ; 为盒子模型 设置 静态定位 模式 , 该 盒子模型 就会按照标准流的方式 …

【面试】spring中怎么解决循环依赖问题?

文章目录前言1、什么是循环依赖&#xff1f;2、Spring怎么解决循环依赖3、如何解决&#xff1f;4、怎么样的循环依赖无法处理?5、总结:前言 思考: 什么是循环依赖&#xff1f;Spring怎么解决循环依赖Spring对于循环依赖无法解决的场景 1、什么是循环依赖&#xff1f; 循环…

Run Loops

Run Loops 运行循环是与线程相关的基本基础结构的一部分。运行循环是事件处理循环&#xff0c;用于安排工作并协调传入事件的接收。运行循环的目的是在有工作要做时让线程保持忙碌&#xff0c;在没有工作要做时让线程休眠。 运行循环管理不是完全自动的。您仍然必须设计线程代…

【Java Web】012 -- SpringBootWeb综合案例(登录功能、登录校验、异常处理)

目录 一、登录功能 1、基础登录功能 ①、SQL语句 ②、接口参数 ③、实现思路 ④、实现步骤 2、联调Bug&#xff08;没有Cookie或Session&#xff09; 二、登录校验 1、登录校验的实现思路 2、会话技术 ①、会话与会话跟踪 ②、会话跟踪方案对比 Cookie Session …

C# 多线程编程

1 线程与进程 进程&#xff1a;进程可以理解为一块包含了某些些资源的内存区域&#xff0c;操作系统通过进程这一方式把他的工作划分为不同的单元。一个应用程序可以对应于多个进程。 线程&#xff1a;线程是进程中的独立执行单元&#xff0c; 对于操作系统而言&#xff0c;他…

【学习笔记】unity脚本学习(四)【inputManager、键盘输入、鼠标输入、Raycast】

目录输入inputManagerHorizontal虚拟轴的各个属性含义&#xff08;摘选自ChatGpt&#xff0c;部分回答不准确&#xff09;键值的含义键名称命名约定&#xff1a;键盘输入静态函数GetKeyGetButtonKeyCodeGetButton/Down/upGetAxisGetAxisRaw 返回由 axisName 标识的虚拟轴的值&a…

【Gradle-2】一文搞懂Gradle配置

1、前言 “Gradle的配置太多了&#xff0c;经常版本更新还有变化&#xff0c;而且它还能扩展&#xff0c;记是记不住了&#xff0c;只能用到再搜了&#xff0c;哎&#xff0c;难顶” 真的难顶&#xff0c;但是我想挑战一下… 本文介绍的重点&#xff1a; Gradle配置简介Grad…

slam与导航开发

Gmapping是一种基于激光雷达数据的地图构建算法&#xff0c;可以用于建立机器人的环境地图。 Gmapping算法是基于粒子滤波器&#xff08;Particle Filter&#xff09;的SLAM算法&#xff0c;它通过将机器人在环境中的位姿和地图中的特征进行联合估计&#xff0c;实现了机器人在…

个人使用mac OS和win OS的差异

苹果 macOS 操作系统和 Windows 操作系统在很多方面有所不同&#xff0c;主要体现在以下几个方面&#xff1a; 用户界面&#xff1a;macOS 和 Windows 的用户界面风格不同。macOS 推崇简洁、优雅的设计&#xff0c;注重操作体验&#xff1b;Windows 软件更为丰富&#xff0c;但…

Doris(1):Doris介绍

1 Doris简介 Apache Doris是一个现代化的基于MPP&#xff08;大规模并行处理&#xff09;技术的分析型数据库产品。简单来说&#xff0c;MPP是将任务并行的分散到多个服务器和节点上&#xff0c;在每个节点上计算完成后&#xff0c;将各自部分的结果汇总在一起得到最终的结果(…

最小生成树和最短路径及其他

还是学过的&#xff0c;主要用于复习q v q 一、最小生成树 最小生成树的定义 用于无向图中&#xff0c;无向图指的是没有带方向路径的图&#xff0c;给定n个点&#xff0c;m条边&#xff0c;如果将这些点依次相连&#xff0c;求出连接这些点的最小数值 应用场景 根据这个算…

9 个JSON.stringify的秘密大多数开发人员却不知道

作为前端开发工程师&#xff0c;你一定用过JSON.stringify&#xff0c;但你知道它的全部秘密吗&#xff1f; 很久以前&#xff0c;我因此在工作中犯下了无法挽回的错误。如果我早点知道&#xff0c;就不会发生这样的悲剧。 理解 JSON.stringify 基本上&#xff0c;JSON.stri…

神经网络辐射场NeRF、实时NeRF Baking、有向距离场SDF、占用网络Occupancy、NeRF 自动驾驶

1 NeRF原理2 NeRF加速PlenoxelsKiloNeRFInstant NGPTensoRF3 SDF NeRF4 Occupancy NeRF5 NeRF应用简介常见应用实际应用的挑战6 NeRF自动驾驶1 NeRF原理 NeRF (Neural Radiance Fields&#xff0c;神经辐射场) 是2020年ECCV会议上的Best Paper&#xff0c;其将隐式表达推上了…

安卓玩机搞机----移植第三方rom修复 第三方GSI系统修复bug综合解析【一】

很多朋友热衷与刷写第三方非当前机型官方系统的rom。和刷写第三方gsi等等。例如 米系列机型刷写Flyme 一加机型刷写miui oppo刷写gsi等等。 很多友友也会尝试自己移植第三方rom。但此类操作最大的问题在于修复可以开机后的bug&#xff0c;今天的教程综合说明下这类修复思路…

STM32F103RCT6

STM32F103RCT6是一款由STMicroelectronics公司生产的基于ARM Cortex-M3内核的32位微控制器。 它具有高性能、低功耗和广泛的应用领域。 包括ADC&#xff08;模数转换器&#xff09; DAC&#xff08;数字模拟转换器&#xff09; TIM&#xff08;定时器&#xff09; USART&#x…

Python 中 SyntaxError: ‘yield‘ outside function 错误

当我们在函数外部使用 yield 关键字时&#xff0c;会出现 Python “SyntaxError: ‘yield’ outside function”。 要解决该错误&#xff0c;如果我们需要对每个元素执行一些运算符&#xff0c;请使用列表理解&#xff0c;或者缩进函数内部使用 yield 的代码。 下面是一个产生…