MyBatis

这里写目录标题

1. 什么是框架?

简历、楼房
我们自己书写代码经常有不规范的地方,但使用了别人的框架之后,约束和方便了我们代码的编写。
框架可以被认为是别人帮我们写好了绝大多数的规则和代码,你只需要按照这个框架的要求填写进去就可以了。

框架既然是别人写好的代码,那么他们一般是以一些jar包的方式提供给我们使用的。

2. 什么是SSM或SSH框架或三大框架整合?

SSH:Spring框架,Struts2框架,Hibernate/JPA框架
SSM:Spring框架,Spring MVC框架,MyBatis框架
当然,这些框架的组合并不是完全固定的,可以任意组合。

3. 什么是MyBatis框架?

MyBatis是一个持久层框架。专门负责与数据库的交互,即替代了以前的JDBC。
但是MyBatis并非是一个新的数据库连接技术,他的所有代码都是采用JDBC的基本技术书写的。
即Java中连接数据库只有JDBC,MyBatis只是在JDBC的基础上进行了加工,更方便我们使用了。

4. 什么是持久化?

将程序中的数据在持久状态(数据库)和瞬时状态(内存)之间进行转换的机制。
比如一个new User(1, “Tom”, 10);这个对象就是瞬时,断电即丢失或程序结束即丢失。
但是一旦他被存入数据库表格中,就被认为是持久的。

注意:持久化是一个双向的过程,即从数据库里读也算持久化

5. ORM(对象关系映射):Object Relational Mapping

关系:一个数据库表格就叫一个二元关系,简称关系,或者称作关系型表格
5.1 将一个对象和表格中的一行进行对应
id name age
1 tom 10 new User(1, “tom”, 10)
2 jerry 4 new User(2, “jerry”, 4)
3 ben 12 new User(3, “ben”, 12)

5.2 将一个类和一个表格的结构进行对应
class User{
Integer id;
String name;
Integer age;
}

create table users(
  id int, 
  name varchar(30),
  age int
);

搭建一个最简单的MyBatis程序

1. 删除和建立数据库表格,注意暂时不要使用复杂类型,如日期和枚举

drop table if exists users;
create table users(
id int,
name varchar(30),
age int
);

2. 建立实体

3. 建立dao层接口,我们就做2个功能,即插入和查询

public interface UserDao {
List select();
int insert(User user);
}

搭建一个最简单的MyBatis程序

1. 删除和建立数据库表格,注意暂时不要使用复杂类型,如日期和枚举

drop table if exists users;
create table users(
id int,
name varchar(30),
age int
);

2. 建立实体

3. 建立mapper层接口,

public interface UserMapper {
List select();
int insert(User user);
}
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
MyBatis习惯将Dao写成Mapper,并放入mapper包的里面
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️

之后的做法有两种:
3.1 采用注解
在Mapper接口的每一个方法上,写好其对应的SQL语句
public interface UserMapper {
@Select(“select * from users”)
List select();

  @Insert("insert into users(id, name, age) values(#{id}, #{name}, #{age})")
  //JDBC中通常采用?进行占位,但是MyBatis需要使用#{}的形式来完成占位
  //{}的里面需要写的是参数中属性的名字,即下面方法参数是User,{}中放置的是User中属性的名字
  int insert(User user);

}

3.2 采用配置文件

4. 在resources文件夹中建立mybatis-config.xml文件(文件名是任意指定的,不一定非要叫这个名字)

<?xml version="1.0" encoding="UTF-8" ?> ⚠️⚠️⚠️数据库驱动 ⚠️⚠️⚠️数据库URL,有时区问题的同学记得加时区timeZone ⚠️⚠️⚠️ ⚠️⚠️⚠️ ⚠️⚠️⚠️此处是dao层接口的包名和接口名 ⚠️⚠️⚠️如果一个项目中有多个dao层的接口,需要在此处分别列出⚠️⚠️⚠️ ⚠️⚠️⚠️之所以这样做就是告诉MyBatis发现这个接口的存在⚠️⚠️⚠️

