Mybatis

Mybatis

第一个Mybatis案例

创建maven总工程,引入mybatis需要的jar包
<dependencies>
        <!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.4.6</version>
        </dependency>
        
        <!-- https://mvnrepository.com/artifact/junit/junit -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
        <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.16</version>
        </dependency>

        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>
配置总配置文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">

<configuration>
    <settings>
        <!-- 开启log4j来记录日志 -->
        <setting name="logImpl" value="LOG4J"/>
    </settings>
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/test01?characterEncoding=utf-8&amp;serverTimezone=UTC&amp;useSSL=false"/>
                <property name="username" value="lcf"/>
                <property name="password" value="123456"/>
            </dataSource>
        </environment>
    </environments>
    <!--配置mapper xml-->
    <mappers>
        <mapper resource="com/lcf/dao/UserDao.xml"/>
    </mappers>
</configuration>
工具类实现
//工具类
public class MybatisUtils {
    private static SqlSessionFactory sqlSessionFactory;
    static {
        InputStream inputStream = null;
        try {
            //使用mybatis的一步,获取sqlSessionFactory
            String resource = "mybatis-config.xml";
            inputStream = Resources.getResourceAsStream(resource);
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
    public static SqlSession getSqlSession(){
       return sqlSessionFactory.openSession();
    }
}
实现实体类

实体类的字段要与mysql表格字段一致

public class User {
    private int id ;
    private String name ;
    private String pwd;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getPwd() {
        return pwd;
    }

    public void setPwd(String pwd) {
        this.pwd = pwd;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", pwd='" + pwd + '\'' +
                '}';
    }
}
实现dao接口类
public interface UserDao {
    List<User> getUserList();
    User getUserById(String name);
}
创建mapper.xml配置文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.lcf.dao.UserDao">
    <select id="getUserList" resultType="com.lcf.pojo.User">
    select * from user1 ;
  </select>
    <select id="getUserById" resultType="com.lcf.pojo.User">
        select * from user1 where name = #{id} ;
    </select>
</mapper>
在主配置文件中引入配置文件
<mappers>
        <mapper resource="com/lcf/dao/UserDao.xml"/>
</mappers>
编写测试类
public class UserDaoTest {

    @Test
    public void test(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        UserDao mapper = sqlSession.getMapper(UserDao.class);
        List<User> userList = mapper.getUserList();
        for (User user : userList) {
            System.out.println(user);
        }
    }

    @Test
    public void test1(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        UserDao mapper = sqlSession.getMapper(UserDao.class);
        User byId = mapper.getUserById("张三");
        System.out.println(byId.toString());
    }
}
在pom中配置过滤
<build>
        <resources>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
                <filtering>true</filtering>
            </resource>

            <resource>
                <directory>src/main/resources</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
                <filtering>true</filtering>
            </resource>
        </resources>
    </build>
配置log4j
编写log4j.properties文件
######################## 将等级为DEBUG的日志信息输出到consoleh和file两个目的地, console和file的定义在下面的代码
log4j.rootLogger=DEBUG,console,file

########################控制台输出的相关设置
log4j.appender.console = org.apache.log4j.ConsoleAppender
#在控制台输出
log4j.appender.console.Target = System.out
#在DEBUG级别输出
log4j.appender.console.Threshold = DEBUG
log4j.appender.console.layout = org.apache.log4j.PatternLayout
#日志格式
log4j.appender.console.layout.ConversionPattern=[%c]-%m%n

######################日志输出级别
log4j.logger.org.mybatis=DEBUG
log4j.logger.java.sql=DEBUG
log4j.logger.java.sql.Statement=DEBUG
log4j.logger.java.sql.ResultSet=DEBUG
log4j.logger.java.sql.PreparedStatement=DEBUG
在主配置文件中配置log4j
<settings>
        <!-- 开启log4j来记录日志 -->
        <setting name="logImpl" value="LOG4J"/>
</settings>

CRUD

1、namespace

namespace中的包名要和Dao/mapper接口的包名一致!

2、select

选择,查询语句;

  • id:就是对应的namespace中的方法名

  • resultType:Sql语句执行的返回值!

  • parameterType:参数类型

    1. 编写接口

       //查询所有用户
          List<User> getUserList();
      
    2. 编写对应的mapper中的sql语句

      <select id="getUserList" resultType="com.lcf.pojo.User">
          select * from user1 ;
       </select>
      
    3. 测试

      @Test
          public void test(){
              SqlSession sqlSession = null;
              try {
                  sqlSession = MybatisUtils.getSqlSession();
                  UserDao mapper = sqlSession.getMapper(UserDao.class);
                  List<User> userList = mapper.getUserList();
                  for (User user : userList) {
                      System.out.println(user);
                  }
              }catch (Exception e){
                  e.printStackTrace();
              }finally {
                  sqlSession.close();
              }
             
          }
      
3、Insert
<insert id="addUser" parameterType="com.lcf.pojo.User">
        insert into user1(`id`,`name`,`pwd`) values (#{id},#{name},#{pwd});
    </insert>
4、update
<update id="update" parameterType="com.lcf.pojo.User">
       update user1 set name=#{name},pwd=#{pwd} where id=#{id};
    </update>
5、Delete
<delete id="deleteUser" parameterType="int">
        delete  from user1 where id=#{id};
    </delete>

注意点:

曾删改需要提交事物

6、错误分析
  • 标签不要匹配错
  • resouce 绑定mapper,需要使用路径
  • 程序配置文件必须符合规范
  • NullPointerException,没有注册到资源
  • 输出的xml文件中存在中文乱码问题
  • maven资源没有导出问题
7、Map

假设,我们的实体类,或者数据库中的表,字段参数过多,我们可以考虑使用Map

  1. 接口:

    //添加用户
     int addUser2(Map<String,Object> map);
    
  2. xml配置:

    <!--可以直接取出map中的key,根据#{userid}通过key取出value-->
        <insert id="addUser2" parameterType="map">
            insert into user1(`id`,`name`,`pwd`) values (#{userid},#{username},#{userpwd});
        </insert>
    
  3. test测试:

        @Test
        public void testAddUser2(){
            SqlSession sqlSession = MybatisUtils.getSqlSession();
            UserDao mapper = sqlSession.getMapper(UserDao.class);
            HashMap<String, Object> map = new HashMap<String, Object>();
            map.put("userid",5);
            map.put("username","hhhhh");
            map.put("userpwd","123123");
            mapper.addUser2(map);
            sqlSession.commit();
            sqlSession.close();
        }
    

    Map传递参数,直接在sql中取出key即可

    对象茶传递参数,直接在sql中取对象的属性即可

    只有一个基本类型的情况下,可以直接在sql中取得到

    多个参数用map或者注解

配置解析

1、核心配置文件
  • MyBatis-config.xml

  • MyBatis的配置文件包含了会深深影响MyBatis行为的设置和属性信息。

            properties(属性)
            settings(设置)
            typeAliases(类型别名)
            typeHandlers(类型处理器)
            objectFactory(对象工厂)
            plugins(插件)
            environments(环境配置)
                environment(环境变量)
                    transactionManager(事务管理器)
                    dataSource(数据源)
            databaseIdProvider(数据库厂商标识)
            mappers(映射器)
    
    
2、环境配置(environments)

MyBatis 可以配置成适应多种环境

不过要记住:尽管可以配置多个环境,但每个 SqlSessionFactory 实例只能选择一种环境

学会使用配置多套运行环境!

Mybatis 默认的事务管理器就是 JDBC ,链接池 : POOLED

3、属性(properties)

我们可以通过properties 属性来实现引用配置文件

这些属性可以在外部进行配置,并可以进行动态替换。你既可以在典型的 Java 属性文件中配置这些属性,也可以在 properties 元素的子元素中设置。【sql.propertis】

  1. 编写配置文件

    driver = com.mysql.cj.jdbc.Driver
    url = jdbc:mysql://localhost:3306/test01?characterEncoding=utf-8;serverTimezone=UTC;useSSL=true
    username = lcf
    password = 123456
    
  2. 在核心配置文件中引入

    <!--引入外部配置文件-->
    <properties resource="sql.properties">
        <!--添加键值对,但是优先级低于配置文件中的键值对-->
        <property name="password" value="123456"/>
    </properties>
    
    • 可以直接在核心配置文件中引入
    • 可以在其中添加一些属性配置
    • 如果两个文件字段冲突,优先使用外部配置
4、类型别名(typeAliases)
  • ​ 类型别名可为 Java 类型设置一个缩写名字
  • ​ 意在降低冗余的全限定类名书写
<typeAliases>
    <typeAlias alias="user" type="com.lcf.pojo.User"/>
</typeAliases>

也可以指定一个包名,MyBatis 会在包名下面搜索需要的 Java Bean

<typeAliases>
    <package name="com.lcf.pojo"/>
</typeAliases>

每一个在包 domain.blog 中的 Java Bean,在没有注解的情况下,会使用Bean 的首字母小写的非限定类名来作为它的别名,即:他会扫描这个包,默认的别名就是这个类名,首字母小写。

在实体类比较少的时候推荐使用第一种,如果实体类比较多的情况下推荐使用第二种

第一种可以DIY(自定义)第二种则不行 如果一定要设置DIY则使用注解。

例:

@Alias("user")
public class User {
    
}
5、设置(settings)

logImpl指定 MyBatis 所用日志的具体实 现,未指定时将自动查找。SLF4J | LOG4J | LOG4J2 | JDK_LOGGING | COMMONS_LOGGING | STDOUT_LOGGING | NO_LOGGING
6、映射器(mappers)

MapperRegistry:注册绑定我们的mapper文件;

方式一:

<mappers>
    <mapper resource="com/lcf/Dao/UserMapper.xml"/>
</mappers>

方法二:使用class文件绑定注册

<mappers>
    <mapper class="com.lcf.Dao.UserMapper"/>
</mappers>

注意点:

  • 接口和他的Mapper配置文件必须同名
  • 接口和他的Mapper配置文件必须在同一个包下面

方式三:使用扫描包进行注入绑定

<mappers>
    <package name="com.lcf.Dao"/>
</mappers>

注意点:

  • 接口和他的Mapper配置文件必须同名
  • 接口和他的Mapper配置文件必须在同一个包下面

解决属性名和字段名不一致问题

1、问题

数据库中的字段

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7xvgndv2-1617259159535)(ims/Mybatis/2021-02-13%2015-12-42%20%E7%9A%84%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE.png)]

新建一个项目,拷贝之前的,情况测试实体类字段不一致的

public class User {
    private int id ;
    private String name ;
    private String password;
}

解决方案:

  • 起别名

    <select id="queryById" resultType="user">
        select id,name,pwd as password from user1 where id = #{id}
    </select>
    
2、resultMap

结果集映射

id		name		pwd
id		name 		password
<!--结果集映射-->
<resultMap id="UserMap" type="user">
    <!--
            property : 属性,结构体中的属性字段
            column   : 列,表格中的字段名
    -->
    <result property="password" column="pwd"/>
</resultMap>
<select id="queryById" resultMap="UserMap">
    select * from user1 where id = #{id}
</select>
  • resultMap 元素是 MyBatis 中最重要最强大的元素
  • ResultMap 的设计思想是,对简单的语句做到零配置,对于复杂一点的语句,只需要描述语句之间的关系就行了
  • 这就是 ResultMap 的优秀之处——你完全可以不用显式地配置它们

6、日志

6.1、日志工厂

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-N0ZMatEj-1617259159539)(…/…/.config/Typora/typora-user-images/image-20210219091647119.png)]

  • SLF4J
  • LOG4J 【重点】
  • LOG4J2
  • JDK_LOGGING
  • COMMONS_LOGGING
  • STDOUT_LOGGING【掌握】
  • NO_LOGGING

