深入理解Mybatis之配置文件详解_imapperext-程序员宅基地

技术标签: Mybatis配置文件  JavaEE  Mybatis配置文件详解  深入理解Mybatis  Mybatis  

1.  Mybatis配置文件详解

1.1. 全局配置文件内容

SqlMapConfig.xml的配置内容和顺序如下(顺序不能乱):

Properties(属性)

Settings(全局参数设置)

typeAliases(类型别名)

typeHandlers(类型处理器)

objectFactory(对象工厂)

plugins(插件)

environments(环境信息集合)

       environment(单个环境信息)

              transactionManager(事物)

              dataSource(数据源)

mappers(映射器)

1.1.1.  Properties

SqlMapConfig.xml文件中可以引用java属性文件中的配置信息

db.properties配置信息如下:

db.driver=com.mysql.jdbc.Driver

db.url=jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=utf8

db.username=root

db.password=root

SqlMapConfig.xml使用properties标签后,如下所示:

<!-- 通过properties标签,读取java配置文件的内容 -->

<properties resource="db.properties" />

 

<!-- 配置mybatis的环境信息 -->

<environments default="development">

    <environment id="development">

        <!-- 配置JDBC事务控制,由mybatis进行管理 -->

        <transactionManager type="JDBC"></transactionManager>

        <!-- 配置数据源,采用dbcp连接池 -->

        <dataSource type="POOLED">

            <property name="driver"value="${db.driver}"/>

            <property name="url"value="${db.url}"/>

            <property name="username"value="${db.username}"/>

            <property name="password"value="${db.password}"/>

        </dataSource>

    </environment>

</environments>

使用${},可以引用已经加载的java配置文件中的信息。

注意:mybatis将按照下面的顺序加载属性:

u  Properties标签体内定义的属性首先被读取

u  Properties引用的属性会被读取,如果发现上面已经有同名的属性了,那后面会覆盖前面的值

u  parameterType接收的值会最后被读取,如果发现上面已经有同名的属性了,那后面会覆盖前面的值

 

所以说,mybatis读取属性的顺序由高到低分别是:parameterType接收的属性值、properties引用的属性、properties标签内定义的属性。

1.1.2.  Settings

mybatis全局配置参数,全局参数将会影响mybatis的运行行为。

 

详细参见“mybatis学习资料/mybatis-settings.xlsx”文件

1.1.3.  typeAliases

别名是使用是为了在映射文件中,更方便的去指定入参和结果集的类型,不再用写很长的一段全限定名。

1.1.3.1.      mybatis支持的别名

别名

映射的类型

_byte

byte

_long

long

_short

short

_int

int

_integer

int

_double

double

_float

float

_boolean

boolean

string

String

byte

Byte

long

Long

short

Short

int

Integer

integer

Integer

double

Double

float

Float

boolean

Boolean

date

Date

decimal

BigDecimal

bigdecimal

BigDecimal

 

1.1.3.2.      自定义别名

SqlMapConfig.xml配置信息如下:

<!-- 定义别名 -->

    <typeAliases>

        <!-- 单个定义别名 -->

        <typeAlias type="cn.itcast.mybatis.po.User" alias="user"/>

       

        <!-- 批量定义别名(推荐) -->

        <!-- [name]:指定批量定义别名的类包,别名为类名(首字母大小写都可) -->

        <package name="cn.itcast.mybatis.po"/>

    </typeAliases>

1.1.4.  Mappers

1.1.4.1.      <mapper resource=’’/>

使用相对于类路径的资源

如:<mapperresource="sqlmap/User.xml" />

1.1.4.2.      <mapper url=’’/>

使用完全限定路径

如:<mapperurl="file:///D:\workspace_spingmvc\mybatis_01\config\sqlmap\User.xml"/>

1.1.4.3.      <mapper class=’’/>

使用mapper接口的全限定名

如:<mapperclass="cn.itcast.mybatis.mapper.UserMapper"/>

注意:此种方法要求mapper接口和mapper映射文件要名称相同,且放到同一个目录下

1.1.4.4.      <package name=’’/>(推荐)

注册指定包下的所有映射文件

