Mybatis | Mybatis的核心配置

目录:

  • Mybatis的核心配置 :
    • 一、MyBatis的 “核心对象”
      • 1.1 SqlSessionFactory
      • 1.2 SqlSession :
        • SqlSession对象中的操作数据库的方法 :
          • \<T> T selectOne ( String statement )
          • \<T> T selectOne( String statement , Object parameter )
          • \<E> List\<E> selectList ( String statement )
          • \<E> List\<E> selectList ( String statement , Object parameter )
          • \<E> List\<E> selectList ( String statement , Object parameter , RowBounds rowBounds )
          • void select ( String statement , Object parameter , ResultHandler handler )
          • int insert ( String statement )
          • int insert ( String statement , Object parameter )
          • int update( String statement )
          • int update( String statement , Object parameter)
          • int delete( String statement )
          • int delete( String statement , Object parameter)
          • int commit( )
          • void rollback( )
          • void close( )
          • \<T> T getMapper( Class\<T> type )
          • Connection getConnection( )
        • 使用工具类创建 “SqlSession” / SqlSession工具类
    • 二、MyBatis的 “配置文件”
      • “映射文件”中的 “主要元素”
        • \<properties>元素
        • \<settings>元素
        • \<typeAliases>元素
        • \<typeHandler>元素
        • \<objectFactory>元素
        • \<plugins>元素
        • \<environments>元素
        • \<mappers>元素
    • 三、MyBatis的 “映射文件”
      • “配置文件”中的 “主要元素”
        • \<select>元素
        • \<insert>元素
        • \<update>元素和\<delete>元素
        • \<sql>元素
        • \<resultMap>元素 (可解决“属性名” 和 “字段名”不一样导致的数据无法映射成功的问题)

Mybatis的核心配置 :

一、MyBatis的 “核心对象”

  • 在使用MyBatis框架时,主要涉及 两个核心对象 : SqlSessionFactorySqlSession,它们在MyBatis框架中起着至关重要作用

1.1 SqlSessionFactory

  • SqlSessionFactory是MyBatis 框架中十分重要对象,它是单个数据库映射关系经过编泽后内存镜像,其主要作用创建SqlSession

  • SqlSessionFactory 对象的实例可以通过 SqlSessionFactoryBuilder对象 来构建,而SqlSessionFactoryBuilder对象 则可以通过 XML配置文件 或一个预先定义好Configuration实例 构建出SqlSessionFactory实例

  • 以下内容讲解的是 :就是 通过XML配置文件 构建出的SqlSessionFactory实例,其实现代码如下:

    InputStream inputStream = Resources.getResourceAsStream("配置文件的位置");
    //通过SqlSessionFactoryBuilder的 build()方法 + 配置文件来创建 SqlSessionFactory
    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
    
  • SqlSessionFactory对象线程安全 的,它一旦被创建,在整个应用执行期间都会存在。如果我们多次地创建同一个数据库的SqlSessionFactory,那么此数据库的资源将很容易被耗尽。为了解决此问题,通常每一个数据库都会只对应一个 SqlSessionFactory, 所以在 构建SqlSessionFactory实例时,建议使用单列模式

1.2 SqlSession :

  • SqlSession 是MyBatis 框架中另一个重要对象, 它是 应用程序持久层之间执行与操作的一个单线程对象,其主要作用执行持久化操作

  • SqlSession对象包含数据库中所有执行SOL操作方法SqlSession中有很多操作数据库方法),由于其底层封装JDBC连接,所以可以直接使用SqlSession实例来 执行已映射SQL语句

    (可用SqlSession来执行 “映射文件” 中的sql语句)。

  • 每一个线程都应该有一个自己的SqlSession实例,并且该实例不能被共享的。同时,SqlSession实例线程不安全 的,因此 使用范围 最好在 一次请求一个方法 中,绝不能将其放在一个静态字段实例字段任何类型的管理范围 (如Servlet的HttpSession)中使用。

  • 使用完SqlSession对象之后,要及时地关闭它,通常可以将其放在fnally块中关闭

//通过 sqlSessionFactory对象获得"SqlSession"
SqlSession sqlSession = sqlSessionFactory.openSession();
try{//此处执行持久化操作
}finally{sqlSession.close();
}
SqlSession对象中的操作数据库的方法 :
<T> T selectOne ( String statement )

<T> T selectOne ( String statement ) : 查询方法 : 参数 statement 是在 “ 映射文件 中定义的 <select>元素id
目的是 : 获得映射文件中的 “<select>元素下所代表的 sql语句 作为selectOne( )方法的参数 ”)。使用该方法后,会返回执行SQL语句查询结果一条泛型对象

<T> T selectOne( String statement , Object parameter )

<T> T selectOne ( String statementObject parameter ) :查询方法 : 参数 statement 是在 “ 映射文件 中定义的 <select>元素idparameter查询所需参数。使用该方法后,会返回执行SQL语句查询结果一条泛型对象

<E> List<E> selectList ( String statement )

<E> List<E> selectList ( String statement ) : 查询方法 : 参数 statement 是在 “映射文件” 中定义的 <select>元素id 。使用该方法后,会返回执行SQL语句查询结果泛型对象集合

<E> List<E> selectList ( String statement , Object parameter )

<E> List<E> selectList ( String statement , Object parameter ) : 查询方法 : 参数 statement 是在 “ 映射文件” 中定义的 <select>元素id , parameter 是查询所需的参数。使用该方法后,会返回执行SQL语句查询结果的 泛型对象集合

<E> List<E> selectList ( String statement , Object parameter , RowBounds rowBounds )

<E> List<E> selectList ( String statement , Object parameter ) : 查询方法 : 参数==statement==是在 “ 映射文件” 中定义的 <select>元素id , parameter 是查询所需的参数,rowBounds是用于分页参数对象。使用该方法后会返回执行SQL语句查询结果的 泛型对象集合

void select ( String statement , Object parameter , ResultHandler handler )