在Mybatis 中具体使用哪一个日志实现,在设置中决定

STDOUT_LOGGING标准日志输出

在mybatis核心配置文件中,配置我们的日志

<settings>
    <setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>

6.2、LOG4J

6.2.1、什么是LOG4J?
  • Log4j是Apache的一个开源项目,通过使用Log4j,我们可以控制日志信息输送的目的地是控制台、文件、GUI组件,甚至是套接口服务器、NT的事件记录器、UNIX Syslog守护进程
  • 我们也可以控制每一条日志的输出格式
  • 通过定义每一条日志信息的级别,我们能够更加细致地控制日志的生成过程
  • 令人感兴趣的就是,这些可以通过一个配置文件来灵活地进行配置,而不需要修改应用的代码。
6.2.2、LOG4J的使用
  1. 先导入log4j的包

    <dependency>
        <groupId>log4j</groupId>
        <artifactId>log4j</artifactId>
        <version>1.2.17</version>
    </dependency>
    
  2. 创建log4j.properties

    ######################## 将等级为DEBUG的日志信息输出到consoleh和file两个目的地, console和file的定义在下面的代码
    log4j.rootLogger=DEBUG,console,file
    
    ########################控制台输出的相关设置
    log4j.appender.console = org.apache.log4j.ConsoleAppender
    #在控制台输出
    log4j.appender.console.Target = System.out
    #在DEBUG级别输出
    log4j.appender.console.Threshold = DEBUG
    log4j.appender.console.layout = org.apache.log4j.PatternLayout
    #日志格式
    log4j.appender.console.layout.ConversionPattern=[%c]-%m%n
    
    ######################日志输出级别
    log4j.logger.org.mybatis=DEBUG
    log4j.logger.java.sql=DEBUG
    log4j.logger.java.sql.Statement=DEBUG
    log4j.logger.java.sql.ResultSet=DEBUG
    log4j.logger.java.sql.PreparedStatement=DEBUG
    
  3. 配置log4j为日志的实现

    <settings>
        <!-- 开启log4j来记录日志 -->
        <setting name="logImpl" value="LOG4J"/>
    </settings>
    
  4. 直接测试运行刚才的查询

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zRReMqRb-1617259159542)(…/…/.config/Typora/typora-user-images/image-20210220100302105.png)]