如:<package name="cn.itcast.mybatis.mapper"/>

 

注意:此种方法要求mapper接口和mapper映射文件要名称相同,且放到同一个目录下

1.2. Mybatis映射文件

1.2.1.  输入映射

1.2.1.1.      ParameterType

指定输入参数的java类型,可以使用别名或者类的全限定名。它可以接收简单类型、POJO、HashMap。

1.2.1.1.1.    传递简单类型

参考入门需求:根据用户ID查询用户信息。

1.2.1.1.2.    传递POJO对象

参考入门需求:添加用户。

1.2.1.1.3.    传递POJO包装对象

开发中通过pojo传递查询条件 ,查询条件是综合的查询条件,不仅包括用户查询条件还包括其它的查询条件(比如将用户购买商品信息也作为查询条件),这时可以使用包装对象传递输入参数。

1、需求:

 综合查询用户信息,需要传入查询条件复杂,比如(用户信息、订单信息、商品信息)。

2、定义包装类对象

一般User.java类要和数据表表字段一致,最好不要在这里面添加其他字段,第二天学习mybatis的逆向工程时,会根据表结构,生成po类,如果在po类中扩展字段,此时会被覆盖掉。

所以针对要扩展的po类,我们需要创建一个扩展类,来继承它。

定义POJO包装类:

3、编写Mapper接口

 //通过包装类来进行复杂的用户信息综合查询

public List<UserExt>findUserList(UserQueryVO userQueryVO);

4、编写Mapper映射文件

  <!-- 通过包装类来进行复杂的用户信息综合查询 -->

<select id="findUserList" parameterType="userQueryVO" resultType="userExt">

        SELECT* FROM USER WHERE sex=#{userExt.sex} AND username LIKE'%${userExt.username}%'

</select>

 

5、编写测试代码

  @Test

publicvoid findUserListTest() {

    // 创建SqlSession

    SqlSession sqlSession = sqlSessionFactory.openSession();

    // 通过SqlSession,获取mapper接口的动态代理对象

    UserMapper userMapper =sqlSession.getMapper(UserMapper.class);

 

    //构造userQueryVO对象

    UserQueryVO userQueryVO = new UserQueryVO();

       

    // 构造UserExt对象

    UserExt userExt = new UserExt();

    userExt.setSex("1");

    userExt.setUsername("小明");

       

    userQueryVO.setUserExt(userExt);

 

    // 调用mapper对象的方法

    List<UserExt> list =userMapper.findUserList(userQueryVO);

 

    System.out.println(list);

    // 关闭SqlSession

    sqlSession.close();

}

1.2.1.2.      传递HashMap

同传递POJO对象一样,mapkey相当于pojo的属性

1、映射文件

<!-- 传递hashmap综合查询用户信息 -->

   <select id="findUserByHashmap" parameterType="hashmap" resultType="user">

     select * from user where id=#{ id} and username like '%${ username}%'

   </select>

上边红色标注的是hashmap的key。

2、测试代码

Public void testFindUserByHashmap()throws Exception{

      //获取session

      SqlSessionsession = sqlSessionFactory.openSession();

      //获限mapper接口实例

      UserMapperuserMapper = session.getMapper(UserMapper.class);

      //构造查询条件Hashmap对象

      HashMap<String,Object> map = new HashMap<String, Object>();

      map.put("id", 1);

      map.put("username", "管理员");

     

      //传递Hashmap对象查询用户列表

      List<User>list= userMapper.findUserByHashmap(map);

      //关闭session

      session.close();

   }

 

 

异常测试:

传递的map中的key和sql中解析的key不一致。

测试结果没有报错,只是通过key获取值为空。

 

1.2.2.  输出映射

1.2.2.1.      resultType

使用resultType进行结果映射时,需要查询出的列名和映射的对象的属性名一致,才能映射成功。

 

如果查询的列名和对象的属性名全部不一致,那么映射的对象为空。

如果查询的列名和对象的属性名有一个一致,那么映射的对象不为空,但是只有映射正确那一个属性才有值。

 

如果查询的sql的列名有别名,那么这个别名就是和属性映射的列名。

1、使用方法

 使用resultType进行结果映射时,查询的列名和映射的pojo属性名完全一致,该列才能映射成功。

