一、基础实验——MyBatis 框架搭建

实验内容及步骤

创建数据库

在MySQL 中创建一个名称为mybatisdb 的数据库,并在该数据库中创建一个名称为user 的数据表,表结构如表5-1 所示:

  1. create table user
  2. (
  3. uid int auto_increment
  4. primary key,
  5. uname varchar(20) null,
  6. usex varchar(20) null
  7. );

创建maven项目

image.png

创建持久化类MyUser

创建一个名为com.mybatis.po 包,在该包中创建持久化类MyUser,类中声明的属性与数据表user 的字段一致

  1. @Data
  2. public class MyUser {
  3. String uname;
  4. String usex;
  5. int uid;
  6. }

创建映射文件

创建一个名为com.mybatis.mapper 的包,在该包中创建映射文件UserMapper.xml,并在其中配置操作数据库的SQL 语句,具体代码如下:

  1. <?xml version="1.0" encoding="UTF-8" ?>
  2. <!DOCTYPE mapper
  3. PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  4. "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  5. <mapper namespace="com.mybatis.mapper.UserMapper">
  6. <select id="selectUserById" parameterType="Integer"
  7. resultType="com.mybatis.po.MyUser">
  8. Select * from user where uid = #{uid}
  9. </select>
  10. <select id="selectAllUser" resultType="com.mybatis.po.MyUser">
  11. Select * from user
  12. </select>
  13. <insert id="addUser" parameterType="com.mybatis.po.MyUser">
  14. Insert into user (uname,usex) values(#{uname},#{usex})
  15. </insert>
  16. <update id="updateUser" parameterType="com.mybatis.po.MyUser">
  17. update user set uname=#{uname}, usex=#{usex} where uid=#{uid}
  18. </update>
  19. <delete id="deleteUser" parameterType="Integer">
  20. delete from user where uid = #{uid}
  21. </delete>
  22. </mapper>

创建配置文件

创建MyBatis 的核心配置文件mybatis-config.xml,在该文件中配置了数据库环境和映射文件的位置,具体代码如下:

  1. <?xml version="1.0" encoding="UTF-8" ?>
  2. <!DOCTYPE configuration
  3. PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
  4. "http://mybatis.org/dtd/mybatis-3-config.dtd">
  5. <configuration>
  6. <environments default="development">
  7. <environment id="development">
  8. <transactionManager type="JDBC"/>
  9. <dataSource type="POOLED">
  10. <property name="driver" value="com.mysql.jdbc.Driver"/>
  11. <property name="url"
  12. value="jdbc:mysql://????/mybatisdb"/>
  13. <property name="username" value="zhangkun"/>
  14. <property name="password" value="zhangkun"/>
  15. </dataSource>
  16. </environment>
  17. </environments>
  18. <mappers>
  19. <mapper resource="com/mybatis/mapper/UserMapper.xml"/>
  20. </mappers>
  21. </configuration>

image.png
(云数据库,数据库的url已打码)

创建测试类

创建一个名为com.mybatis.test 的包,在该包中创建测试类MyBatisTest,在其中使用输入流读取配置文件,然后根据配置信息构建SqlSesstionFactory 对象,再通过SqlSessionFactory 对象创建SqlSession 对象,并使用SqlSession 对象的方法执行数据库操作,部分代码如下:

  1. package com.mybatis.test;
  2. import com.mybatis.mapper.UserMapper;
  3. import com.mybatis.po.MyUser;
  4. import org.apache.ibatis.io.Resources;
  5. import org.apache.ibatis.session.SqlSession;
  6. import org.apache.ibatis.session.SqlSessionFactory;
  7. import org.apache.ibatis.session.SqlSessionFactoryBuilder;
  8. import java.io.IOException;
  9. import java.io.InputStream;
  10. import java.util.List;
  11. /**
  12. * @Author: 张坤
  13. * @DateTime: 2021/11/8 10:47
  14. * @Description: 该类用于 TODO
  15. */
  16. public class MyBatisTest {
  17. public static void main(String[] args){
  18. try {
  19. InputStream config= Resources.getResourceAsStream("mybatis-config.xml");
  20. SqlSessionFactory ssf= new SqlSessionFactoryBuilder().build(config);
  21. SqlSession ss=ssf.openSession();
  22. //查询一个用户
  23. MyUser mu = ss.selectOne("com.mybatis.mapper.UserMapper.selectUserById", 1);
  24. System.out.println(mu);
  25. //添加一个用户
  26. MyUser addmu=new MyUser();
  27. addmu.setUname("张三");
  28. addmu.setUsex("男");
  29. ss.insert("com.mybatis.mapper.UserMapper.addUser",addmu);
  30. ////修改一个用户
  31. mu.setUname("李四");
  32. UserMapper userMapper=ss.getMapper(UserMapper.class);
  33. userMapper.updateUser(mu);
  34. ////删除一个用户
  35. userMapper.deleteUser(addmu);
  36. ////查询所有用户
  37. List<MyUser> myUserList=userMapper.selectAllUser();
  38. System.out.println(myUserList.toString());
  39. ss.commit();
  40. ss.close();
  41. } catch (IOException e) {
  42. e.printStackTrace();
  43. }
  44. }
  45. }

这里有两种方法调用函数

  1. 调用session自带的函数

    1. SqlSession ss=ssf.openSession();
    2. MyUser mu = ss.selectOne("com.mybatis.mapper.UserMapper.selectUserById", 1);
  2. 调用userMapper的接口

    1. UserMapper userMapper=ss.getMapper(UserMapper.class);
    2. userMapper.updateUser(mu);

    实验总结

  3. 运行结果截图;

  4. 简述MyBatis 的工作原理;
  5. 简述MyBatis 和Hibernate 的异同点和优缺点;
  6. 碰到的问题及解决方案或思考;
  7. 实验收获及总结。

    二、提高实验——映射器

    实验内容及步骤

    元素中使用resultMap 属性,代码片段如下:

    1. <select id="selectResultMap" resultMap="myResult">
    2. Select * from user
    3. </select>

    修改测试代码,使用id 为selectResultMap 的select 操作完成查询,并记录运行结果;

    1. public class MyBatisTest {
    2. public static void main(String[] args){
    3. try {
    4. InputStream config= Resources.getResourceAsStream("mybatis-config.xml");
    5. SqlSessionFactory ssf= new SqlSessionFactoryBuilder().build(config);
    6. SqlSession ss=ssf.openSession();
    7. List<MapUser> mapUserList=ss.selectList
    8. ("com.mybatis.mapper.UserMapper.selectResultMap");
    9. for(MapUser mm:mapUserList){
    10. System.out.println(mm.toString());
    11. }
    12. ss.commit();
    13. ss.close();
    14. } catch (IOException e) {
    15. e.printStackTrace();
    16. }
    17. }
    18. }

    image.png

    实验总结

  8. 运行结果截图;

  9. 结合实验过程,总结MyBatis 实现查询时返回的结果集由集中常见的存储

方式;

  1. 碰到的问题及解决方案或思考;
  2. 实验收获及总结。

    三、扩展实验——级联查询

    实验内容及步骤

    一对一级联查询

    创建数据表

    在数据库中创建两张数据表:身份证表idcard,个人信息表person,创建代码如下: ```sql CREATE TABLE idcard ( id tinyint (2) NOT NULL AUTO_INCREMENT, code varchar(18) COLLATE utf8_unicode_ci DEFAULT NULL, PRIMARY KEY (id) ); CREATE TABLE person( id tinyint(2) NOT NULL, name varchar(20) DEFAULT NULL, age int(11) DEFAULT NULL, idcard_id tinyint(2) DEFAULT NULL, PRIMARY KEY (id), KEY idcard_id (idcard_id), CONSTRAINT idcard_id FOREIGN KEY (idcard_id) REFERENCES idcard (id) );

INSERT INTO mybatisdb.idcard (id, code) VALUES (1, ‘11’); INSERT INTO mybatisdb.idcard (id, code) VALUES (2, ‘22’); INSERT INTO mybatisdb.idcard (id, code) VALUES (3, ‘33’); INSERT INTO mybatisdb.person (id, name, age, idcard_id) VALUES (11, ‘张三’, 11, 1); INSERT INTO mybatisdb.person (id, name, age, idcard_id) VALUES (22, ‘李四’, 22, 2); INSERT INTO mybatisdb.person (id, name, age, idcard_id) VALUES (33, ‘王五’, 33, 2); INSERT INTO mybatisdb.person (id, name, age, idcard_id) VALUES (44, ‘赵六’, 44, 3);

  1. <a name="RBfjY"></a>
  2. #### 创建持久化类
  3. 创建对应的持久化类Idcard 和Person,代码如下:
  4. ```java
  5. package com.mybatis.po;
  6. @Data
  7. public class Idcard {
  8. int id;
  9. String code;
  10. }
  1. package com.mybatis.po;
  2. @Data
  3. public class Person {
  4. Integer id;
  5. String name;
  6. Integer age;
  7. Integer idcard_id;
  8. Idcard idCard;
  9. }@Data
  10. public class Person {
  11. int id;
  12. String name;
  13. int age;
  14. int idcard_id;
  15. }

打开延迟加载开关

在MyBatis 的核心配置文件mybatis-config.xml 中打开延迟加载开关,代码片段如下:
写在最前面(每个标签必须按顺序写,否则报错)

  1. <configuration>
  2. <!--在使用MyBatis嵌套查询方式进行关联查询时,使用MyBatis的延迟加载可以在一定程度上提高查询效率-->
  3. <settings>
  4. <!--打开延迟加载的开关-->
  5. <setting name="lazyLoadingEnabled" value="true"/>
  6. <!--将积极加载改为按需加载-->
  7. <setting name="aggressiveLazyLoading" value="false"/>
  8. </settings>
  9. ......
  10. </configuration>

创建映射文件

创建映射文件IdCardMapper.xml代码如下:

  1. <?xml version="1.0" encoding="UTF-8" ?>
  2. <!DOCTYPE mapper
  3. PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  4. "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  5. <mapper namespace="com.dao.IdCardDao">
  6. <select id="selectCodeById" parameterType="Intege" resultType="com.po.Idcard">
  7. select* from idcard where id=#{id}
  8. </select>
  9. </mapper>

创建映射文件PersonMapper.xml,并在其中以3 中方式实现“根据id 查询个人信息”的功能,具体代码如下:

  1. <?xml version="1.0" encoding="UTF-8" ?>
  2. <!DOCTYPE mapper
  3. PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  4. "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  5. <mapper namespace="com.mybatis.mapper.PersonMapper">
  6. <resultMap type="com.mybatis.po.Person" id="cardAndPerson1">
  7. <id property="id" column="id"/>
  8. <result property="name" column="name"/>
  9. <result property="age" column="age"/>
  10. <!--一对一级联查询-->
  11. <association property="idCard" column="idcard_id" javaType="com.mybatis.po.Idcard"
  12. select="com.mybatis.mapper.IdCardMapper.selectCodeById"/>
  13. </resultMap>
  14. <select id="selectPersonById1" parameterType="Integer" resultMap="cardAndPerson1">
  15. select* from person where id=#{id}
  16. </select>
  17. <!--一对一根据id查询个人信息:级联查询的第二种方法:嵌套结果,执行一个SQL-->
  18. <resultMap type="com.mybatis.po.Person" id="cardAndPerson2">
  19. <id property="id" column="id"/>
  20. <result property="name" column="name"/>
  21. <result property="age" column="age"/>
  22. <!--一对一级联查询-->
  23. <association property="idCard" javaType="com.mybatis.po.Idcard">
  24. <id property="id" column="idcard_id"/>
  25. <result property="code" column="code"/>
  26. </association>
  27. </resultMap>
  28. <select id="selectPersonById2" parameterType="Integer" resultMap="cardAndPerson2">
  29. select p.*,ic.code
  30. from person p, idcard ic
  31. where p.idcard_id=ic.id and p.id=#{id}
  32. </select>
  33. <!--一对一根据id查询个人信息:连接查询(使用PoJ0存储结果)-->
  34. <select id="selectPersonById3" parameterType="Integer" resultType="com.mybatis.pojo.SelectPersonById">
  35. select p.*,ic.code
  36. from person p, idcard ic
  37. where p.idcard_id=ic.id and p.id=#{id}
  38. </select>
  39. </mapper>

创建POJO 类

创建POJO 类com.pojo.SelectPersonById,代码片段如下

  1. package com.mybatis.pojo;
  2. @Data
  3. public class SelectPersonById {
  4. private Integer id;
  5. private String name;
  6. private Integer age;
  7. private String code;
  8. }

创建接口类

创建数据操作接口IdCardDao 以及其实现类,接口的具体代码如下:

  1. public interface IdCardMapper {
  2. public Idcard selectCodeById(int id);
  3. }

创建数据操作接口PersonDao 以及其实现类,接口的具体代码如下:

  1. public interface PersonMapper {
  2. public Person selectPersonById1 (Integer id);
  3. public Person selectPersonById2 (Integer id);
  4. public SelectPersonById selectPersonById3(Integer id);
  5. }

创建测试类

导入maven项目 junit用于测试

  1. <dependency>
  2. <groupId>org.junit.jupiter</groupId>
  3. <artifactId>junit-jupiter</artifactId>
  4. <version>RELEASE</version>
  5. <scope>compile</scope>
  6. </dependency>

创建测试类TestOneToOne 并记录运行结果,代码片段如下:

  1. public class TestOneToOne {
  2. @Test
  3. public void test() {
  4. InputStream config = null;
  5. try {
  6. config = Resources.getResourceAsStream("mybatis-config.xml");
  7. SqlSessionFactory ssf = new SqlSessionFactoryBuilder().build(config);
  8. SqlSession ss = ssf.openSession();
  9. PersonMapper personMapper = ss.getMapper(PersonMapper.class);
  10. Person pl = personMapper.selectPersonById1(11);
  11. System.out.println(pl);
  12. System.out.println("==============================");
  13. Person p2 = personMapper.selectPersonById2(11);
  14. System.out.println(p2);
  15. System.out.println("===============================");
  16. SelectPersonById p3 = personMapper.selectPersonById3(11);
  17. System.out.println(p3);
  18. } catch (IOException e) {
  19. e.printStackTrace();
  20. }
  21. }
  22. }

点击函数声明左侧的按钮开启测试
image.png
测试结果如下:
image.png

实验总结:

  1. 运行结果截图;
  2. 碰到的问题及解决方案或思考;
  3. 实验收获及总结。