寒假学习12篇
### 2.1 向SQL语句传参
#### 2.1.1 **mybatis日志输出配置**
mybatis配置文件设计标签和顶层结构如下:
 - configuration(配置)
        - [properties(属性)](https://mybatis.org/mybatis-3/zh/configuration.html#properties)
        - [settings(设置)](https://mybatis.org/mybatis-3/zh/configuration.html#settings)
        - [typeAliases(类型别名)](https://mybatis.org/mybatis-3/zh/configuration.html#typeAliases)
        - [typeHandlers(类型处理器)](https://mybatis.org/mybatis-3/zh/configuration.html#typeHandlers)
        - [objectFactory(对象工厂)](https://mybatis.org/mybatis-3/zh/configuration.html#objectFactory)
        - [plugins(插件)](https://mybatis.org/mybatis-3/zh/configuration.html#plugins)
        - [environments(环境配置)](https://mybatis.org/mybatis-3/zh/configuration.html#environments)
            - environment(环境变量)
                - transactionManager(事务管理器)
                - dataSource(数据源)
        - [databaseIdProvider(数据库厂商标识)](https://mybatis.org/mybatis-3/zh/configuration.html#databaseIdProvider)
        - [mappers(映射器)](https://mybatis.org/mybatis-3/zh/configuration.html#mappers)
我们可以在mybatis的配置文件使用**settings标签**设置,输出运过程SQL日志!
通过查看日志,我们可以判定#{} 和 ${}的输出效果!
settings设置项:
|logImpl|指定 MyBatis 所用日志的具体实现,未指定时将自动查找。|SLF4J | LOG4J(3.5.9 起废弃) | LOG4J2 | JDK_LOGGING | COMMONS_LOGGING | STDOUT_LOGGING | NO_LOGGING|未设置|
|-|-|-|-|
    日志配置:
```XML
<settings>
  <!-- SLF4J 选择slf4j输出! -->
  <setting name="logImpl" value="SLF4J"/>
</settings>
```
#### 2.1.2 **#{}形式**
Mybatis会将SQL语句中的#{}转换为问号占位符。
#### 2.1.3 **${}形式**
${}形式传参,底层Mybatis做的是字符串拼接操作。
通常不会采用${}的方式传值。一个特定的适用场景是:通过Java程序动态生成数据库表,表名部分需要Java程序通过参数传入;而JDBC对于表名部分是不能使用问号占位符的,此时只能使用
结论:实际开发中,能用#{}实现的,肯定不用${}。
特殊情况: 动态的不是值,是列名或者关键字,需要使用${}拼接
```Java
//注解方式传入参数!!
@Select("select * from user where ${column} = #{value}")
User findByColumn(@Param("column") String column, 
                                @Param("value") String value);
```
### 2.2 数据输入
#### 2.2.1 **Mybatis总体机制概括**
#### 2.2.2 **概念说明**
这里数据输入具体是指上层方法(例如Service方法)调用Mapper接口时,数据传入的形式。
    - 简单类型:只包含一个值的数据类型
        - 基本数据类型:int、byte、short、double、……
        - 基本数据类型的包装类型:Integer、Character、Double、……
        - 字符串类型:String
    - 复杂类型:包含多个值的数据类型
        - 实体类类型:Employee、Department、……
        - 集合类型:List、Set、Map、……
        - 数组类型:int[]、String[]、……
        - 复合类型:List<Employee>、实体类中包含集合……
#### 2.2.3 **单个简单类型参数**
Mapper接口中抽象方法的声明
```Java
Employee selectEmployee(Integer empId);
```
SQL语句
```XML
<select id="selectEmployee" resultType="com.atguigu.mybatis.entity.Employee">
  select emp_id empId,emp_name empName,emp_salary empSalary from t_emp where emp_id=#{empId}
</select>
```
> 单个简单类型参数,在#{}中可以随意命名,但是没有必要。通常还是使用和接口方法参数同名。
#### 2.2.4 **实体类类型参数**
Mapper接口中抽象方法的声明
```Java
int insertEmployee(Employee employee);
```
SQL语句
```XML
<insert id="insertEmployee">
  insert into t_emp(emp_name,emp_salary) values(#{empName},#{empSalary})
</insert>
```
对应关系
结论
Mybatis会根据#{}中传入的数据,加工成getXxx()方法,通过反射在实体类对象中调用这个方法,从而获取到对应的数据。填充到#{}解析后的问号占位符这个位置。
#### 2.2.5 **零散的简单类型数据**
零散的多个简单类型参数,如果没有特殊处理,那么Mybatis无法识别自定义名称:

Mapper接口中抽象方法的声明
```Java
int updateEmployee(@Param("empId") Integer empId,@Param("empSalary") Double empSalary);
```
SQL语句
```XML
<update id="updateEmployee">
  update t_emp set emp_salary=#{empSalary} where emp_id=#{empId}
</update>
```
对应关系

#### 2.2.6 **Map类型参数**
Mapper接口中抽象方法的声明
```Java
int updateEmployeeByMap(Map<String, Object> paramMap);
```
SQL语句
```XML
<update id="updateEmployeeByMap">
update t_emp set emp_salary=#{empSalaryKey} where emp_id=#{empIdKey}
</update>
```
junit测试
```Java
private SqlSession session;
//junit5会在每一个@Test方法前执行@BeforeEach方法
@BeforeEach
public void init() throws IOException {
    session = new SqlSessionFactoryBuilder()
            .build(
                    Resources.getResourceAsStream("mybatis-config.xml"))
            .openSession();
}
@Test
public void testUpdateEmpNameByMap() {
  EmployeeMapper mapper = session.getMapper(EmployeeMapper.class);
  Map<String, Object> paramMap = new HashMap<>();
  paramMap.put("empSalaryKey", 999.99);
  paramMap.put("empIdKey", 5);
  int result = mapper.updateEmployeeByMap(paramMap);
  log.info("result = " + result);
}
//junit5会在每一个@Test方法后执行@@AfterEach方法
@AfterEach
public void clear() {
    session.commit();
    session.close();
}
```
**对应关系**
#{}中写Map中的key
**使用场景**
有很多零散的参数需要传递,但是没有对应的实体类类型可以使用。使用@Param注解一个一个传入又太麻烦了。所以都封装到Map中。
 
                    
                     
                    
                 
                    
                
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号