如果查询的列名和映射的pojo属性名全部不一致,则不会创建pojo对象;

如果查询的列名和映射的pojo属性名有一个一致,就会创建pojo对象。

2、输出简单类型

 当输出结果只有一列时,可以使用ResultType指定简单类型作为输出结果类型。

第一步:Mapper映射文件

<!-- 综合查询用户信息总数,需要传入查询条件复杂,比如(用户信息、订单信息、商品信息) -->

<select id="findUsersCount" parameterType="UserQueryVO"

      resultType="int">

      SELECT count(1) FROM USER WHERE sex =#{userExt.sex} AND username LIKE'%${userExt.username}%'

</select>

第二步:Mapper接口

//综合查询用户信息总数。学习:resultType输出简单类型

public int findUsersCount(UserQueryVOvo);

第三步:测试代码

@Test

publicvoidtestFindUsersCount() {

    // 创建SqlSession

    SqlSession sqlSession = sqlSessionFactory.openSession();

    // 通过SqlSession,获取mapper接口的动态代理对象

    UserMapper userMapper =sqlSession.getMapper(UserMapper.class);

 

    //构造userQueryVO对象

    UserQueryVO userQueryVO = new UserQueryVO();

       

    // 构造UserExt对象

    UserExt userExt = new UserExt();

    userExt.setSex("1");

    userExt.setUsername("小明");

       

    userQueryVO.setUserExt(userExt);

 

   int count = mapper.findUsersCount(userQueryVO);

   System.out.println(count);  // 关闭SqlSession

    sqlSession.close();

}

3、输出POJO单个对象和列表

   注意:输出单个pojo对象和pojo列表(盛放pojo对象)时,mapper映射文件中的resultType的类型是一样的,mapper接口的方法返回值不同。

第一步:Mapper映射文件

<select id="findUsersByName" parameterType="java.lang.String" resultType="cn.itcast.mybatis.po.User">

        SELECT* FROM USER WHERE username LIKE '%${value}%'

</select>

第二步:Mapper接口

下面看下mapper接口的不同之处

l  输出单个pojo对象

//根据用户名称来模糊查询用户信息

public User findUsersByName(String username);

l  输出pojo列表

//根据用户名称来模糊查询用户信息列表

    public List<User>findUsersByName(String username);

 

总结:同样的mapper映射文件,返回单个对象和对象列表时,mapper接口在生成动态代理的时候,会根据返回值的类型,决定调用selectOne方法还是selectList方法。

1.2.2.2.      resultType

resultMap可以进行高级结果映射(一对一、一对多映射)。

1、使用方法

如果查询出来的列名和属性名不一致,通过定义一个resultMap将列名和pojo属性名之间作一个映射关系。

l  定义resultMap

l  使用resultMap作为statement的输出映射类型。

2、需求

把下面SQL的输出结果集进行映射

SELECT id id_,username username_,sex sex_FROM USER WHERE id = 1

3、Mapper映射文件

定义resultMap:

<!-- 定义resultMap-->

<!--

    [id]:定义resultMap的唯一标识

    [type]:定义该resultMap最终映射的pojo对象

    [id标签]:映射结果集的唯一标识列,如果是多个字段联合唯一,则定义多个id标签

    [result标签]:映射结果集的普通列

    [column]SQL查询的列名,如果列有别名,则该处填写别名

    [property]pojo对象的属性名

-->

<resultMap type="user" id="userResultMap">

    <id column="id_" property="id"/>

    <result column="username_" property="username"/>

    <result column="sex_" property="sex"/>

</resultMap>

 

定义statement:

<!-- 根据ID查询用户信息(学习resultMap -->

<select id="findUserByIdResultMap" parameterType="int" resultMap="userResultMap">

SELECT id id_,username username_,sex sex_ FROM USER WHERE id =#{id}

</select>

4、Mapper接口定义

//根据ID查询用户信息(学习resultMap

    public User findUserByIdResultMap(int id);

定义Statement使用resultMap映射结果集时,Mapper接口定义方法的返回值类型为mapper映射文件中resultMaptype类型。

5、测试代码

@Test

publicvoid findUserByIdResultMapTest() {

    // 创建SqlSession

    SqlSession sqlSession = sqlSessionFactory.openSession();

    // 通过SqlSession,获取mapper接口的动态代理对象

    UserMapper userMapper =sqlSession.getMapper(UserMapper.class);

 

    // 调用mapper对象的方法

    User user = userMapper.findUserByIdResultMap(1);

 

    System.out.println(user);

    // 关闭SqlSession

    sqlSession.close();

}

 

1.3. 动态Sql(重点)

通过Mybatis提供的各种动态标签实现动态拼接sql,使得mapper映射文件在编写SQL时更加灵活,方便。常用动态SQL标签有:if、where、foreach;

1.3.1.  If和where

Ø  If标签:作为判断入参来使用的,如果符合条件,则把if标签体内的SQL拼接上。

注意:用if进行判断是否为空时,不仅要判断null,也要判断空字符串‘’;

Ø  Where标签:会去掉条件中的第一个and符号。

1、需求

用户信息综合查询列表和用户信息综合查询总数这两个statement的定义使用动态SQL。

2、映射文件

<!-- 综合查询用户信息,需要传入查询条件复杂,比如(用户信息、订单信息、商品信息) -->

<select id="findUsersByQueryVO" parameterType="cn.itcast.mybatis.po.QueryUserVO"

      resultType="User">

      SELECT * FROM USER

   <where>

      <if test="userExt !=null">

         <if test="userExt.sex != null and userExt.sex != ''">

            AND sex = #{userExt.sex}

         </if>

         <if test="userExt.username != null and userExt.username !=''">

            AND username LIKE'%${userExt.username}%'

         </if>

      </if>

   </where>

</select>

  

<!-- 综合查询用户信息总数,需要传入查询条件复杂,比如(用户信息、订单信息、商品信息) -->

<select id="findUsersCount" parameterType="QueryUserVO"

      resultType="int">

   SELECTcount(1) FROM USER

   <where>

      <if test="userExt !=null">

         <if test="userExt.sex != null and userExt.sex != ''">

            AND sex = #{userExt.sex}

         </if>

         <if test="userExt.username != null and userExt.username !=''">

            AND username LIKE'%${userExt.username}%'

         </if>

      </if>

   </where>

</select>

3、Mapper接口

//通过包装类来进行复杂的用户信息综合查询

public List<UserExt>findUserList(UserQueryVO userQueryVO);

//综合查询用户总数

public int findUsersCount(UserQueryVOuserQueryVO);

4、测试代码:

不传用户名:

输出的SQL如下(也不包含用户名):

通过测试可以得知,打印出的SQL语句确实会随着条件的满足情况而不一样。

 

1.3.2.  Sql片段

Mybatis提供了SQL片段的功能,可以提高SQL的可重用性。

1、定义sql片段

使用sql标签来定义一个SQL片段:

<!-- 定义SQL片段 -->

<!--

    [sql标签]:定义一个SQL片段

    [id]SQL片段的唯一标识

    建议:

        1SQL片段中的内容最好是以单表来定义

        2、如果是查询字段,则不要写上SELECT

        3、如果是条件语句,则不要写上WHERE

 -->

<sql id="select_user_where">

    <if test="userExt != null">

      <if test="userExt.sex !=null and userExt.sex != ''">

         ANDsex = #{userExt.sex}

      </if>

      <if test="userExt.username!= null and userExt.username != ''">

         AND usernameLIKE '%${userExt.username}%'

      </if>

   </if>

</sql>

2、引用sql片段

使用<include refid=’’ /> 来引用SQL片段:

<!-- 根据用户id来查询用户信息(使用SQL片段) -->

<!--

    [include标签]:引用已经定义好的SQL片段

    [refid]:引用的SQL片段id

-->

<select id="findUserList" parameterType="userQueryVO" resultType="userExt">

 

    SELECT * FROM USER

<where>

      <include refid="select_user_where"/>

   </where>

</select>

<!-- 综合查询用户信息总数,需要传入查询条件复杂,比如(用户信息、订单信息、商品信息) -->

<select id="findUsersCount" parameterType="QueryUserVO"

      resultType="int">

   SELECTcount(1) FROM USER

   <where>

      <include refid="select_user_where"/>

   </where>

</select>

1.3.3.  Foreach

向sql传递数组或List时,mybatis使用foreach解析数组里的参数并拼接到SQL中。

1.3.3.1.      传递pojo对象的List集合

1、需求

在用户查询列表和查询总数的statement中增加多个id输入查询。

2、Sql

SELECT * FROM user WHERE id IN (1,10,16)

3、定义pojo中的List属性

4、映射文件

<!-- [foreach标签]:表示一个foreach循环 -->

<!-- [collection]:集合参数的名称,如果是直接传入集合参数,则该处的参数名称只能填写[list] -->

<!-- [item]:每次遍历出来的对象 -->

<!-- [open]:开始遍历时拼接的串 -->

<!-- [close]:结束遍历时拼接的串 -->

<!-- [separator]:遍历出的每个对象之间需要拼接的字符 -->

<if test="idList != null and idList.size > 0">

<foreach collection="idList" item="id"open="AND id IN (" close=")" separator=",">

        #{id}

</foreach>

</if>

5、Mapper接口

//根据用户ID的集合查询用户列表(学习foreach标签之通过POJO对象传ID集合)

public List<UserExt> findUserList(UserQueryVO vo);

6、测试代码

@Test

publicvoid testFindUserList() {

    // 创建SqlSession

    SqlSession sqlSession = sqlSessionFactory.openSession();

    // 通过SqlSession,获取mapper接口的动态代理对象

    UserMapper mapper =sqlSession.getMapper(UserMapper.class);

 

    // 构造QueryUserVO对象

    QueryUserVO vo = new QueryUserVO();

    // UserExt ext = new UserExt();

    // ext.setUsername("小明");

    // ext.setSex("1");

    // vo.setUserExt(ext);

 

    // 创建用户ID集合,然后设置到QueryUserVO对象中

    List<Integer> idList = newArrayList<Integer>();

    idList.add(1);

    idList.add(10);

    idList.add(16);

    vo.setIdList(idList);

 

    // 调用mapper代理对象的方法

    List<UserExt> list =mapper.findUserList(vo);

    System.out.println(list);

    // 关闭SqlSession

    sqlSession.close();

}

1.3.3.2.      直接传递List集合

1、需求

根据用户ID的集合查询用户列表

2、Sql

SELECT * FROM user WHERE id IN (1,10,16)

 

3、映射文件

<!-- 根据用户ID的集合查询用户列表(学习foreach标签之直接传ID集合) -->

<!--

    [foreach标签]:表示一个foreach循环

    [collection]:集合参数的名称,如果是直接传入集合参数,则该处的参数名称只能填写[list]

    [item]:定义遍历集合之后的参数名称

    [open]:开始遍历之前需要拼接的SQL

    [close]:结束遍历之后需要拼接的SQL

    [separator]:遍历出的每个对象之间需要拼接的字符

 -->

<select id="findUsersByIdList" parameterType="java.util.List"resultType="user">

    SELECT * FROM USER

    <where>

        <if test="list[少东家1]  != null and list.size > 0">

            <foreach collection="list" item="id"open="AND id IN (" close=")" separator=",">

                #{id}

            </foreach>

        </if>

    </where>

</select>

4、Mapper接口

//根据用户ID的集合查询用户列表(学习foreach标签之直接传ID集合)

public List<User>findUsersByIdList (List<Integer> idList);

5、测试代码

@Test

publicvoid findUsersByIdListTest() {

    // 创建SqlSession

    SqlSession sqlSession = sqlSessionFactory.openSession();

    // 通过SqlSession,获取mapper接口的动态代理对象

    UserMapper userMapper =sqlSession.getMapper(UserMapper.class);

 

    // 构造List<Integer>集合

    List<Integer> idList = new ArrayList<Integer>();

    idList.add(1);

    idList.add(10);

idList.add(16);

 

    // 调用mapper对象的方法

    List<User> list =userMapper.findUsersByIdList (idList);

    System.out.println(list);

    // 关闭SqlSession

    sqlSession.close();

}

1.4. Mybatis和hibernate的区别:

Mybatis技术特点:

1、通过直接编写SQL语句,可以直接对SQL进行性能的优化;

2、学习门槛低,学习成本低。只要有SQL基础,就可以学习mybatis,而且很容易上手;

3、由于直接编写SQL语句,所以灵活多变,代码维护性更好。

4、不能支持数据库无关性,即数据库发生变更,要写多套代码进行支持,移植性不好。

5、需要编写结果映射。

Hibernate技术特点:

1、标准的orm框架,程序员不需要编写SQL语句。

2、具有良好的数据库无关性,即数据库发生变化的话,代码无需再次编写。

3、学习门槛高,需要对数据关系模型有良好的基础,而且在设置OR映射的时候,需要考虑好性能和对象模型的权衡。

4、程序员不能自主的去进行SQL性能优化。

 

Mybatis应用场景:

       需求多变的互联网项目,例如电商项目。

Hibernate应用场景:

       需求明确、业务固定的项目,例如OA项目、ERP项目等。


如果是直接传入集合参数,则该处的参数名称只能填写[list]

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/u013110682/article/details/80000714

智能推荐

Python大作业——爬虫+可视化+数据分析+数据库(数据库篇)-程序员宅基地

文章浏览阅读742次,点赞22次,收藏9次。msg_box = QMessageBox(QMessageBox.Warning, ‘温馨提示’, ‘用户名和密码不能为空’)msg_box = QMessageBox(QMessageBox.Warning, ‘错误提示’, ‘用户名或者密码错误’)msg_box = QMessageBox(QMessageBox.Warning, ‘温馨提示’, ‘用户名已经存在’)msg_box = QMessageBox(QMessageBox.Warning, ‘温馨提示’, ‘数据库连接错误’)

FreeType在嵌入式系统中显示矢量字体_矢量字体 csdn-程序员宅基地

文章浏览阅读83次。在这个示例中,我们使用FT_Load_Glyph()函数加载字符索引为charIndex的字符。在这个例子中,我们使用FT_Set_Pixel_Sizes()函数设置字体的像素大小。在这个例子中,我们包含了FreeType的头文件,并定义了一个FT_Library对象来表示FreeType库的实例。在这个示例中,我们使用FT_New_Face()函数加载名为"font.ttf"的字体文件。一旦字体的大小和字符编码设置完成,我们可以进行字体的渲染和显示。在显示字体之前,我们需要设置字体的大小和字符编码。_矢量字体 csdn

Mysql的列式数据库infobright存储引擎_列式存储数据库选型-程序员宅基地

文章浏览阅读7.9k次。什么是infobright? Infobright是一个与MySQL集成的开源数据仓库软件,可作为MySQL的一个存储引擎来使用,SELECT查询与普通MySQL无区别。优点:Ø查询性能高 --比普通Mysql 数据库引擎(MyISAM、InnoDB) 快5-60倍.Ø存储数据量大 --能存储的数据量特别大.Ø高压缩比 --_列式存储数据库选型

学生党双十一蓝牙耳机选购指南,高颜值平价实用蓝牙耳机推荐_击音f1-程序员宅基地

文章浏览阅读179次。蓝牙耳机发展到现在算是达到了高峰,其中涌现的品牌产品不计其数。这就让很多消费者对蓝牙耳机的购买关注点发生了变化,从只认品牌到追求性价比了,而且现在许多平价蓝牙耳机的确是非常值得入手的。刚好双十一也快来临了,又到了购物狂欢节,所以小编就整理了一些性价比高且性能优异的蓝牙耳机,分享给各位。击音F1击音F1搭载了全新的蓝牙5.0芯片,在更高效稳定连接的同时,还将声音信号同时传达到左右耳单元,做到了更低延迟,可以听声辨位占据主动,配合着出众的AAC/SBC高清解码,优化还原了CD级音质,不管是听音乐还是_击音f1

如何定制丝网印刷电极-程序员宅基地

文章浏览阅读30次。丝网印刷电极(Screen-printed electrodes,SPE)是利用印刷技术将碳胶、银胶等各类不同胶材,以不同的设计图样印刷于不易溶解于水的基板/底板上而得到的电极。我们要再聊一下当市售电极无法满足实验需求是该如何定制化丝网印刷电极的。

【张兔兔送书第一期:考研必备书单】-程序员宅基地

文章浏览阅读4k次,点赞55次,收藏55次。八九月的朋友圈刮起了一股晒通知书潮,频频有大佬晒出“研究生入学通知书”,看着让人既羡慕又焦虑。果然应了那句老话——比你优秀的人,还比你努力。

随便推点

Thinkpad笔记本键盘拆卸_thinkpad键帽拆卸图解-程序员宅基地

文章浏览阅读7.5w次,点赞2次,收藏9次。1、键盘的拆卸并不需要从背板开始,可以直接拆键盘。可以参考视频http://v.youku.com/v_show/id_XMzg4MTc4NjUyNA==.html?spm=a2h0j.11185381.listitem_page1.5!2~A2、键盘帽的拆卸。先扣左上角,再扣右上角,再慢慢拉掉下面的部分,就可以卸掉键帽。安装键帽,只需要按下去,听到两声咔咔就行了。3、键盘x支..._thinkpad键帽拆卸图解

【Godot4.2】注释习惯 -- 拒绝屎山,提高代码可读性_godot 注释-程序员宅基地

文章浏览阅读1.1k次,点赞32次,收藏12次。我个人于2020年9月左右开始接触Godot,在2021年8月汉化一个关于GDScript脚本注释习惯的视频时,学习到了一些有用的代码注释规则,于是逐渐将一些注释习惯引入自己的代码书写中。这些注释习惯一直延续至今,并逐渐形成我自己的一种风格。本篇就来介绍一下我自己的注释习惯,以及谈谈这样做的好处。当然你并不需要完全和我一致,每个人都有自己的习惯。如果你觉得还有哪些好的提高代码可读性的好方法,可以留言或讨论。希望本篇内容对学习Godot的小伙伴们有用。_godot 注释

ChatGPT能测试用例,那么测试人员会被取代吗?_有人说chatgpt将会替代软件测试工程师(点工)-程序员宅基地

文章浏览阅读3.2k次。功能测试:检查用户名、密码、验证码的输入和校验,以及登录按钮的点击和跳转 性能测试:检查登录界面的加载速度,以及不同情况下的响应时间 界面测试:检查登录界面的布局、样式、字体、颜色等是否符合设计要求 安全性测试:检查是否有防止SQL注入、暴力破解、跨站脚本等攻击的措施 兼容性测试:检查在不同的浏览器、操作系统、分辨率下是否能正常显示和使用 可用性测试:检查是否支持Tab和Enter键,以及提示语是否友好 你想要我给你具体的例子吗?从功能覆盖率上说也没啥问题,基本的要点都有,而且异常情况也有比较多的覆盖。_有人说chatgpt将会替代软件测试工程师(点工)

Android 会议电话应用设计_android 三方通话无分离-程序员宅基地

文章浏览阅读1k次,点赞3次,收藏10次。背景以下内容基于Android P code。 并以三方通话为例。合并通话IMS先看下合并通话后Call、Connection的变化:合并通话后Call Connection的变更1. 合并通话后把新的ImsCallSession给了原来的foreground的ImsCall,原来的两个ImsCallSession都断开了。合并通话后ImsCallSession..._android 三方通话无分离

解决 Caused by: net.sf.jsqlparser.parser.ParseException: Encountered unexpected token:XXXXXXX_存储过程 encountered unexpected token: ")" ")-程序员宅基地

文章浏览阅读2.2k次。解决 Caused by: net.sf.jsqlparser.parser.ParseException: Encountered unexpected token:XXXXXXX_存储过程 encountered unexpected token: ")" ")

Android页面跳转动画简介_android 页面跳转动画-程序员宅基地

文章浏览阅读382次。在项目中常用到的页面跳转的方式主要有两种:1、通过在startActivity后执行overridePendingTransition方法进行动画的切换。overridePendingTransition(R.anim.left_in,R.anim.left_out); 其中第一个参数为activity进入时的效果,具体效果可以自己实现。left_in:xml versi_android 页面跳转动画