Mybatis基本使用

Mybatis基本使用

1.日志输出

在mybatis-config.xml 中的settings 标签配置 mybatis的设置项

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

设置日志的属性是 logImpl,其候选值有 SLF4J、LOG4J、LOG4J2、STDOUT_LOGGING、NOLOGGING等

image-20240809175305508

 

2. #{} 和 ${} 区别

#{} :表示占位符 + 赋值,也就是先用 去占位,然后把你传进来的值赋值进去。

<select id="queryById" resultType="com.ztone.pojo.Employee">
    select emp_id empId, emp_name empName, emp_salary empSalary from t_emp
        where emp_id = #{id};
</select>

image-20240811102549393

可以看到sql的执行是先用 ? 进行占位,然后把参数赋值进去

${}:表示字符串拼接,是直接把你传进去的值拼接到sql语句上

<select id="queryById" resultType="com.ztone.pojo.Employee">
    select emp_id empId, emp_name empName, emp_salary empSalary from t_emp
        where emp_id = ${id};
</select>

image-20240811102722705

可以看到,这种方式是直接把参数拼接到了 sql 中

 

建议使用#{} ,可以防止注入问题,但是这种方式只能是将sql语句中的值去占位,不能将列名占位,如果想动态控制列名就要使用 ${}

 

3. 传入参数

在使用 #{} 或 ${} 接值的时候传入参数的规定

3.1 单个参数

简单类型如 Integer、Float、Double等,在 #{} 中可以随意起名,但建议和传入的参数名相同,如上面的id

如果参数是实体对象,在接收值的时候就是用 该对象的属性