简单使用
  1. 在要使用Log4j的类中导入 import org.apache.log4j.Logger;

  2. 日志对象,参数为当前类的class

    static Logger logger = Logger.getLogger(MyTest.class);
    
  3. 日志级别

    logger.info("info");
    logger.debug("debug");
    logger.error("error");
    

7、分页

为什么要分页?

  • 减少数据的处理量

使用Limit分页

语法: select * from user1 limit startIndex,pageSize;
select * from user1 limit 3; #[0,n]

使用Mybatis实现分页,核心SQL

  1. 接口

    //分页
    List<User> getUserByLimit(Map<String,Integer> map);
    
  2. Mapper.XML

    <select id="getUserByLimit" resultMap="UserMap" resultType="user" parameterType="map">
        select * from user1 limit #{startIndex},#{pageSize}
    </select>
    

    测试

    @Test
        public void TestLimit(){
            SqlSession sqlSource = MybatisUtils.getSqlSource();
            UserDao mapper = sqlSource.getMapper(UserDao.class);
            HashMap<String, Integer> map = new HashMap<String, Integer>();
            map.put("startIndex",1);
            map.put("pageSize",3);
            List<User> userByLimit = mapper.getUserByLimit(map);
            for (User user : userByLimit) {
                System.out.println(user);
            }
            sqlSource.close();
        }
    

    8、使用注解开发

    8.1使用注解开发

  3. 注解在接口上实现

    @Select("select * from user1")
    List<User> queryAll();
    
  4. 需要在核心配置文件中绑定接口!

    <mappers>
        <mapper class="com.lcf.Dao.UserDao"/>
    </mappers>
    
  5. 测试使用:

    @Test
        public void testQueryAll(){
            SqlSession sqlSource = MybatisUtils.getSqlSource();
            UserDao mapper = sqlSource.getMapper(UserDao.class);
            List<User> users = mapper.queryAll();
            for (User user : users) {
                System.out.println(user);
            }
            sqlSource.close();
        }
    

    本质:反射机制实现

    底层:动态代理

    Mybatis详细的执行流程!

    8.2、CRUD