5. 准备进行测试

⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
只有接口怎么测试?MyBatis根据这个接口在后台帮我自动生成了实现类(看不到)

package com.google.db.dao;

import com.google.db.entity.User;
import com.google.db.mapper.UserMapper;
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 org.junit.After;
import org.junit.Before;
import org.junit.Test;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;

import static org.junit.Assert.*;

public class UserDaoTest {

private SqlSessionFactory sqlSessionFactory;
private SqlSession sqlSession;

@After//After表示之后的,即在所有Test方法执行之后,会执行这个方法的内容
public void after() throws IOException {
    sqlSession.close();  //数据库连接用完后记得关闭
}

@Before //Before表示之前的,即在所有Test方法执行之前,会执行这个方法的内容
public void before() throws IOException {
    InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
    //MyBatis提供了一个类Resources和方法getResourceAsStream用来在一个mybatis-config.xml文件上打开输入流
    sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
    //用这个文件中的信息构建一个重量级的对象sqlSessionFactory
    //这个对象整个项目中应该只有一个,且不应该被轻易关闭,它代表了整个MySQL数据库的信息

    sqlSession = sqlSessionFactory.openSession();
    //sqlSession表示一个MyBatis到数据库的连接,类似于JDBC中的Connection
}

@Test
public void selectTest() throws IOException {
    UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
    //getMapper方法的含义就是拿到MyBatis在后台帮我们生成的那个接口的实现
    List<User> users = userMapper.select();
    for(User user : users)
        System.out.println(user);  //users.forEach(System.out::println);
}

@Test
public void saveTest() throws IOException {
    UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
    userMapper.insert(new User(2, "Jerry", 3));
    sqlSession.commit(); //对于增删改,都需要提交事务
}

}