void select ( String statement, Object parameter,ResultHandler handler ) : 查询方法 : 参数statement是在配置文件中定义的 <select>元素idparameter 是查询所需的 参数ResultHandler对象用于处理查询返回复杂结果集。 (通常用于多表查询

int insert ( String statement )

int insert ( String statement ) : 插入方法 : 参数 statement是在 “映射文件” 中定义的 <select>元素id ,使用该方法后,会返回执行 SQL语句所影响行数

int insert ( String statement , Object parameter )

int insert ( String statement , Object parameter ) : 插入方法 : 参数 statement 是在 “ 映射文件” 中定义的 <select>元素idparameter 是查询所需的参数。使用该方法后,会返回执行 SQL语句所影响行数

int update( String statement )

int update ( String statement ) : 更新方法 : 参数 statement 是在 “ 映射文件” 中定义的 <update>元素id ,使用该方法后,会返回执行 SQL语句所影响行数

int update( String statement , Object parameter)

int update ( String statement , Object parameter ) : 更新方法 : 参数 statement 是在 “ 映射文件” 中定义的 <update>元素idparameter更新所需的参数。使用该方法后,会返回执行 SQL语句所影响行数

int delete( String statement )

int delete ( String statement ) : 删除方法 : 参数 statement 是在 “映射文件” 中定义的 <delete>元素id ,使用该方法后,会返回执行 SQL语句所影响行数

int delete( String statement , Object parameter)

int delete ( String statement , Object parameter ) : 删除方法 : 参数 statement 是在 “ 映射文件” 中定义的 <delete>元素idparameter删除所需的参数使用该方法后,会返回执行 SQL语句所影响行数

int commit( )

int commit ( ) : 提交事务方法

void rollback( )

int rollback ( ) : 回滚事务方法

void close( )

int close ( ) : 关闭SqlSession 对象。

<T> T getMapper( Class<T> type )
  • <T> T getMapper ( Class<T> type ) : 该方法会返回 Mapper接口代理对象,该对象关联了SqlSession对象,开发人员可以使用对象直接调用方法操作数据库。参数type是Mapper的接口类型。MyBatis官方推荐通过
    Mapper对象访问MyBatis
  • 该方法 : getMapper( ) 的目的是根据传入的 类类型type 返回一个与该类型匹配的对象。具体实现可能涉及反射机制,用于 创建并返回一个与传入类类型相匹配实例
Connection getConnection( )

Connection getConnection( ) : 获取 JDBC数据库连接对象 的方法。

使用工具类创建 “SqlSession” / SqlSession工具类
  • 使用工具类创建 SqlSession对象 :

    package com.myh.utils;import org.apache.ibatis.io.Resources;
    import org.apache.ibatis.session.SqlSession;
    import org.apache.ibatis.session.SqlSessionFactory;
    import org.apache.ibatis.session.SqlSessionFactoryBuilder;import java.io.IOException;
    import java.io.InputStream;/*** 工具类*/
    public class SqlSessionUtils {  //获得SqlSession的"工具类"private static SqlSessionFactory sqlSessionFactory = null;//初始化 SqlSessionFactory 对象static { //静态代码块try {//使用Mybatis提供的Resources类加载mybatis-config.xml配置文件InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");//构建SqlSessionFactory工厂SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);} catch (IOException e) {e.printStackTrace();}}/*** 获得SqlSession对象的静态方法*/public static SqlSession getSession() {return sqlSessionFactory.openSession();}
    }
    

    这样,我们在使用时就 只创建了一个SqlSessionFactory 对象,并且可以通过工具类getSession( ) 方法, 来 获取SqlSession对象

二、MyBatis的 “配置文件”

MyBatis的核心配置文件中,包含了很多影响MyBatis行为的重要信息。这些信息通常在一个项目中只会在一个配置文件中编写,并且编写后也不会轻易改动。

“映射文件”中的 “主要元素”

  • MyBatis 框架的 核心配置文件 (即 mybatis-config.xml )中,<configuration> 元素 是配置文件的 根元素其他元素都要在 <configuration> 元素内配置。

  • Mybatis配置文件主要元素图 :(要熟悉 <configuration>元素各个子元素配置。)

    在这里插入图片描述

    ps :
    ==<Cofgnaion>子元素必须按照图中由上到下==的顺序进行配置,否则Mybatis在解新xml配置文件的时候会报错。

<properties>元素
  • <properties>是一个配置属性元素,该元素通常用于内部配置 “外在化”,即通过外部的配置来动态地替换内部定义的属性

(直接的使用 : 将外部的 Xxx.properties文件中的属性用于 mybatis配置文件中 )。
例如,数据库的连接等属性,就可以通过典型的 Java属性文件 ( .properties文件 )中的配置替换

ps :
当我们在mybatis配置文件中 使用 <properties>元素导入 .properties文件时,即可在mybatis配置文件中,即直接使用 .properties文件中的数据

db.properties

jdbc.driver = com.mysql.jdbc.Driver
jdbc.url = jdbc:mysql://localhost:3306/mybatis
jdbc.username = root
jdbc.password = root

mybatis-config.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration><!-- properties属性 --><!-- 通过properties属性引入 .properties配置文件, mybatis配置文件中则可直接使用 .properties中的数据,进行"动态替换"  --><properties resource="db.properties"/><!-- environments属性 --><environments default="mysql"><environment id="mysql"><transactionManager type="JDBC"/><dataSource type="POOLED"><!--通过“properties属性”来将 以下的driver、url、username、password 和.properties配置文件 中的数据进行“动态替换”--><property name="driver" value="${jdbc.driver}"/><property name="url" value="${jdbc.url}"/><property name="username" value="${jdbc.username}"/><property name="password" value="${jdbc.password}"/></dataSource></environment></environments></configuration>

完成上述配置后,dataSource中连接数据库的4个属性 ( driverurlusermamepassword值将会由db.properties文件对应的值动态替换。这样就为配置提供了诸多灵活的选择。
除了可以像上述通过外部配置文件定义属性值外,还可以通过配置 <properties>元素的子元素 <property>,以及通过方法参数传递的方式来获取属性值。由于使用properties配置文件来配置属性值可以方便地多个配置文件使用这些属性值,并且方便日后的维护和修改,所以在实际开发中,使用.properties文件来配置属性值最常用的方式

<settings>元素
  • <settings>元素主要用于改变MyBatis运行时行为,例如 开启二级缓存开启延迟加载 等。
    虽然不配置<settings>元素,也可以正常运行MyBatis, 但是熟悉<settings>的配置内容以及它们的作用还是十分必要的。

  • 常见的**<settings>属性配置在 “配置文件” 中的使用** :

        <settings><setting name="cacheEnabled" value="true" /><setting name="lazyLoadingEnabled" value="true" /><setting name="multipleResultSetsEnabled" value="true"/><setting name="useColumnLabel" value="true"/><setting name="useGeneratedKeys" value="false" /><setting name="autoMappingBehavior" value="PARTIAL"/>.....</settings>
    
<typeAliases>元素
  • <typeAliases>元素 用于为配置文件中的Java类型设置一个简短的名字,即 设置别名别名的设置与XML配置相关,其使用的意义在于减少全限定类名冗余。 如 : 可用 <typeAliases>元素POJO类设置一个 “别名

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd"><configuration><!--  定义别名  --><typeAliases><!-- typeAlias元素 为 typeAliases元素的 "子元素"  --><typeAlias alias="user" type="com.myh.po.Customer"/></typeAliases></configuration>
    

    上述示例中,<typeAliases> 元素子元素 <typeAlias> 中的type属性用于指定需要被定义别名的类的全限定名alias属性的属性值user 就是自定义的别名,它可以代替com.myh.po.Customer使用在MyBatis文件任何位置如果省略alias属性,MyBatis 会默认将类名首字母 小写后的名称作为别名

  • POJO类过多,还可以通过自动扫描包形式自定义别名 (此时以类名首字母小写后的名称为 “别名”),具体示例如下 :

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd"><configuration><!--  定义别名  --><typeAliases><!--   使用自动扫描包来定义“别名”  --><!--   Mybatis会将所用 com.myh.po包中POJO类以首字母小写的名称 作为“别名” --><!--   如: Customer 的 默认设置的别名为: customer  --><package name="com.myh.po"/></typeAliases></configuration>
    
  • 需要注意的是,上述方式的别名只适用于没有使用注解的情况。如果在程序中使用了注解,则别名其注解的值, 具体如下 :

    //使用注解来为该POJO类设置在 mybatis-config.xml配置文件中使用的 "别名"
    @Alias(value = "customer")
    public class Customer {  .....
    }
    
  • 除了可以使用 <typeAliases>元素自定义别名外,MyBatis框架还默认为许多常见的Java类型(如数值字符串日期集合等 )提供了 相应的类型别名。(可使用时查询常见的Java类型别名是什么

<typeHandler>元素
  • MyBatis预处理语句( PreparedStatement )中 设置一个参数或者从结果集 ( ResultSet )中取出一个值 时,都会用其框架内部注册了的 typeHandler ( 类型处理器 ) 进行相关处理

  • typeHandler作用就是将预处理语句 中传入的参数从 javaType ( Java类型) 转换为 jdbcType
    ( JDBC类型),或者从数据库取出结果时将 jdbcType 转换为 javaType

  • 为了方便转换,Mybatis框架提供了一系列默认的类型处理器

    类型处理器Java 类型JDBC 类型
    BooleanTypeHandlerjava.lang.Boolean, boolean数据库兼容的 BOOLEAN
    ByteTypeHandlerjava.lang.Byte, byte数据库兼容的 NUMERIC 或 BYTE
    ShortTypeHandlerjava.lang.Short, short数据库兼容的 NUMERIC 或 SMALLINT
    IntegerTypeHandlerjava.lang.Integer, int数据库兼容的 NUMERIC 或 INTEGER
    LongTypeHandlerjava.lang.Long, long数据库兼容的 NUMERIC 或 BIGINT
    FloatTypeHandlerjava.lang.Float, float数据库兼容的 NUMERIC 或 FLOAT
    DoubleTypeHandlerjava.lang.Double, double数据库兼容的 NUMERIC 或 DOUBLE
    BigDecimalTypeHandlerjava.math.BigDecimal数据库兼容的 NUMERIC 或 DECIMAL
    StringTypeHandlerjava.lang.StringCHAR, VARCHAR
    ClobReaderTypeHandlerjava.io.Reader-
    ClobTypeHandlerjava.lang.StringCLOB, LONGVARCHAR
    NStringTypeHandlerjava.lang.StringNVARCHAR, NCHAR
    NClobTypeHandlerjava.lang.StringNCLOB
    BlobInputStreamTypeHandlerjava.io.InputStream-
    ByteArrayTypeHandlerbyte[]数据库兼容的字节流类型
    BlobTypeHandlerbyte[]BLOB, LONGVARBINARY
    DateTypeHandlerjava.util.DateTIMESTAMP
    DateOnlyTypeHandlerjava.util.DateDATE
    TimeOnlyTypeHandlerjava.util.DateTIME
    SqlTimestampTypeHandlerjava.sql.TimestampTIMESTAMP
    SqlDateTypeHandlerjava.sql.DateDATE
    SqlTimeTypeHandlerjava.sql.TimeTIME
    ObjectTypeHandlerAnyOTHER 或未指定类型
    EnumTypeHandlerEnumeration TypeVARCHAR 或任何兼容的字符串类型,用来存储枚举的名称(而不是索引序数值)
    EnumOrdinalTypeHandlerEnumeration Type任何兼容的 NUMERIC 或 DOUBLE 类型,用来存储枚举的序数值(而不是名称)。
    SqlxmlTypeHandlerjava.lang.StringSQLXML
    InstantTypeHandlerjava.time.InstantTIMESTAMP
    LocalDateTimeTypeHandlerjava.time.LocalDateTimeTIMESTAMP
    LocalDateTypeHandlerjava.time.LocalDateDATE
    LocalTimeTypeHandlerjava.time.LocalTimeTIME
    OffsetDateTimeTypeHandlerjava.time.OffsetDateTimeTIMESTAMP
    OffsetTimeTypeHandlerjava.time.OffsetTimeTIME
    ZonedDateTimeTypeHandlerjava.time.ZonedDateTimeTIMESTAMP
    YearTypeHandlerjava.time.YearINTEGER
    MonthTypeHandlerjava.time.MonthINTEGER
    YearMonthTypeHandlerjava.time.YearMonthVARCHAR 或 LONGVARCHAR
    JapaneseDateTypeHandlerjava.time.chrono.JapaneseDateDATE
  • MyBatis框架所提供的 这些类型处理器不能够满足需求时,还可以通过自定义的方式对类型处理器进行扩展 ( 自定义类型处理器可以通过实现TypeHandler 接口 或者 继承 BaseTypeHandle类来定义)。

    <typeHandler> 元素就是用于在配置文件注册自定义类型处理器的。它的使用方式有两种
    注册一个类类型处理器
    注册一个包所有类型处理器

    CustomertypeHandler.java

    package com.myh.type;import org.apache.ibatis.type.JdbcType;
    import org.apache.ibatis.type.TypeHandler;import java.sql.CallableStatement;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    public class CustomertypeHandler implements TypeHandler {@Overridepublic void setParameter(PreparedStatement ps, int i, Object parameter, JdbcType jdbcType) throws SQLException {} @Overridepublic Object getResult(ResultSet rs, String columnName) throws SQLException {return null;}@Overridepublic Object getResult(ResultSet rs, int columnIndex) throws SQLException {return null;}@Overridepublic Object getResult(CallableStatement cs, int columnIndex) throws SQLException {return null;}
    }
    

    mybatis-config.xml

         <!-- 注册一个类的类型处理器 --><typeHandlers><!--  以单个类的形式配置   --><typeHandler handler="com.myh.type.CustomertypeHandler"/></typeHandlers><!-- 注册一个包中所有类的类型处理器 --><typeHandlers><!--  注册一个包中所有的typeHandler,系统在启动时会自动扫描包下的所有文件  --><package name="com.myh.type"/></typeHandlers>
    
<objectFactory>元素
  • MyBatis框架每次创建 结果对象新实例 时,都会使用一个对象工厂( ObjectFactory )的实例来完成。MyBatis中默认的 ObjectFactory的作用 就是 实例化目标类,它既可以通过默认构造方法实例化,也可以在参数映射存在的时候通过参数构造方法来实例化

  • 在通常情况下, 我们使用默认的ObjectFactory即可,MyBatis 中默认ObjectFactory是由org.apache.ibatis rflection.factory.DefaultObjectFactory来提供服务的。大部分场景下都不用配置和修改,但如果想覆盖ObjectFactory的默认行为,则可以通过自定义ObjectFactory来实现。

    MyObjectFactory.java

    package com.myh.objFactory;import org.apache.ibatis.reflection.factory.DefaultObjectFactory;import java.util.List;
    import java.util.Properties;//自定义工厂类 : 该类可以实现ObjectFactory接口 或 继承 DefaultObjectFactory类
    public class MyObjectFactory extends DefaultObjectFactory { //要继承DefaultObjectFactory类private static final long serialVerSionUID = -4114845625429965832L;@Overridepublic <T> T create(Class<T> type) {return super.create(type);}@Overridepublic <T> T create(Class<T> type, List<Class<?>> constructorArgTypes, List<Object> constructorArgs) {return super.create(type, constructorArgTypes, constructorArgs);}@Overridepublic void setProperties(Properties properties) {super.setProperties(properties);}@Overridepublic <T> boolean isCollection(Class<T> type) {return super.isCollection(type);}
    }
    

    mybatis-config.xml

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd">
    <configuration><objectFactory type="com.myh.objFactory.MyObjectFactory"><property name="name" value="MyObjectFactory"/></objectFactory></configuration>
    
<plugins>元素
  • MyBatis允许在已映射语句执行过程中某一点进行拦截调用,这种拦截调用是通过插件来实现的。<plugins> 元素作用就是配置用户所开发插件。如果用户想要进行插件开发,必须要先了解其内部运行原理,因为在试图修改或重写已有方法的行为时,很可能会破坏MyBatis原 有的核心模块。
<environments>元素
  • 配置文件中,<environments>元素用于对环境进行配置MyBatis环境配置 实际上就是 数据源的配置,我们可以通过 <environments>元素配置多种数据源,即配置多种数据库

       <!-- environments属性 --><environments default="mysql"><environment id="mysql"><transactionManager type="JDBC"/><dataSource type="POOLED"><!--通过“properties属性”来将 以下的driver、url、username、password 和.properties配置文件 中的数据进行“动态替换”--><property name="driver" value="${jdbc.driver}"/><property name="url" value="${jdbc.url}"/><property name="username" value="${jdbc.username}"/><property name="password" value="${jdbc.password}"/></dataSource></environment></environments>
    

    在上述代码中,<environments>元素环境配置根元素,它包含个一default属性,该属性用于指定默认环境ID。 是 <environments>元素的 “子元素”, : <environment> 可以定义多个,其记属性用于表示所定义环境ID值。在 environment元素内,包含事务管理 ( transactionManager ) 和 数据源 ( dataSource ) 的配置信息,其 <transactionManager>元素用于配置事务管理,它的type属性用于指定事务管理的方式,即使用哪种事务管理器<dalaSource>元素用于配置数据源,它的type属性用于指定使用哪种数据源

    在MyBatis中,可以配置两种类型的事务管理器,分别是 JDBCMANAGEDJDBC : 此配置直接使用了JDBC提交回滚设置,它依赖于从数据源得到的连接来管理事务作用域
    MANAGED : 此配置从来不提交回滚一个连接 ,而是让容器来管理事务整个生命周期
    默认情况下,它会关闭连接,但一些容器并不希望这样,为此可以将closeConnection属性
    置为false阻止它默认关闭行为

    ps :
    如果没有必要中 使用的是 Spring+ MyBatis,则 没有必要 在MyBatis ( mybatis-config.xml ) 中 配置事务管理器,因为实际开发中,会使用Spring自带的管理器实现事务管理

<mappers>元素
  • 配置文件 ( mybatis-config.xml )中,<mappers>元素 用于 指定MyBatis 映射文件 (引入“映射文件”)(XxxMapper.xml )的 位置,一般可以使用以下 4种方法 引入映射文件。 ( 一个mybatis-config.xml 配置文件可以引入多个“映射文件”。)

    使用 “类路径” 引入
    使用 “本地文件路径” 引入
    使用 “接口类” 引入
    使用 “包名” 引入

  • 使用 “类路径” 引入

    <mappers><!-- 使用"类路径"读取"映射文件" --><mapper resource="com/myh/mapper/CustomerMapper.xml"/>
    </mappers>
    
  • 使用 “本地文件路径” 引入

     <mappers><!--  使用“本地文件路径”引入“映射文件”  --><mapper url="file:///D:/com/myh/mapper/CustomerMapper.xml"/></mappers>
    
  • 使用 “接口类” 引入

    <mappers><!--  使用“接口类”引入“映射文件”  --><mapper class="com.myh.mapper.CustomerMapper"/>
    </mappers>
    
  • 使用 “包名” 引入

    <mappers><!-- 使用“包名”引入“映射文件” --><package name="com.myh.mapper"/>
    </mappers>
    

三、MyBatis的 “映射文件”

  • 映射文件 ( XxxMapper.xml )是Mybatis框架中十分重要的文件,可以说,Mybatis框架的强大之处就体现在“映射文件”的编写上
  • 映射文件中,<mapper>元素映射文件根元素,其他元素都是它的子元素
    在这里插入图片描述

“配置文件”中的 “主要元素”

<select>元素
  • <select>元素 用于映射 “查询语句”,它可以帮助我们从数据库中读出数据,并组装数据给企业开发者。

        <!-- “查询数据”--><select id="findCustomerById" parameterType="Integer" resultType="com.myh.po.Customer">select * from t_customer where id = #{id}</select>
    

    上述语句中的唯一标识为 findCustomerByld,它接收一个 Integer 类型参数,并返回一个Customer类型对象

  • <select>元素中,除了上述代码中的几个属性还有其他一些可以配置属性如下所示

    属性说明
    id表示命名空间中唯一标识符, 常与命名空间组合起来使用组合后如果不唯一, MyBatis会抛出异常。
    parameterType该属性表示传入SQL语句参数类全限定名或者别名。它是一个可选属性, 因为MyBatis可以通过TypeHandler推断出具体传入语句参数。其默认值是unset (依赖于驱动)
    resultType从SQL语句中返回的类型全限定名或者别名。如果是集合类型,那么返回的应该是集合可以包含类型,而不是集合本身。返回时可以使用resultTyperesultMap之一。
    resultMap表示外部resultMap命名引用。返回时可以使用resultTyperesultMap之一。
    flushCache表示在调用SQL语句之后,是否需要MyBatis清空之前查询本地缓存二级缓存。其值为布尔类型( truelfalse),默认值为false。如果设置为true,则任何时候只要SQL语句被调用,都会清空本地缓存二级缓存。
    useCache用于控制二级缓存开启关闭。其值为布尔类型( truelfalse),默认值为true,表示将查询结果存入二级缓存中。
    timeout用于设置超时参数,单位为超时将抛出异常
    fetchSize获取记录总条数设定,其默认值是unset (依赖于驱动)。
    statementType用于设置MyBatis使用哪个JDBCStatement工作,其值为STATEMENTPREPARED(默认值)CALLABLE, 分别对应JDBC中的StatementPreparedStatementCallableStatement
    属性说明
    resultSetType表示结果集类型,其值可设置为FORWARD_ONLY、SCROLL_SENSITIVE 或SCROLL_INSENSITIVE, 它的默认值是unset (依赖于驱动)
<insert>元素
  • <insert>元素用于映射“插入语句,在执行完元素中定义的SQL语句后,返回一个表示插入记录数整数
<!--useGeneratedKeys="true" : 获得该insert语句插入数据库时形成的“主键id” / 获得数据库内部产生的主键idkeyProperty="id" : 将插入或更新时的“返回值”赋值到PO类的对应的“属性”上 : 即将刚获得的“主键id”赋值到PO类对应的id属性上-->
<!--  该insert语句的返回值 : ①返回插入成功的行数 ②插入行的主键id  -->
<insert id="addCustomer" parameterType="com.myh.po.Customer"flushCache="true" statementType="PREPARED"keyProperty="id" keyColumn="" useGeneratedKeys="true" timeout="20">insert into t_customer(username,jobs,phone)values(#{username},#{jobs},#{phone})
</insert>

以上的 insert语句返回值 : ①返回插入成功的行数 ②插入行的主键id
上述代码中可以看出,<insert>元素属性<select>元素属性大部分相同<insert>元素包含了 3个特有属性

  • <insert>元素 中的三个特有 属性 :
属性说明
keyProperty( 仅对insert和update有用 )此属性 ( keyProperty )的作用插入 或 更新操作时返回值赋值给 PO类某个属性通常会设置为“主键”对应的属性
(通常会设置该属性的值为“id” (即将插入形成的“主键id”值赋值到PO类中 )。如果需要设置联合主键,可以在多个值之间用逗号隔开
例子如 :
keyProperty =“i‘d” ( 要结合useGeneratedKeys属性使用 ) :
useGeneratedKeys属性获得的 ( 插入形成的 ) “主键id” 赋值到PO类的对应的id属性上,这样就能获得insert语句生成的数据对应的“主键id”了。
keyColumn( 仅对insertupdate有用 ) 此属性用于 设置第几列主键主键列不是表中第一列时需要设置,在需要主键联合时,值可以使用逗号隔开。
useGeneratedKeys( 仅对insertupdate有用 )此属性会使 MyBatis 使用 JDBCgetGeneratedKeys( )方法来获取由数据库内部生产主键 (此时一般配合keyProperty属性使用来将该“主键 赋值给PO类对应的属性上。”), 如MySQLSQL Server自动递增字段,其 默认值false

执行插入操作后,很多时候我们会需要返回插入成功数据生成主键值 ( 表中主键id ),此时就可以通过
上面所讲解的3个属性来实现。


  • 如果使用的数据库支持主键自动增长 (如MySQL ),那么可以通过keyProperty属性 指定PO类某个属性接收主键返回值 ( 通常会设置到id属性上 : 将主键id赋值给PO类id属性上 ),同时还要通过 useGeneratedKeys属性才能实现目标功能。 例子如下 :

<insert>元素 中的三个特有 属性 例子如 :

CustomerMapper.xml (映射文件) :

<!--useGeneratedKeys="true" : 获得该insert语句插入数据库时形成的“主键id” / 获得数据库内部产生的主键idkeyProperty="id" : 将插入或更新时的“返回值”赋值到PO类的对应的“属性”上 : 即将刚获得的“主键id”赋值到PO类对应的id属性上-->
<!--  该insert语句的返回值 : ①返回插入成功的行数 ②插入行的主键id  -->
<insert id="addCustomer" parameterType="com.myh.po.Customer"keyProperty="id"  useGeneratedKeys="true" >insert into t_customer(username,jobs,phone)values(#{username},#{jobs},#{phone})
</insert>

以上的 insert语句返回值 : ①返回插入成功的行数 ②插入行的主键id

CustomerTest.java (测试类) :

public class CustomerTest {@org.junit.Test //单元测试public void addCustomerTest() throws IOException {//1.读取mybatis框架的配置文件String resource = "com/myh/映射文件的元素/mybatis-config.xml";//通过“输入流”读取mybatis配置文件/*在该mybatis-config.xml配置文件中,已配置了“数据源”信息 和配置了"映射文件 : XxxMapper.xml”的位置,可实施加载“映射文件”*/InputStream inputStream = Resources.getResourceAsStream(resource);//2.根据配置文件“构建会话工厂 : SqlSessionFactory ”SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);//3.通过SqlSessionFactory(会话工厂)创建SqlSession("会话"对象)SqlSession sqlSession = sqlSessionFactory.openSession();Customer customer = new Customer();customer.setUsername("小蓝");customer.setJobs("学生");customer.setPhone("12345678");//将该Customer对象存入到数据库中,同时目的是: 将存入到数据库中的数据对应的“主键id”获得且返回int insert = sqlSession.insert("CustomerMapper.addCustomer", customer);/*** 输出"插入数据"形成的"主键id值"  (从数据库中获得的主键id值是存储在Customer这个PO类中的)*/System.out.println(customer.getId());if (insert > 0) {System.out.println("你成功插入了" + insert + "条数据!");} else {System.out.println("插入数据操作失败! ");}//4.设置“事务管理”sqlSession.commit();//5.关闭SqlSessionsqlSession.close();}
}

通过上述的<insert>元素三个特有属性,即可获得插入数据对应“ 主键id”

在这里插入图片描述


  • 如果使用的数据库不支持主键自动增长 (如Oracle ), 或者支持增长的数据库 取消了主键自增 的规则时,也可以使用MyBatis提供的另一种方式自定义生成主键例子如下

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    <!--映射文件中,插入数据用 <insert>元素
    -->
    <!-- #{} : 相当于"占位符"  ${} : 相当于在sql语句后要拼接的"字符串" -->
    <mapper namespace="CustomerMapper"><insert id="insertCustomer" parameterType="com.myh.po.Customer"><selectKey keyProperty="id" resultType="Integer" order="BEFORE">select if(max(id) is null,1,max(id) + 1)as newId from t_customer</selectKey>insert into t_customer(username,jobs,phone)values(#{username},#{jobs},#{phone})</insert></mapper>
    

    上述代码中,<selectKey> 元素会首先运行,它会通过自定义的语句来设置数据中的主键 (如果
    t_customer表中没有记录,则将id设置为1,否则就将id的最大值加1,来为新的主键),然后再调用插入语句
    <selectKey>元素在使用时可以设置以下几种属性

    <selectKeykeyProperty="id"resultType="Integer"order="BEFORE"statementType="PREPARED">
    

    在上述 <selectKey>元素的几个属性中,keyPropertyresultTypestatementType的作用与前面讲解的相同,order 属性可以被设置为BEFOREAFTER如果设置BEFORE,那么它会首先执行 <selectKey>元素中的配置设置主键,然后执行插入语句;如果设置为AFTER,那么它会先执行插入语句,然后执行 <selectKey>元素中的配置内容。

<update>元素和<delete>元素
  • <update><delete>元素 的使用比较简单,它们的属性配置也基本相同 ,其常用属性如下 :
  <!-- 更新 --><update id="updateCustomer" parameterType="com.myh.po.Customer"flushCache="true" statementType="PREPARED" timeout="20"></update><!-- 删除 --><delete id="deleteCustomer" parameterType="com.myh.po.Customer"flushCache="true" statementType="PREPARED" timeout="20"></delete>

从上述配置代码中可以看出,<update><delete>元素属性基本与 <select>元素中属性一致
<insert>元素一样,<update> 和<delete>元素在执行完之后,也会返回一个表示影响记录条数整数,其使用示例如下 :

<!-- 更新 -->
<update id="updateCustomer" parameterType="com.myh.po.Customer">update t_customer set username = #{username},jobs=#{jobs},phone=#{phone}where id = #{id}</update><!-- 删除 --><delete id="deleteCustomer" parameterType="Integer">delete from t_customer where id = #{id}</delete>
<sql>元素
  • 一个映射文件中,通常需要定义多条SQL语句,这些SQL语句的组成可能有一部分是相同的 ( 如多条select语句中都查询相同的idusernamejobs 字段),如果每一个SQL语句都重写遍相同的部分, 势必会增加代码量,导致映射文件过于臃肿

  • 那么有没有什么办法将这些SQL语句相同组成部分抽取出来,然后在需要的地方引用呢 ?
    答案是肯定的,我们可以在映射文件中使用MyBatis所提供的 <sql>元素来解决上述问题。<sql>元素的作用 : 就是定义可重用SQL代码片段,然后在其他语句中引用这一代码片段

    例子如

     <sql id="customerColumns"> id,username,jobs,phone</sql><select id="findCustomerById" parameterType="Integer" resultType="com.myh.po.Customer">select <include refid="customerColumns"/>from t_customerwhere id = #{id}</select>
    
<resultMap>元素 (可解决“属性名” 和 “字段名”不一样导致的数据无法映射成功的问题)
  • <resultMap>元素表示结果映射集,是 MyBatis最重要 也是 最强大元素。它的主要作用 : 是
    定义映射规则级联的更新 以及 定义类型转化器 等。

    ps :
    <resultMap>元素 可解决“属性名” 和 “字段名不一样导致的数据无法映射成功问题

  • <resutMap>元素中包含了属性 / 子元素,如下所示 :

       <!--  resultMap的元素结构  --><resultMap type="" id=""><constructor>  <!-- 类在实例时,用来注入"结果"到"结构方法"中 --><idArg/>    <!-- ID参数;标记结果为ID --><arg/>     <!-- 注入到构造方法的一个普通结果 --></constructor><id/>          <!-- 用于表示哪个"列"是"主键" --><result/>      <!-- 注入到“字段”或“JavaBean属性”的普通结果 --><association property=""/>  <!-- 用于一对一关联 --><collection property=""/>   <!-- 用于一对多关联 --><discriminator javaType="">   <!-- 使用"结果值"来决定哪个"结果映射"--><case value=""></case></discriminator></resultMap>
    
  • <resutMap>元素属性 关系如下表所示 :

    属性描述
    type表示需要 映射 POJO ( 普通Java对象 )
    id这个 resultMap唯一标识
  • <resutMap>元素子元素 关系如下表所示 :

    子元素描述
    <constructor>用于配置构造方法 ( 当一个POJO未定义无参构造方法时,就可以使用 <constructor>元素 进行配置)。
    <id>分别标记 POJO中属性中的“主键和 标记数据库表中字段的 “主键,并 将二者进行关联
    ps :
    这意味着,通过 <resultMap> 中的 <id>元素的配置,POJO“主键”属性名 不用 和数据库中 “主键”名相同。
    <result>表示 POJO属性数据库表映射关系。(用于POJO中 “属性数据库表中的 “进行关联。 )
    ps :
    这意味着
    ,通过 <resultMap> 中的 <result>元素的配置,数据库中的 “字段” 以及 该“字段”相对应的 “属性”名,不用一致。(在 <result>中设置各自的名称即可)
    <association>表示“一对一”关联。用于处理“多表”时的关联关系
    <collection>表示“一对多”关联。用于处理“多表”时的关联关系
    <discriminator>使用"结果值"来决定哪个"结果映射"用于处理一个单独的数据库查询 返回很多不同数据类型 结果集情况
  • 在默认情况下,MyBatis程序在运行时会 自动地将查询到数据与需要返回的对象属性进行匹配赋值 ( 需要表中的 列名与对象的属性名称完全一致 )。 然而实际开发时,数据表中的和需要返回的对象的属性可能不会完全一致, 这种情况下MyBatis是不会自动赋值。此时,就可以使用 <resultMap>元素进行处理

  • 实际开发中,如果当POJO中“属性名” 和 数据库中“字段名不一致,此时查询数据库,数据会无法映射到POJO类中,最后导致查询到的内容为null。 此时<resultMap>元素即可解决这个问题

    例子如:
    在这里插入图片描述

    在这里插入图片描述


    此时可使用“映射文件” 中的因属性名 和 字段名不一致导致的数据无法映射POJO中的问题。如下所示 :

    UserMapper.xml

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    <mapper namespace="UserMapper"><!--  select元素中使用resultType时,当数据库中"字段名" 和POJO中"属性名"不一致时,select的数据将则无法映射到POJO类中,即输出内容为null --><!--  select元素中用resultMap时,数据库中“字段名” 和 POJO中“属性名”不用保持一致,此时也能完成将select到的数据映射到POJO类中--><select id="selectUser_resultType" resultType="com.myh.po.User" parameterType="Integer">select * from t_user where t_id = #{id}</select><!--上面这个select的查询的数据是无法映射到POJO类中,即select的数据为null,因为数据库中“字段名” 和 POJO中的“属性名”,此时可用 <resultMap>元素来解决这个问题 --><resultMap id="resultMap" type="com.myh.po.User"><!--   下面配置的目的 : "属性名" 和 "字段名" 可以不用保持一致   --><id property="id" column="t_id"/><result property="name" column="t_name"/><result property="age" column="t_age"/></resultMap><!--  因为此处用了resultMap(已经配置好了,完成各种内容的“映射了”,所以即使"属性名" 和 “字段名”不一致,也能select到数据)  --><select id="selectUser_resultMap" resultMap="resultMap" parameterType="Integer">select * from t_user where t_id = #{id}</select></mapper>
    

    UserTest.java (测试类)

    public class UserTest {@org.junit.Test //单元测试public void selectUser_resultType_resultMap_Test() throws IOException {//1.读取mybatis框架的配置文件String resource = "com/myh/映射文件的元素/mybatis-config.xml";InputStream inputStream = Resources.getResourceAsStream(resource);//2.根据配置文件“构建会话工厂 : SqlSessionFactory ”SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);//3.通过SqlSessionFactory(会话工厂)创建SqlSession("会话"对象)SqlSession sqlSession = sqlSessionFactory.openSession();User user1 = (User)sqlSession.selectOne("UserMapper.selectUser_resultType", 2);/**此处输出的内容为 : null ,因为字段名和属性名 不一样,数据无法映射成功,最后输出的内容为 : null*/System.out.println("从数据库中查询到的数据为(通过resultType获得): "+user1);/**此处输出的内容为 : "查询到的数据",即使“属性名” 和 “字段名”没有保持一致,但通过resultMap元素的配置,查询到的数据依然能映射到POJO类中。*/User user2 = (User)sqlSession.selectOne("UserMapper.selectUser_resultMap", 2);System.out.println("从数据库中查询到的数据为(通过resultMap获得): "+user2);//4.关闭SqlSessionsqlSession.close();}
    }
    

    控制台输出结果为
    在这里插入图片描述

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

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

相关文章

android程序员面试笔试宝典,Android开发社招面试总结

部分面试常问的面试专题 一、Java篇 1.多线程并发&#xff1b; sleep 和 wait 区别join 的用法线程同步&#xff1a;synchronized 关键字等线程通信线程池手写死锁 2.Java 中的引用方式&#xff0c;及各自的使用场景 3.HashMap 的源码 4.GC(垃圾回收)是什么&#xff1f;如何…

日本极致产品力|如何利用招牌业务,打造占据63%市场份额的咖喱品牌

招牌产品是品牌的代表性产品&#xff0c;行业中领先品牌的招牌产品往往可以代表整个品类。在内线产品竞争中&#xff0c;通过在顾客心智中确立一个强势招牌产品形象可以提高品牌势能。好侍能够成为日本调味品头部品牌&#xff0c;通过香辛料招牌业务获取增长是其成功的关键。 从…

分享6个解决msvcp110.dll丢失的方法,全面解析msvcp110.dll文件

msvcp110.dll 是一个动态链接库 (DLL) 文件&#xff0c;属于 Microsoft Visual C 库的一部分&#xff0c;具体来说是 Microsoft Visual C 2012 版本的运行时组件。这个 DLL 文件包含了在 Windows 环境下运行用 C 编写的程序所必需的一些函数和资源。当一个应用程序是使用 Visua…

基于Python3的数据结构与算法 - 07 归并排序

一、归并 引入 假设现在的列表分两段有序&#xff0c;如何将其合并成为一个有序列表。 这种操作成为一次归并。 归并的思路 分别对两个列表进行遍历&#xff0c;比较两个列表中的最小值&#xff0c;将更小的取出来。取出后一次进行上操作&#xff0c;直到其中一个列表中的元…

1分钟学会Python字符串前后缀与编解码

1.前缀和后缀 前缀和后缀指的是&#xff1a;字符串是否以指定字符开头和结尾 2.startswith() 判断字符串是否以指定字符开头&#xff0c;若是返回True&#xff0c;若不是返回False str1 "HelloPython"print(str1.startswith("Hello")) # Trueprint…

【转载】深度学习笔记——详解损失函数

原文链接: https://blog.csdn.net/weixin_53765658/article/details/136360033 CSDN账号: Purepisces github账号: purepisces 希望大家可以Star Machine Learning Blog https://github.com/purepisces/Wenqing-Machine_Learning_Blog 损失函数 根据您使用的神经网络类型和数…

力扣SQL50 进店却未进行过交易的顾客 查询

Problem: 1581. 进店却未进行过交易的顾客 文章目录 思路Code 思路 &#x1f468;‍&#x1f3eb; 山山山林老木 左连接查询筛选 transation_id 为 null 的值group by customer_id Code select v.customer_id ,count(customer_id) count_no_trans from Visits v left jo…

java找工作之JavaWeb(一)

JavaWeb 一个web应用有多部份组成&#xff08;静态web&#xff0c;动态web&#xff09; html&#xff0c;css&#xff0c;jsjsp&#xff0c;servletjava程序jar包配置文件(Properties) web应用程序编写完毕后&#xff0c;若想提供给外界访问&#xff0c;需要一个服务器来统一…

3694-51-7,3,5-Dinitro-1,2-phenylenediamine,合成其他化合物的重要中间体

您好&#xff0c;欢迎来到新研之家 文章关键词&#xff1a;3694-51-7&#xff0c;3,5-Dinitro-1,2-phenylenediamine&#xff0c;3,5-二硝基-1,2-苯二胺;3,5-二硝基苯-1,2-二胺 一、基本信息 【产品简介】&#xff1a;3,5-Dinitro-1,2-phenylenediamine, with the molecular…

一台工控机的能量

使用Docker搭建EPICS的IOC记录 Zstack EPICS Archiver在小课题组的使用经验 以前电子枪调试&#xff0c;用一台工控机跑起束测后台&#xff0c;这次新光源用的电子枪加工回来又是测试&#xff0c;又是用一台工控机做起重复的事&#xff0c;不过生命在于折腾&#xff0c;重复的…

openGauss学习笔记-232 openGauss性能调优-系统调优-资源负载管理-资源管理准备-资源规划

文章目录 openGauss学习笔记-232 openGauss性能调优-系统调优-资源负载管理-资源管理准备-资源规划 openGauss学习笔记-232 openGauss性能调优-系统调优-资源负载管理-资源管理准备-资源规划 完成资源负载管理功能配置前&#xff0c;需要先根据业务模型完成租户资源的规划。业…

【白嫖8k买的机构vip教程】Appium自动化(3):Appium-Desktop界面介绍

Appium-Desktop主界面包含三个菜单Simple、Advanced、Presets Simple界面&#xff1a; Host设置Appium server的ip地址&#xff0c;本地调试可以将ip地址修改为127.0.0.1&#xff1b;Port设置端口号&#xff0c;默认是4723不用修改Start Server 启动 Appium serverEdit Confi…

[SUCTF 2019]EasyWeb --不会编程的崽

个人认为&#xff0c;这题还算有些东西。先来看源码 <?php function get_the_flag(){// webadmin will remove your upload file every 20 min!!!! $userdir "upload/tmp_".md5($_SERVER[REMOTE_ADDR]);if(!file_exists($userdir)){mkdir($userdir);}if(!empty…

【力扣白嫖日记】550.游戏玩法分析IV

前言 练习sql语句&#xff0c;所有题目来自于力扣&#xff08;https://leetcode.cn/problemset/database/&#xff09;的免费数据库练习题。 今日题目&#xff1a; 550.游戏玩法分析IV 表&#xff1a;Activity 列名类型player_idintdevice_idintevent_datedategames_played…

leetcode--接雨水(双指针法,动态规划,单调栈)

目录 方法一&#xff1a;双指针法 方法二&#xff1a;动态规划 方法三&#xff1a;单调栈 42. 接雨水 - 力扣&#xff08;LeetCode&#xff09; 黑色的是柱子&#xff0c;蓝色的是雨水&#xff0c;我们先来观察一下雨水的分布情况: 雨水落在凹槽之间&#xff0c;在一个凹槽的…

第三百七十五回

文章目录 1. 概念介绍2. 使用方法3. 代码与效果3.1 示例代码3.2 运行效果 4. 内容总结 我们在上一章回中介绍了"分享三个使用TextField的细节"相关的内容&#xff0c;本章回中将介绍如何让Text组件中的文字自动换行.闲话休提&#xff0c;让我们一起Talk Flutter吧。 …

《C++进阶--10.多态》

目录 10. 多态 10.1 多态的基本概念 10.2 多态案例一-计算器类 10.3 纯虚函数和抽象类 10.4 多态案例二-制作饮品 10.5 虚析构和纯虚析构 10.6 多态案例三-电脑组装 10. 多态 10.1 多态的基本概念 多态是C面向对象三大特性之一 多态分为两类 静态多态: 函数重载 和 运算…

HTML---Ajax

文章目录 目录 文章目录 前言 一.Ajax概述 二.原生创建Ajax 三,使用Jquery处理Ajax 总结 一.Ajax概述 AJAX&#xff08;Asynchronous Javascript And XML&#xff09;是一种创建交互式网页应用的网页开发技术。它使用Javascript语言与服务器进行异步交互&#xff0c;可以传…

matplotlib.animation 3d姿态动画

目录 演示效果&#xff1a; 演示代码&#xff1a; 保存为gif 演示效果&#xff1a; 演示代码&#xff1a; import numpy as np import matplotlib.pyplot as plt from mpl_toolkits.mplot3d import Axes3D from matplotlib.animation import FuncAnimation# 定义人体关键点…

flutterandroidx支持,【工作经验分享】

基于Linux的pc启动过程 我们都知道&#xff0c;所有的程序软件包括操作系统都是运行在内存中的&#xff0c;然而我们的操作系统一般是存放在硬盘上的&#xff0c;当我们按下开机键的时候&#xff0c;此时内存中什么程序也没有&#xff0c;因此需要借助某种方式&#xff0c;将操…