我们可以在工具类创建的时候实现自动提交事物

public static SqlSession getSqlSource(){
        return sqlSessionFactory.openSession(true);
    }

编写接口,增加注解:

public interface UserDao {
    @Select("select * from user1")
    List<User> queryAll();

    @Select("select * from user1 where id=#{id}")
    User queryUserById(@Param("id") int id);

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

    @Update("update user1 set name=#{name},pwd=#{password} where id=#{id}")
    int updateUser(User user);

    @Delete("delete from user1 where id=#{id}")
    int deleteUser(@Param("id") int id);
}

测试类:

public class MyTest {
    @Test
    public void testQueryAll(){
        SqlSession sqlSource = MybatisUtils.getSqlSource();
        UserDao mapper = sqlSource.getMapper(UserDao.class);
        List<User> users = mapper.queryAll();
        for (User user : users) {
            System.out.println(user);
        }
        sqlSource.close();
    }

    @Test
    public void testQueryUserById(){
        SqlSession sqlSource = MybatisUtils.getSqlSource();
        UserDao mapper = sqlSource.getMapper(UserDao.class);
        User user = mapper.queryUserById(2);
        System.out.println(user);
        sqlSource.close();
    }

    @Test
    public void testAddUser(){
        SqlSession sqlSource = MybatisUtils.getSqlSource();
        UserDao mapper = sqlSource.getMapper(UserDao.class);
        mapper.addUser(new User(4,"李麻子","123456"));
        sqlSource.close();
    }