public interface EmployeeMapper {
    int insertEmp(Employee employee);
}
<insert id="insertEmp">
    insert into t_emp(emp_name, emp_salary) values(#{empName}, #{empSalary});
</insert> 

 

3.2 多个参数

简单类型

当你传入的参数是多个时,就不能随意起名了,也不能用 传入的参数名。

public interface EmployeeMapper {
    
    List<Employee> queryByNameAndSalary(String name, Double salary);
}

有三种解决方案:

  • 在这个方法的形参上使用@Param注解来指定参数的名称,在sql语句中就可以使用这个名称了

    public interface EmployeeMapper {
        List<Employee> queryByNameAndSalary(@Param("empName") String name, @Param("empSalary") Double salary);
    }
    <select id="queryByNameAndSalary" resultType="com.ztone.pojo.Employee">
        select emp_id empId, emp_name empName, emp_salary empSalary from t_emp
            where emp_name = #{empName} and emp_salary = #{empSalary}
    </select>
  • mybatis 的特殊机制,是根据参数的索引,arg0、arg1 .......

    <select id="queryByNameAndSalary" resultType="com.ztone.pojo.Employee">
        select emp_id empId, emp_name empName, emp_salary empSalary from t_emp
            where emp_name = #{arg0} and emp_salary = #{arg1}
    </select>
  • 第三种方式和第二种类似。param1、param2.......

 

Map类型,使用map的key接收值

public interface EmployeeMapper {

    int insertEmpMap(Map employeeMap);
}
<insert id="insertEmpMap">
    insert into t_emp(emp_name, emp_salary) values(#{name}, #{salary});
</insert>
EmployeeMapper mapper = sqlSession.getMapper(EmployeeMapper.class);

Map map = new HashMap();

map.put("name","zhangsan");
map.put("salary",200.0);

int i = mapper.insertEmpMap(map);

 

4.返回值指定

4.1 返回单个

在DML(插入、删除、更新)操作中不需要指定返回值的类型,都是int

在查询操作中,如果返回的是基本数据类型

在<select 标签中的resultType属性指定 返回值的类型,一般是类的全限定符

public interface EmployeeMapper {

    String queryNameById(Integer id);
    
    Double querySalaryById(Integer id);
}
<select id="queryNameById" resultType="java.lang.String">
    select emp_name empName from t_emp where emp_id = ${id};
</select>

<select id="querySalaryById" resultType="java.lang.Double">
    select emp_salary empName from t_emp where emp_id = ${id};
</select>

Mybatis 提供了 常用类型的 简单别名,基本数据类型 int --> _int double--> _double

包装数据类型 Double 可以直接使用double

String 的别名是 string

map、list 也是如此

如果返回值类型是对象,也需要写出全限定符

<select id="queryByNameAndSalary" resultType="com.ztone.pojo.Employee">
    select emp_id empId, emp_name empName, emp_salary empSalary from t_emp
        where emp_name = #{arg0} and emp_salary = #{arg1}
</select>

mybaits并没有给他们创建别名,这时候可以在 mybatis-config.xml 中自己创建别名,使用的标签是typeAlias

<typeAliases>
    <typeAlias type="com.ztone.pojo.Employee" alias="employee"/>
</typeAliases>

这样可以指定某个类的别名,在select 标签中resultType就可以直接使用这个别名

如果不想每个类都去指定,可以用包的方式指定

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

这样这个包下的所有类的别名就是类的首字母小写,在这个前提下,可以用 @Alias("xxxxx") 指定某个类特殊的别名

在查询时,数据库中列名是下划线格式,而实体类中是驼峰式命名,如果手动起别名就无法映射。但手动起别名还是有些费劲。

可以在 mybatis-config.xml 中开启驼峰自动映射,就不用起别名,直接用*代替,或用驼峰式命名即可。

在settings标签中

<settings>
    <setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>

mapUnderscoreToCamelCase属性值默认是false,设置为true 开启

如果返回的数据不是定义的实体类中有的属性,那么可以用 map 去接值。也就是 resultType 的值是 map

用map接值,列名是map的key,结果是map的值

如果返回值是list,那么resultType就是list集合中的泛型。

原因是mybatis的底层用的是 ibatis,ibatis的查询方法有两个,selectOne和 selectList。

selectOne 调用的也是 selectList,所以在底层就是返回了 集合,所以直接指定泛型即可。

 

5.主键回显和自动提交事务

当执行DML(插入、更新、删除)操作时,一定要提交事务,数据库中的数据才能发生变化,在执行 openSession 方法是自动开启事务,但是在完成操作后,还需要调用 sqlSession的 commit方法提交事务。

另一种方式是自动提交事务,就是在调用 openSession时传入 true,表示自动提交事务,就不用自己手动调用commit方法了

SqlSession sqlSession = sqlSessionFactory.openSession(true);

 

主键回显就是,在执行完插入语句后,主键如果是自动增长的,那么该如何获取这个主键的值?

在insert 标签中 加入三个属性

  • useGenerateKeys 把值设置为true,就表示需要接收自增长主键的值

  • keyColumn 数据库中对应的主键

  • keyProperty 把主键赋值给哪个属性

<insert id="insertEmpMap" useGeneratedKeys="true" keyColumn="emp_id" keyProperty="empId">
    insert into t_emp(emp_name, emp_salary) values(#{name}, #{salary});
</insert>

 

如果主键不是自增长的,而是自己传入的值,该如何主键回显呢?

如果使用 UUID作为 主键,手动传入方式如下:

public void test_01() throws IOException {
    InputStream in = Resources.getResourceAsStream("mybatis-config.xml");

    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);

    SqlSession sqlSession = sqlSessionFactory.openSession(true);

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

    Teacher teacher = new Teacher();
    teacher.settId(UUID.randomUUID().toString().replace("-",""));
    teacher.settName("lalala");

    int i = mapper.insertTeacher(teacher);

    sqlSession.close();
}

 

如果交给mybatis去维护,就不需要自己手动创建这个UUID,可以在insert标签里面使用 selectKey去查询,他有三个属性

  • order 有两个值 before和 after,分别表示在 插入语句之前执行还是之后执行

  • resultType 返回值的类型,也就是selectKey标签中语句返回值的类型

  • keyProperty 查询结果赋值给哪个属性(实体类的属性)

<insert id="insertTeacher">

    <selectKey order="BEFORE" resultType="string" keyProperty="tId">
        select UUID();
    </selectKey>
    insert into teacher(t_id, t_name) values(#{tId},#{tName})
</insert>

 

6.resultMap

当数据库列和实体类的属性不一致时,可以使用开启 驼峰命名自动映射,也可以手动映射,用到的标签就是resultMap

<resultMap id="tMap" type="teacher">
    <id column="t_id" property="tId"/>
    <result column="t_name" property="tName"/>
</resultMap>
<select id="queryByid" resultMap="tMap">
    select * from teacher where t_id = #{id}
</select>

在select标签中用resultMap 指定自定义映射,值就是resultMap的id

resultMap标签的type属性是返回值的类型

里面的id标签表示数据库主键的映射,result表示其他列的映射。

posted @ 2024-08-13 17:50  GrowthRoad  阅读(13)  评论(0编辑  收藏  举报