当前位置: 首页 > news >正文

java学习总结(四):MyBatis

一、MyBatis介绍

像MyBatis、Hibernate都是属于ORM框架

对象关系映射(英语:(Object Relational Mapping,简称ORM)

MySql、Oracle、SqlServer都是关系型数据库

1、O->R add/insert/save

studentDao.insert(student)

把一个java对象保存到数据库中的一行记录

2、R->O selectById/findById/listById

Student student = sudentDao.findById(id)

把数据库里面的一行记录封装成一个java对象

二、MyBatis执行流程

MappedStatement是MyBatis框架中的一个重要类,用于表示映射配置文件(Mapper XML文件)中的SQL语句。在MyBatis中,每个SQL语句都会被解析成一个MappedStatement对象,它包含了SQL语句的相关信息,如ID、参数映射、结果映射、SQL语句类型等。

<select id="selectAll" resultType="Student">
    SELECT id, name, age, gender, banji_id FROM student
</select>
、读取MyBatis配置文件:mybatis-config.xml加载运行环境和映射文件
2、构造会话工厂SqlSessionFactory
3、会话工厂创建SqlSession对象(包含了执行SQL语句的所有方法)
4、操作数据库的接口,Executor执行器,同时负责查询缓存的维护
5、Executor接口的执行方法中有一个MappedStatement类型的参数,封装了映射信息
6、输入参数映射(Java类型转换为数据库支持的类型)
7、输出结果映射(数据库类型转化为Java类型)

三、MyBatis快速入门

@Test
public void testSelectById() throws IOException {
   String resource = "mybatis.xml";
   InputStream inputStream = Resources.getResourceAsStream(resource);
   // 创建 SqlSessionFactory    Session:会话 (连接数据库后就建立了一次会话,有了会话就可以操作数据库)
   SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
   // 得到SqlSession
   SqlSession sqlSession = sqlSessionFactory.openSession();
   // 执行sql语句
   Student student = sqlSession.selectOne("student.selectById", 59);
   System.out.println(student);
}

四、封装工具类

public class MyBatisUtil {
    private static SqlSessionFactory sqlSessionFactory;
    
    //静态代码块中的代码只会执行一次
    static {
        try {
            String resource = "mybatis.xml";
            InputStream inputStream;
            inputStream = Resources.getResourceAsStream(resource);
            // 创建 SqlSessionFactory    Session:会话 (连接数据库后就建立了一次会话,有了会话就可以操作数据库)
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static SqlSession getSqlSession() {
        // 得到SqlSession
        SqlSession sqlSession = sqlSessionFactory.openSession();
        return sqlSession;
    }
}

@Test
public void testSelectById1() throws IOException {
   SqlSession sqlSession = MyBatisUtil.getSqlSession();
   // 执行sql语句
   Student student = sqlSession.selectOne("student.selectById", 66);
   System.out.println(student);
}

五、typeAliases类型别名

上图是mybatis3.3.0官方文档上提供的别名和java类型的映射关系

int/Integer/ineger

在配置int时通过上表可以看出,即可以是java中的基本类型int,也可以是java中的包装类型Integer,不过在配置为包装类型是必须是java.lang.Integer,所以在配置为int是我们的java接口中的参数类型最好是Integer的。

string/String :对应java中的java.lang.String

map :对应java.util.Map

hashmap :对应java.util.HashMap

list :对应java.util.List

arraylist :对应java.util.ArrayList

<settings>
    <!-- 下划线字段对应实体类驼峰命名 数据库表:banji_id 映射到类里面:banjiId -->
    <setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>

<typeAliases>
     <!--
     <typeAlias alias="Student" type="com.situ.mybatis.pojo.Student"/>
     <typeAlias alias="Banji" type="com.situ.mybatis.pojo.Banji"/> -->
     <!-- 扫描包里面的类,批量起别名,别名即类名,不区分大小写 -->
     <package name="com.situ.mybatis.pojo"/>
</typeAliases>

六、基本增删改查的操作

<mapper namespace="student">

    <!-- public Student selectById(Integer id) {}
       parameterType="java.lang.Integer"
       resultType="com.situ.mybatis.pojo.Student"
    -->
    <select id="selectById"  parameterType="Integer" resultType="Student">
       SELECT id,name,age,gender,banji_id FROM student where id=#{id}
    </select>

    <!--public List<Student> selectAll();-->
    <select id="selectAll" resultType="Student">
       SELECT id,name,age,gender,banji_id FROM student
    </select>

    <!-- 对于更新类的操作返回的是影响的行数,但是resultType不需要写
     public int deleteById(Integer id)
     更新类返回影响的行数,在这里不用写返回值类型
    -->
    <delete id="deleteById" parameterType="Integer">
       DELETE FROM student WHERE id=#{id}
    </delete>

    <!--public int add(Student student)-->
    <insert id="add" parameterType="Student" useGeneratedKeys="true" keyProperty="id">
       INSERT INTO
           student(name,age,gender,banji_id)
       VALUES
           (#{name},#{age},#{gender},#{banjiId})
    </insert>

    <update id="update" parameterType="Student">
       UPDATE
           student
       SET
           name=#{name},
           age=#{age},
           gender=#{gender},
           banji_id=#{banjiId}
       WHERE
           id=#{id}
    </update>
</mapper>
@Test
public void testDeleteById() throws IOException {
   // Setting autocommit to false on JDBC Connection
   // JDBC默认autocommit值是true,MyBatis把JDBC的autocommit设置为false,
   // 当执行delete的时候并没有真正提交到数据库,对于更新类的操作需要手动提交。
   // 在JDBC里面默认不需要用户手动提交因为autocommit 默认就是true,执行executeUpdate
   // 的时候直接修改了数据库
   SqlSession sqlSession = MyBatisUtil.getSqlSession();
   int count = sqlSession.delete("student.deleteById", 59);
   System.out.println("count: " + count);
   // 对于更新类的操作需要手动提交
   sqlSession.commit();
   sqlSession.close();
}

七、Sql片段

<sql id="studentColumns">
   id,name,age,gender,banji_id
</sql>

<!-- 通过id查找学生 refid reference-->
<select id="selectById" parameterType="Integer" resultType="Student">
    SELECT <include refid="studentColumns"/>
    FROM student
    WHERE id = #{id}
</select>

八、输入映射

parameterType(输入类型)
  1. 传递简单类型:selectById(Integer id)
使用时候#{id}
  1. 传递实体类:add(Student student)
使用时候#{age}括号中的值为实体类中属性的名字。
  1. 传递Map(传递过个参数)
@Test
public void testSelectByPage() throws IOException {
   SqlSession sqlSession = MyBatisUtil.getSqlSession();
   int pageNo = 2;
   int pageSize = 3;
   int offset = (pageNo - 1) * pageSize;
   Map<String, Integer> map = new HashMap<String, Integer>();
   map.put("offset", offset);
   map.put("pageSize", pageSize);
   List<Student> list = sqlSession.selectList("student.selectByPage", map);
   for (Student student : list) {
     System.out.println(student);
   }
}
<select id="selectByPage" parameterType="Map" resultType="Student">
   SELECT <include refid="studentColumns"/> 
   FROM  student 
   LIMIT #{offset},#{pageSize}
</select>

九、输出映射

1、基本数据类型:

查找一共有多少学生

<select id="selectTotalCount" resultType="Integer">
   SELECT count(*) FROM student
</select>

@Test
public void testSelectTotalCount() throws IOException {
   SqlSession sqlSession = MyBatisUtil.getSqlSession();
   int count = sqlSession.selectOne("student.selectTotalCount");
   System.out.println("count: " + count);
}

2、输出实体类:Student

3、输出集合:List

resultMap

如果查询出来的列名和实体类的属性不一致,通过定义一个resultMap对列名和实体类属性名做一个映射关系。

resultMap 元素是 MyBatis 中最重要最强大的元素。

结果集的映射是 MyBatis 最强大的特性,对其有一个很好的理解的话,许多复杂映射的情形都能迎刃而解。使用 resultMap 或 resultType,但不能同时使用。

<!-- resultMap最终是要将结果映射到Student上
当实体类的属性名和表的字段名不一致的时候,必须要写这个映射 -->
<resultMap type="Student" id="studentMap">
   <!-- 映射主键属性:如果有多个主键字段,则定义多个id -->
   <!-- property:类的属性名 -->
   <!-- column:表的字段名 -->
   <id column="id" property="id" />
   <!-- result定义普通属性 -->
   <result column="student_name"  property="name" />
   <result column="age" property="age" />
   <result column="gender" property="gender" />
</resultMap>

<select id="selectAll" resultMap="studentMap">
   select id,student_name,age,gender from student
</select>

相关文章:

  • 低成本抗衡DeepSeek-R1!QwQ-32B本地部署教程:消费级硬件可部署
  • 分布式事务中TCC、SAGA 或可靠消息事务应该如何理解?
  • WPS的Excel文档如何利用VB脚本批量替换超链接的内容
  • Linux 》》Ubuntu 18 LTS 之后的版本 修改IP地址 主机名
  • TypeScript 中 interface 与 type的使用注意事项 及区别详细介绍
  • TypeScript深度解析:从类型系统到工程化实践
  • MCP服务协议详细介绍
  • 【Windows】Wan 2.1 视频生成模型本地部署
  • xxl-job部署在docker-destop,实现定时发送预警信息给指定邮箱
  • 年龄与疾病(信息学奥赛一本通-1106)
  • Qt C++ 常用压缩库推荐 快速压缩 解压缩数据
  • Java是怎么解决并发问题的?
  • 高效图像处理工具:从需求分析到落地实现
  • 【vue + JS】OCR图片识别、文字识别
  • react对比vue的核心属性
  • 2340单点修改、区间查询
  • 独立开发记录:使用Trae和Cloudflare快速搭建了自己的个人博客
  • 深度学习与大模型-矩阵
  • 解数独 (leetcode 37
  • 生化混合智能技术(Biochemical Hybrid Intelligence, BHI)解析与应用
  • 王楚钦球拍受损,乒乓球裁判揭秘大赛球拍检测
  • 国家发改委:正在会同有关方面,加快构建统一规范、协同共享、科学高效的信用修复制度
  • 中国戏剧梅花奖终评结果公示,蓝天和朱洁静等15名演员入选
  • 老旧小区加装电梯后续维护谁负责?上海:各区属房管集团托底保障
  • 苏丹港持续遭无人机袭击,外交部:呼吁各方保护民用设施和平民安全
  • 上海发文加强直播经济技能人才培养:三年新培养持证直播技能人才5万名