    @Test
    public void testUpdateUser(){
        SqlSession sqlSource = MybatisUtils.getSqlSource();
        UserDao mapper = sqlSource.getMapper(UserDao.class);
        mapper.updateUser(new User(4,"李大炮","123123"));
        sqlSource.close();
    }

    @Test
    public void testDelete(){
        SqlSession sqlSource = MybatisUtils.getSqlSource();
        UserDao mapper = sqlSource.getMapper(UserDao.class);
        mapper.deleteUser(4);
        sqlSource.close();
    }

【重点注意:需要将接口绑定到核心配置文件!!】

关于@Param()注解

  • 基本类型的参数或者String类型,需要加上
  • 引用类型不需要加
  • 如果只有一个基本类型的话,可以忽略,但建议加上
  • 我们在SQL中引用的就是我门这里的@Param()中设定的属性

9、Lombok

使用步骤:

  1. 在idea中安装lombok插件:

  2. 在项目中导入lombok的jar包依赖:

    <!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.12</version>
        </dependency>
    
  3. 在实体类上加上注解:

    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    public class User {
        private int id ;
        private String name ;
        private String password;
    }
    
  4. Lombok中的方法:

    @Getter and @Setter
    @FieldNameConstants
    @ToString
    @EqualsAndHashCode
    @AllArgsConstructor, @RequiredArgsConstructor and @NoArgsConstructor
    @Log, @Log4j, @Log4j2, @Slf4j, @XSlf4j, @CommonsLog, @JBossLog, @Flogger, @CustomLog
    @Data
    @Builder
    @SuperBuilder
    @Singular
    @Delegate
    @Value
    @Accessors
    @Wither
    @With
    @SneakyThrows
    @val
    @var
    experimental @var
    @UtilityClass
    Lombok config system
    

