Mybatis基础知识学习笔记

发布时间:2024年01月19日

Universe Infinity inc.

看似缓慢,实则迅捷。在处理事务时,我总在寻找最佳路径。在学习知识时,我曾试图通过捷径提高效率。但后来我发现,这些方法虽然看似快速,但在实际应用中效率却很低。相反,遵循最基本的方法,脚踏实地地提升,才能真正提高代码能力。因为代码能力最终还是要靠不断地编写和实践中提升的。

一、Mybaits 基本使用

Mybatis开发几步内容

  • 创建对应的bean
  • 创建mapper接口类
  • 创建mapper接口类对应的xml
  • 将接口类对应的xml注册到mybatis的配置文件中
二、Mybaits的输入

注意${}和#{}的区别

1、建表
drop table `t_emp`;
CREATE TABLE `t_emp` (
    emp_id INT AUTO_INCREMENT,
    emp_name CHAR(100),
    emp_salary DOUBLE(10 , 5 ),
    PRIMARY KEY (emp_id)
)  ENGINE=INNODB DEFAULT CHARSET=UTF8;
INSERT INTO `t_emp`(emp_name,emp_salary) VALUES("tom",200.33);
INSERT INTO `t_emp`(emp_name,emp_salary) VALUES("jerry",666.66);
INSERT INTO `t_emp`(emp_name,emp_salary) VALUES("andy",777.77);
2、实体类
public class Employee {
    private Integer empId;
    private String empName;
    private Double empSalary;
}
3、Mapper接口
public interface EmployeeMapper {
    //1、单个传参形式
    Employee selectByEmpId(Integer empId);
    Employee selectByEmpName(String empName);
    //2、多个传参形式。自定义参数名时,要用@Param和mapper.xml中的参数匹配
    int updateEmployee(@Param("empName") String empName, @Param("empSalary") Double empSalaryByMe);
    //int updateEmployee(String empName, Double empSalaryByMe);
    //3、实体传参时
    int insertByEmployee(Employee employee);
    //4、map类型传参
    int updateEmployeeByMap(Map<String, Object> paramMap);
    int insertEmployeeByMap(Map<String,Object> map);
}
4、Mapper接口对应的XML文件配置
<!-- namespace等于mapper接口类的全限定名,这样实现对应 -->
<mapper namespace="com.tang.springmybatis1.mapper.EmployeeMapper">
    <!-- 查询使用 select标签
            id = 方法名
            resultType = 返回值类型
            标签内编写SQL语句
     -->
    <!-- 1、单个简单数据类型传参-->
    <select id="selectByEmpId" resultType="com.tang.springmybatis1.pojo.Employee">
        <!-- #{empId}代表动态传入的参数,并且进行赋值!后面详细讲解 -->
        select emp_id empId,emp_name empName, emp_salary empSalary from
        t_emp where emp_id = ${empId} <!--${}这种形式非必要不用,会显式的出现在日志中,一般用于动态表名-->
    </select>
    <select id="selectByEmpName" resultType="com.tang.springmybatis1.pojo.Employee">
        <!-- #{empId}代表动态传入的参数,并且进行赋值!后面详细讲解 -->
        select emp_id empId,emp_name empName, emp_salary empSalary from
        t_emp where emp_name = #{empName} <!--#{}这种形式在日志中的显式是?,保护数据安全-->
    </select>
    
    <!--2、多个简单类型传参-->
    <update id="updateEmployee">
        update t_emp set emp_salary=#{empSalary} where emp_name=#{empName}
    </update>

    <!--3、实体类类型传参
        传入的Employee类
        自动提取其成员变量的getXxx方法 注意#{}中的明明要和成员变量相同
    -->
    <insert id="insertByEmployee">     <!-- 插入数据使用insert标签-->
        insert into t_emp(emp_name,emp_salary) values (#{empName},#{empSalary})
    </insert>

    <!--4、map类型传参。有很多零散的参数需要传递,但是没有对应的实体类类型可以使用.#{}中写Map中的key-->
    <update id="updateEmployeeByMap">
        update t_emp set emp_salary=#{empSalary} where emp_id=#{empId}
    </update>
    <insert id="insertEmployeeByMap">
        insert into t_emp(emp_name,emp_salary) values (#{empName},#{empSalary})
    </insert>
</mapper>
5、Test
public class EmployeeTest2 {
    private SqlSession session;
    //junit5会在每一个@Test方法前执行@BeforeEach方法
    @BeforeEach
    public void init() throws IOException {
        session = new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("mybatis-config.xml")).openSession();
    }
    //1、简单类型传参
    @Test
    public void testSelectByEmpId(){
        EmployeeMapper mapper = session.getMapper(EmployeeMapper.class);
        Employee employee = mapper.selectByEmpId(1);
        System.out.println(employee);
    }
    @Test
    public void testSelectByEmpName(){
        EmployeeMapper mapper = session.getMapper(EmployeeMapper.class);
        Employee employee = mapper.selectByEmpName("tang");
        System.out.println(employee);
    }
    //2、多个简单类型传参
    @Test
    public void testUpdateEmployee(){
        EmployeeMapper mapper = session.getMapper(EmployeeMapper.class);
        mapper.updateEmployee("tang",9999.0);
        System.out.println(mapper.selectByEmpName("tang"));
    }

    //3、实体类型传参
    @Test
    public void testInsertByEmployee(){
        EmployeeMapper mapper = session.getMapper(EmployeeMapper.class);
        Employee employee = new Employee();
        employee.setEmpName("wang");
        employee.setEmpSalary(123.0);
        int i = mapper.insertByEmployee(employee);
        System.out.println(i);
        System.out.println(mapper.selectByEmpName("wang"));
    }
    //4、mapper类型传参
    @Test
    public void testUpdateEmpNameByMap() {
        EmployeeMapper mapper = session.getMapper(EmployeeMapper.class);
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("empSalary", 999.99);
        paramMap.put("empId", 5);
        int result = mapper.updateEmployeeByMap(paramMap);
        System.out.println(result);
    }
    @Test
    public void testInsertEmployeeByMap(){
        EmployeeMapper mapper = session.getMapper(EmployeeMapper.class);
        HashMap<String, Object> map = new HashMap<>();
        map.put("empName","chen");
        map.put("empSalary","98734.00");
        int i = mapper.insertEmployeeByMap(map);
        System.out.println(i);
    }
    //junit5会在每一个@Test方法后执行@AfterEach方法
    @AfterEach
    public void clear() {
        session.commit();
        session.close();
    }
6、mybatis-config.xml的配置
<configuration>
    <settings>
        <!-- SLF4J 选择slf4j输出! -->
        <setting name="logImpl" value="SLF4J"/>
    </settings>
    <!-- environments表示配置Mybatis的开发环境,可以配置多个环境,在众多具体环境中,使用default属性指定实际运行时使用的环境。default属性的取值是environment标签的id属性的值。 -->
    <environments default="development">
        <!-- environment表示配置Mybatis的一个具体的环境 -->
        <environment id="development">
            <!-- Mybatis的内置的事务管理器 -->
            <transactionManager type="JDBC"/>
            <!-- 配置数据源 -->
            <dataSource type="POOLED">
                <!-- 建立数据库连接的具体信息 -->
                <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/mybatis-example"/>
                <property name="username" value="tang"/>
                <property name="password" value="pass"/>
            </dataSource>
        </environment>
    </environments>

    <mappers>
        <!-- Mapper注册:指定Mybatis映射文件的具体位置 -->
        <!-- mapper标签:配置一个具体的Mapper映射文件 -->
        <!-- resource属性:指定Mapper映射文件的实际存储位置,这里需要使用一个以类路径根目录为基准的相对路径 -->
        <!--Maven工程的目录结构来说,resources目录下的内容会直接放入类路径,所以这里我们可以以resources目录为基准 -->
        <mapper resource="mapper/EmployeeMapper.xml"/>
        <mapper resource="mapper/CategoriesMapper.xml"/>
    </mappers>

</configuration>
7、SLF4J配置

其中使用了SLF4J作为输入,其配置如下。这里配置了debug的输出日志,用于日常测试

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn" name="MyApp" packages="">
    <Appenders>
        <Console name="STDOUT" target="SYSTEM_OUT">
            <PatternLayout pattern="%m%n"/>
        </Console>
    </Appenders>
    <Loggers>
        <Root level="debug">
            <AppenderRef ref="STDOUT"/>
        </Root>
    </Loggers>
</Configuration>
三、Mybatis的输出
1、建表
drop table `t_categories`;
CREATE TABLE `t_categories` (
    category_id INT AUTO_INCREMENT,
    category_name CHAR(10),
    category_desc CHAR(100),
    PRIMARY KEY (category_id)
)  ENGINE=INNODB DEFAULT CHARSET=UTF8;
show create table t_categories;
INSERT INTO `t_categories` (category_name, category_desc)
VALUES
    ('手机', '各种品牌和型号的手机'),
    ('笔记本电脑', '各种品牌和型号的笔记本电脑'),
    ('图书', '各种类别和作者的图书'),
    ('电视', '各种尺寸和品牌的电视'),
    ('吸尘器', '各种型号和功率的吸尘器');
2、实体类
public class Categories {
    private int categoryId;
    private String categoryName;
    private String categoryDesc;
}
3、Mapper接口
public interface CategoriesMapper {
    //1、返回为实体类形式
    Categories selectCategoriesByName(String categoryName);
    //2、返回Map类型,返回多个参数且没有实体类对应
    @MapKey("categoryId")
    Map<String,Object> selectCategoriesById(int categoryId);
    //使用@MapKey注解后可以查询多个实体对象,其输出是一个列表形式
    @MapKey("categoryId")
    Map<String,Object> selectCategoriesAllByMap();
    //3、返回List类型。查询结果返回多个实体类对象,希望把多个实体类对象放在List集合中返回
    List<Categories> selectCategoriesAllByList();
    //4、返回主键值-自增型主键
    int insertCategories(Categories categories);
    int deleteCategoriesByName(String categoryName);
}
4、Mapper接口对应的xml配置
<!--namespace和具体的mapper接口类关联,使用全限定符-->
<mapper namespace="com.tang.springmybatis1.mapper.CategoriesMapper">
    <!--1、返回为实体类形式,使用resultType指定对应的实体类-->
    <select id="selectCategoriesByName" resultType="com.tang.springmybatis1.pojo.Categories">
        select category_id categoryId,category_name categoryName,category_desc categoryDesc
        from t_categories where category_name=#{categoryName};
    </select>
        
    <!--2、查询结果返回多个参数没有实体类对应时-->
    <select id="selectCategoriesById" resultType="map">
        select category_id categoryId,category_name categoryName,category_desc categoryDesc
        from t_categories where category_id=#{categoryId};
    </select>
    <select id="selectCategoriesAllByMap" resultType="map">
        select category_id categoryId,category_name categoryName,category_desc categoryDesc
        from t_categories;
    </select>
        
    <!--3、查询结果返回List类型-->
    <select id="selectCategoriesAllByList" resultType="com.tang.springmybatis1.pojo.Categories">
        select category_id categoryId,category_name categoryName,category_desc categoryDesc
        from t_categories;
    </select>
        
    <!--4、返回主键值-->
    <!-- useGeneratedKeys属性字面意思就是“使用生成的主键” -->
    <!-- keyProperty属性可以指定主键在实体类对象中对应的属性名,Mybatis会将拿到的主键值存入这个属性 -->
    <insert id="insertCategories" useGeneratedKeys="true" keyProperty="categoryId">
        insert into t_categories(category_name,category_desc) values (#{categoryName},#{categoryDesc});
    </insert>
    <delete id="deleteCategoriesByName">
        delete from t_categories where category_name=#{categoryName};
    </delete>
</mapper>
5、Test
public class CategoriesTest3 {
    private SqlSession session;
    //junit5会在每一个@Test方法前执行@BeforeEach方法
    @BeforeEach
    public void init() throws IOException {
        session = new SqlSessionFactoryBuilder()
                .build(
                        Resources.getResourceAsStream("mybatis-config.xml"))
                .openSession();
    }
    //1、返回单个实体类
    @Test
    public void testSelectCategoriesByName() {
        CategoriesMapper mapper = session.getMapper(CategoriesMapper.class);
        Categories categories = mapper.selectCategoriesByName("手机");
        System.out.println(categories);
    }
    //2、返回Map类型
    @Test
    public void testSelectCategoriesById(){
        CategoriesMapper mapper =session.getMapper(CategoriesMapper.class);
        Map<String, Object> stringObjectMap = mapper.selectCategoriesById(1);
        System.out.println(stringObjectMap);
    }
    @Test
    public void testSelectCategoriesAllByMap(){
        CategoriesMapper mapper = session.getMapper(CategoriesMapper.class);
        Map<String, Object> stringObjectMap = mapper.selectCategoriesAllByMap();
        System.out.println(stringObjectMap);
    }
    //3、返回List类型
    @Test
    public void testSelectCategoriesAllByList(){
        CategoriesMapper mapper = session.getMapper(CategoriesMapper.class);
        List<Categories> categories = mapper.selectCategoriesAllByList();
        System.out.println(categories);
        for (Categories category : categories) {
            System.out.println(category);
        }
    }
    //4、返回主键值
    @Test
    public void testInsertCategories() {
        CategoriesMapper mapper = session.getMapper(CategoriesMapper.class);
        mapper.deleteCategoriesByName("公司");
        Categories categories = new Categories();
        categories.setCategoryName("公司");
        categories.setCategoryDesc("公司也是能卖的");
        int i = mapper.insertCategories(categories);
        System.out.println(i);
        System.out.println("返回的主键:" + categories.getCategoryId());
    }
    //junit5会在每一个@Test方法后执行@@AfterEach方法
    @AfterEach
    public void clear() {
        session.commit();
        session.close();
    }
}
6、Mybatis-config.xml注册
<mappers>
    <!-- Mapper注册:指定Mybatis映射文件的具体位置 -->
    <!-- mapper标签:配置一个具体的Mapper映射文件 -->
    <!-- resource属性:指定Mapper映射文件的实际存储位置,这里需要使用一个以类路径根目录为基准的相对路径 -->
    <!--Maven工程的目录结构来说,resources目录下的内容会直接放入类路径,所以这里我们可以以resources目录为基准 -->
    <mapper resource="mapper/CategoriesMapper.xml"/>
</mappers>
文章来源:https://blog.csdn.net/qq_36722262/article/details/135700539
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。