错误问题

  1. junit测试方法不能有参数,不能有返回值

  2. Caused by: org.xml.sax.SAXParseException; lineNumber: 2; columnNumber: 6;

  3. xml文件第一行不要空白

  4. Caused by: java.lang.ClassNotFoundException: Cannot find class: com.google.db.mapper.UserMapp1er

    @Delete(“delete from users where id = #{id}”)
    int delete(Integer id);

    @Update(“update users set name=#{name}, age=#{age} where id = #{id}”)
    int update(User user);

    @Test
    public void deleteTest() throws IOException {
    UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
    userMapper.delete(2);
    sqlSession.commit(); //对于增删改,都需要提交事务
    }

    @Test
    public void updateTest() throws IOException {
    UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
    userMapper.update(new User(2, “Ben”, 5));
    sqlSession.commit(); //对于增删改,都需要提交事务
    }

顺序

  1. 建立数据库表格

  2. 建立实体

  3. 建立接口
    public interface UserMapper {
    List select();
    int insert(User user);
    int delete(Integer id);
    int update(User user);
    }

  4. 为每一个接口,在mappers文件夹下建立对应的xml文件。
    文件名是接口名.xml

这个文件,有些类似是这个接口的实现,其作用和之前的注解的作用是一致的。

⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
mybatis-config.xml叫做mybatis的“配置文件”,每个项目一般只有一个,后期学习了Spring框架后,这个文件一般就没用了。

Mapper结尾的xml文件被称为“映射文件”,每个接口都有一个对应的映射文件
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️

<?xml version="1.0" encoding="UTF-8" ?>
<!--如果一个方法有参数,就需要加好parameterType; 如果一个方法是查询,就需要加resultType-->
<select id="select" resultType="com.google.db.entity.User">
    select * from users
</select>

<!--parameterType指一个方法中的参数类型,这里的类型也要写好包名和接口名-->
<insert id="insert" parameterType="com.google.db.entity.User">
    insert into users(id, name, age) values(#{id}, #{name}, #{age})
</insert>

<update id="update" parameterType="com.google.db.entity.User">
    update users set name=#{name}, age=#{age} where id = #{id}
</update>

<delete id="delete" parameterType="java.lang.Integer">
    delete from users where id = #{id}
</delete>
  1. 修改mybatis-config.xml
    将昨天的

    修改为

  2. org.apache.ibatis.binding.BindingException: Type interface com.google.db.mapper.UserMapper is not known to the MapperRegistry.
    忘记在mybatis-config.xml中加入接口,无论是注解的还是xml形式的,忘记写了
    看映射文件中,namespace后面的包和接口名是不是写错了。

  3. Caused by: java.io.IOException: Could not find resource mapper/UserMapper.xml
    文件不存在,仔细看路径,位置是否正确

  4. Caused by: java.lang.ClassNotFoundException: Cannot find class: com.google.db.entity1.User
    找不到类,即包名+类名写错了,

当数据库的列和实体的属性不能完全对应的时候,就要使用结果映射。

<resultMap id="userResultMap" type="com.google.db.entity.User" >
    <!--id是一个resultMap的名字,任意指定-->
    <!--type是表明哪个实体和数据库中的表格进行对应,值是这个实体的全路径-->
    <id column="id" property="id" javaType="java.lang.Integer" jdbcType="INTEGER" />
    <!--id表示主键,column表示数据库中列的名字,property表示实体中属性的名字-->
    <!--javaType是property属性在java中的类型, jdbcType是column在数据库中的类型-->
    <result column="name" property="name" javaType="java.lang.String" jdbcType="VARCHAR" />
    <!--result表示一个普通列,其余和id一样-->
    <result column="age" property="age" javaType="java.lang.Integer" jdbcType="INTEGER" />
</resultMap>

仅仅在xml文件中加入结果映射是没用的,还需要对其进行使用。
在哪里使用呢?

注意:只有select才能查询结果,才需要结果映射,所以resultMap是用在select中的。

s elect * from users

这里的resultMap="userResultMap"就表示这个查询语句的结果,采用一个ID是userResultMap的结果映射来完成。

resultType和resultMap属性有什么区别呢?

resultType=“com.google.db.entity.User”
resultMap=“userResultMap”
尽量在程序中使用resultMap,除非你这个实体和表格的列名能够被MyBatis自动对应

主键自增⚠️只有insert才会涉及到主键自增

drop table if exists users;
create table users
(
id int primary key auto_increment,
name varchar(30),
age int
);

<insert id="insert" parameterType="com.google.db.entity.User" useGeneratedKeys="true" keyProperty="id"> 
    insert into users(name, age) values(#{name}, #{age})
</insert>



@Test
public void saveTest() throws IOException {
    UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
    userMapper.insert(new User("Jerry", 3));
    sqlSession.commit(); //对于增删改,都需要提交事务
}

如何处理枚举和日期时间类型

drop table if exists logs;
create table logs(
id int primary key auto_increment,
login_time timestamp,
done enum(‘T’, ‘F’)
);

建立实体
public enum Done {
T,F
}

public class Log {
private Integer id;
private LocalDateTime loginTime;
private Done done;

......

}

  1. 建立和实体对应的接口
    public interface LogMapper {
    int insert(Log log);
    List select();
    }

  2. 建立LogMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<select id="select" resultMap="logResultMap">select * from logs</select>

<insert id="insert">
</insert>

关于作业的插入:

insert into users2 (id, name, funkyNumber, roundingMode) values (
#{id}, #{name}, #{funkyNumber}, #{roundingMode, typeHandler=org.apache.ibatis.type.EnumTypeHandler}
)

  1. 在mybatis的配置文件中加入

  2. 测试
    @Test
    public void selectTest() {
    LogMapper logMapper = sqlSession.getMapper(LogMapper.class);
    logMapper.select().forEach(System.out::println);
    }


insert into logs(done, login_time) values(#{done, typeHandler=org.apache.ibatis.type.EnumTypeHandler}, #{loginTime})
    @Test
public void saveTest() {
    LogMapper logMapper = sqlSession.getMapper(LogMapper.class);
    logMapper.insert(new Log(LocalDateTime.of(2020,1,1,1,1,1), Done.F));
    sqlSession.commit();
}

建立表格,实体,Mapper,测试

要求表格有int, varchar, 日期/时间/时间戳,枚举,主键自增

drop table if exists users;
create table users
(
u_id int primary key auto_increment,
email varchar(50),
password varchar(30),
login_count int,
last_login_time timestamp
);
drop table if exists logs;
create table logs
(
l_id int primary key auto_increment,
u_id int,
login_time timestamp
);

  1. 如果两个表格在数据库中存在主外键关系,应该采用关联映射

当一个实体中存在对应的外键时,我们更愿意将外键直接写为另一个实体的引用,而不是参照数据库中的列类型了。

就我们当前的例子来说,Log这个实体中存在一个外键,即uid

public class Log {
private Integer lId;
private Integer uId; //这一列代表的就是外键,目前来讲,他是和数据库中的列类型保持一致的。
private LocalDateTime loginTime;
}

但是我现在更愿意改写为下面的形式

public class Log {
private Integer lId;
private User user; //将外键直接写为另一个实体的引用
private LocalDateTime loginTime;
}

  1. 对接口进行适当改写
    ⚠️⚠️⚠️⚠️⚠️MyBatis的接口不支持方法重载⚠️⚠️⚠️⚠️⚠️
    public interface UserMapper {
    int insert(User user);
    String selectByEmail(String email);
    User selectByEmailAndPassword(@Param(“email”) String email, @Param(“password”)String password);
    int update(User user);
    }

当MyBatis的方法有多个参数时,每个参数应该加上@Param注解
User selectByEmailAndPassword(@Param(“email”) String email, @Param(“password”)String password);

@Param(“这里的内容就是稍后在SQL语句中#{}中的名字”)

当一个类出现在另一个类中的时候,我们就说这两个类产生了关联。一旦有了关联关系,就需要采用

insert into logs(u_id, login_time) values(#{user.uId}, #{loginTime})
注意:#{user.uId} 
<resultMap id="logResultMap" type="com.google.entity.Log">
    <id column="l_id" property="lId" />
    <result column="login_time" property="loginTime" jdbcType="TIMESTAMP" javaType="java.time.LocalDateTime" />
    <association column="u_id" property="user" jdbcType="INTEGER" javaType="com.google.entity.User">
        <id column="u_id" property="uId"/>
        <result column="email" property="email"/>
        <result column="password" property="password"/>
        <result column="login_count" property="loginCount"/>
        <result column="last_login_time" property="lastLoginTime" javaType="java.time.LocalDateTime" jdbcType="TIMESTAMP"/>
    </association>
</resultMap>

为了让关联映射能够起作用,一般都是要做两表连接的,因为只有SQL语句能查询出结果,Java中才有可能将这些结果存入对应的实体。

当结果从数据库中查询出来之后,需要哪些内容被填充,就要看是否进行映射了,比如password

关联映射

关联映射分为单向关联和双向关联,怎么区分?
一个类中包含另一个类的引用,就是单向。互相包含就是双向,比如

class A{}
class B{
private A a; //
}
此时我们说A和B是单向关联

class C{
private List ds = new ArrayList<>();
}
class D{
private C c;
}
此时我们说C和D是双向关联
class C{
private D d;
}
class D{
private C c;
}

<?xml version="1.0" encoding="UTF-8"?>
<insert id="insert" parameterType="com.google.entity.Log">
    insert into logs(u_id, login_time) values(#{user.uId}, #{loginTime})
</insert>

<select id="select" parameterType="java.lang.Integer" resultMap="logResultMap">
    select * from logs l inner join users u on l.u_id = u.u_id
    where l.u_id = #{uId}
</select>
@Test
public void saveTest() {
    LogMapper logMapper = sqlSession.getMapper(LogMapper.class);
    User user = new User();
    user.setuId(1);
    Log log = new Log(1, user, LocalDateTime.now());
    logMapper.insert(log);
    sqlSession.commit();
}

@Test
public void selectTest() {
    LogMapper logMapper = sqlSession.getMapper(LogMapper.class);
    logMapper.select(1).forEach(System.out::println);
}
    <dependency>
        <groupId>log4j</groupId>
        <artifactId>log4j</artifactId>
        <version>1.2.17</version>
    </dependency>

日志:记录程序运行过程中所产生的一些信息,这些信息用于帮助我们查看程序运行的状态和错误信息。

日志文件的名字是log4j.properties

log4j.rootLogger=ERROR, stdout

log4j.logger.com.google.mapper.LogMapper=TRACE
log4j.logger.com.google.mapper.UserMapper=TRACE

log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n

缓存:主要目的是为了加快查询的效率。也就是说只有查询才会用到缓存。

1. 一级缓存:MyBatis中的一级缓存实际上就是把查询出来的内容缓存在sqlSession中,这个就是一级缓存。一级缓存必须使用,不能关闭。

DEBUG [main] - > Preparing: select * from users where email=? and password=?
DEBUG [main] - > Parameters: jerry@google.com(String), 654321(String)
TRACE [main] - <
Columns: u_id, email, password, login_count, last_login_time
TRACE [main] - <
Row: 1, jerry@google.com, 654321, 0, 2020-07-29 21:59:52
DEBUG [main] - <== Total: 1
User{uId=1, email=‘jerry@google.com’, password=‘654321’, loginCount=0, lastLoginTime=2020-07-29T21:59:52}

DEBUG [main] - ==> Preparing: select * from users where email=? and password=?
DEBUG [main] - > Parameters: xxx(String), yyy(String)
DEBUG [main] - <
Total: 0
null

DEBUG [main] - > Preparing: select * from users where email=? and password=?
DEBUG [main] - > Parameters: jerry@google.com(String), 654321(String)
TRACE [main] - <
Columns: u_id, email, password, login_count, last_login_time
TRACE [main] - <
Row: 1, jerry@google.com, 654321, 0, 2020-07-29 21:59:52
DEBUG [main] - <== Total: 1
User{uId=1, email=‘jerry@google.com’, password=‘654321’, loginCount=0, lastLoginTime=2020-07-29T21:59:52}
User{uId=1, email=‘jerry@google.com’, password=‘654321’, loginCount=0, lastLoginTime=2020-07-29T21:59:52}

@Test
public void selectByEmailAndPasswordTest() {
    UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
    System.out.println(userMapper.selectByEmailAndPassword("jerry@google.com", "654321"));

    sqlSession.close();

    sqlSession = sqlSessionFactory.openSession();
    userMapper = sqlSession.getMapper(UserMapper.class);
    System.out.println(userMapper.selectByEmailAndPassword("jerry@google.com", "654321"));
}

sqlSession.close();缓存一旦被关闭,之前一级缓存的结果就丢失了。

2. 二级缓存:二级缓存是跨越sqlSession的缓存,即二级缓存的内容并非存在于sqlSession中。

即便sqlSession被关闭,二级缓存的内容依然存在。二级缓存可以选择的,默认是关闭的。

缓存

  1. 一级缓存:sqlSession级别的缓存,不能关闭,必须使用。

  2. 二级缓存:跨sqlSession的缓存,即sqlSession关闭后,内容依然存在于二级缓存中。
    二级缓存默认是关闭的,想要使用需要先开启。

加入映射文件,之后就启用了二级缓存

想要把查询出来的内容放入二级缓存,要求这个内容必须是可序列化的。

MyBatis的二级缓存默认是如何实现的?

mybatis自带的二级缓存其实不太好用,所以通常我们会用一些第三方工具如redis等来替代它自身的二级缓存。

当一个SQL语句会根据不同条件发生变化时,我们就考虑使用动态SQL

select * from users where id = #{id} 不完整

比如我的一个SQL要求是uId不空就按照uId查询,如果uId为空就按照email查询
select * from users where u_id = #{uId}
select * from users where email = #{email}

List select(User user);

select * from users and email = #{email} and login_count >= #{loginCount} and email = #{email} and login_count >= #{loginCount}
@Test
public void selectTest() throws InterruptedException {
    UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
    User user = new User();
    //user.setEmail("ben@google.com");
    //user.setLoginCount(3);
    userMapper.select(user).forEach(System.out::println);
}
select * from users and email = #{email}
            <when test="loginCount != null">
                and login_count >= #{loginCount}
            </when>

            <when test="email != null and loginCount != null">
                and email = #{email} and login_count >= #{loginCount}
            </when>
        </choose>
    </where>
</select>

update users email=#{email}, password=#{password}, login_count=#{loginCount}, last_login_time=#{lastLoginTime} where u_id=#{uId}

select *
from users
where u_id in (1, 3, 5, 7);

List selectByIds(@Param(“ids”) List ids);

<select id="selectByIds" resultMap="userResultMap">
    select * from users where u_id in
    <foreach item="uId" collection="ids" open="(" separator="," close=")">
        #{uId}
    </foreach>
</select>


@Test
public void selectTest() throws InterruptedException {
    UserMapper userMapper = sqlSession.getMapper(UserMapper.class);

    List<Integer> ids = new ArrayList<>();
    ids.add(1); ids.add(3); ids.add(5); ids.add(7);

    userMapper.selectByIds(ids).forEach(System.out::println);
}
<?xml version="1.0" encoding="UTF-8"?>


4.0.0

<groupId>com.google</groupId>
<artifactId>spring</artifactId>
<version>1.0-SNAPSHOT</version>

<dependencies>
    <!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>5.2.8.RELEASE</version>
    </dependency>

    <!-- https://mvnrepository.com/artifact/org.springframework/spring-test -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-test</artifactId>
        <version>5.2.8.RELEASE</version>
        <scope>test</scope>
    </dependency>
</dependencies>

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.6.1</version>
            <configuration>
                <source>1.8</source>
                <target>1.8</target>
            </configuration>
        </plugin>
    </plugins>
</build>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
大学生参加学科竞赛有着诸多好处,不仅有助于个人综合素质的提升,还能为未来职业发展奠定良好基础。以下是一些分析: 首先,学科竞赛是提高专业知识和技能水平的有效途径。通过参与竞赛,学生不仅能够深入学习相关专业知识,还能够接触到最新的科研成果和技术发展趋势。这有助于拓展学生的学科视野,使其对专业领域有更深刻的理解。在竞赛过程中,学生通常需要解决实际问题,这锻炼了他们独立思考和解决问题的能力。 其次,学科竞赛培养了学生的团队合作精神。许多竞赛项目需要团队协作来完成,这促使学生学会有效地与他人合作、协调分工。在团队合作中,学生们能够学到如何有效沟通、共同制定目标和分工合作,这对于日后进入职场具有重要意义。 此外,学科竞赛是提高学生综合能力的一种途径。竞赛项目通常会涉及到理论知识、实际操作和创新思维等多个方面,要求参赛者具备全面的素质。在竞赛过程中,学生不仅需要展现自己的专业知识,还需要具备创新意识和解决问题的能力。这种全面的综合能力培养对于未来从事各类职业都具有积极作用。 此外,学科竞赛可以为学生提供展示自我、树立信心的机会。通过比赛的舞台,学生有机会展现自己在专业领域的优势,得到他人的认可和赞誉。这对于培养学生的自信心和自我价值感非常重要,有助于他们更加积极主动地投入学习和未来的职业生涯。 最后,学科竞赛对于个人职业发展具有积极的助推作用。在竞赛中脱颖而出的学生通常能够引起企业、研究机构等用人单位的关注。获得竞赛奖项不仅可以作为个人履历的亮点,还可以为进入理想的工作岗位提供有力的支持。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值