    说明

    • @Data : 无参构造,get,set,toString,hashCode,equals 方法
    • @AllArgsConstructor : 有参构造
    • @NoArgsConstructor :无参构造
    • @ToString : toString方法

    10、多对一的处理

    多对一:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RkSsQnEK-1617259159544)(ims/image-20210307110724985.png)]

  • 多个学生对应一个老师
  • 对于学生而言,关联。。多个学生关联一个学生【多对一】
  • 对于老师而言,集合,一个老师有很多学生【一对多】

测试环境搭建

  1. 导入lombok
  2. 新建实体类Teacher与Student
  3. 编写接口TeacherMapper与StudentMapper
  4. 编写mapper配置文件
  5. 在核心配置文件中绑定注册接口或者xml文件
  6. 测试查询是否能成功!

按照查询嵌套处理

<select id="getStudent" resultType="student" resultMap="studentTeacher">
    select * from student;
</select>
<!--association:对象,collection:集合-->
<resultMap id="studentTeacher" type="Student">
    <!--teacher : Student中字段的字段名
		tid :数据库中的外键字段名,通过它查询teacher表
		Teacher :Student中teacher的类型
		getTeacher:查询teacher表的语句
	-->
    <association property="teacher" column="tid" javaType="Teacher" select="getTeacher"/>
</resultMap>
<select id="getTeacher" resultType="teacher">
    select * from teacher where id=#{id}
</select>

按照结果嵌套处理

<!--按照查询结果嵌套处理-->
    <select id="getStudent2" 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="Student">
        <result property="id" column="sid"/>
        <result property="name" column="sname"/>
        <association property="teacher" javaType="teacher">
            <result property="name" column="tname"/>
        </association>
    </resultMap>

回顾mysql多对一查询方式:

  • 子查寻
  • 联表查询

11、一对多处理

比如:一个老师拥有多个学生!

对于老师而言,就是一对多的关系!

  1. 环境搭建 :

    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    public class Student {
        private int id;
        private String name;
        private int tid;
    }
    
    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    public class Teacher {
        private int id;
        private String name;
    
        private List<Student> students;
    }
    
  2. 按照结果嵌套处理

    <select id="getTeacher" resultMap="teacherStudent">
        select t.id tid,t.name tname,s.id sid,s.name sname,s.tid stid
        from teacher t,student s
        where tid=t.id and t.id=#{tid};
    </select>
    <resultMap id="teacherStudent" type="Teacher">
        <result property="id" column="tid"/>
        <result property="name" column="tname"/>
        <collection property="students" ofType="Student">
            <result property="id" column="sid"/>
            <result property="name" column="sname"/>
            <result property="tid" column="stid"/>
        </collection>
    </resultMap>
    
  3. 按照查询嵌套处理

    <select id="getTeacher2" resultMap="getTeacher1">
        select * from teacher where id = #{tid};
    </select>
    
    <resultMap id="getTeacher1" type="Teacher">
        <!--javaType : java字段的类型
            ofType : 类型集合中范型中的类型
        -->
        <collection property="students" ofType="Student" column="id" javaType="ArrayList" select="getStudent"/>
    </resultMap>
    
    <select id="getStudent" resultType="Student">
        select * from student where tid=#{id}
    </select>
    

    小结

    1. 关联- association【多对一】
    2. 集合- collection【一对多】
    3. javaType & ofType
      1. javaType 用来指定实体类中属性的类型
      2. ofType 用来指定映射到List或者集合中的pojo类型,范型的约束类型!

    注意点:

    1. 保证sql的可读性,尽量保证通俗易懂
    2. 注意一对多和多对一中,属性名和字段的问题
    3. 如果问题不好排错,可以使用日志,建议使用Log4j
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值