MyBatis基础使用

MyBatis首页icon-default.png?t=N7T8https://mybatis.net.cn/

MyBatis细节注意,让你更加熟悉MyBatisicon-default.png?t=N7T8https://blog.csdn.net/m0_61160520/article/details/137173558?spm=1001.2014.3001.5501

1.项目目录

 2.数据库

CREATE DATABASE `mybatis-example`;

USE `mybatis-example`;

CREATE TABLE `t_emp`(
  emp_id INT AUTO_INCREMENT,
  emp_name CHAR(100),
  emp_salary DOUBLE(10,5),
  PRIMARY KEY(emp_id)
);

INSERT INTO `t_emp`(emp_name,emp_salary) VALUES("lamu",200.33);
INSERT INTO `t_emp`(emp_name,emp_salary) VALUES("leimu",666.66);
INSERT INTO `t_emp`(emp_name,emp_salary) VALUES("486",777.77);

3.依赖导入pom.xml

<dependencies>
  <!-- mybatis依赖 -->
  <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis</artifactId>
      <version>3.5.11</version>
  </dependency>

  <!-- MySQL驱动 mybatis底层依赖jdbc驱动实现,不需要导入连接池,mybatis自带! -->
  <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>8.0.25</version>
  </dependency>

  <!--junit5测试-->
  <dependency>
      <groupId>org.junit.jupiter</groupId>
      <artifactId>junit-jupiter-api</artifactId>
      <version>5.3.1</version>
  </dependency>

  <dependency>
      <groupId>org.projectlombok</groupId>
      <artifactId>lombok</artifactId>
      <version>1.18.28</version>
      <scope>provided</scope>
  </dependency>
</dependencies>

 4.实体类

@Data
public class Employee {

    private Integer empId;
    private String empName;
    private Double empSalary;
    
    @Override
    public String toString() {
        return "Employee{" +
                "empId=" + empId +
                ", empName='" + empName + '\'' +
                ", empSalary=" + empSalary +
                '}';
    }
}

5.定义mapper接口

public interface EmployeeMapper {
    Employee queryById(Integer id);
    
    //int返回值用于接受受影响的行数
    int insertEmployee(Employee employee);

    //根据工资查询员工信息
    List<Employee> queryBySalary(Double salary);

    //根据员工姓名和工资查询员工信息
    List<Employee> queryByNameAndSalary(@Param("param1") String name, @Param("param2") Double salary);

    //插入员工数据,传入的是一个map(name=员工的名字,salary=员工的薪水)
    //mapper接口中不允许重载!!! 方法名重复了  id名重复了!
    int insertEmpMap(Map data);

    //员工插入
    int insertEmp(Employee employee);
}

6.准备MyBatis配置文件

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    
    <settings>
        <!-- 开启了 mybatis的日志输出,选择使用system进行控制台输出-->
        <setting name="logImpl" value="STDOUT_LOGGING"/>

        <!--开启驼峰式自动映射 数据库 a_column->java aColumn -->
        <setting name="mapUnderscoreToCamelCase" value="true"/>
    </settings>
    <!-- 定义自己类的别名 -->
    <typeAliases>
        <!-- 单独定义 -->
        <!--        <typeAlias type="com.example.pojo.Employee" alias="hahaha" />-->
        <!-- 批量将包下的类给与别名,别名就是类的首字母小写! -->
        <package name="com.example.pojo"/>
    </typeAliases>
    <!-- environments表示配置Mybatis的开发环境,可以配置多个环境,在众多具体环境中,使用default属性指定实际运行时使用的环境。default属性的取值是environment标签的id属性的值。 -->
    <environments default="development">
        <!-- environment表示配置Mybatis的一个具体的环境 -->
        <environment id="development">
            <!-- Mybatis的内置的事务管理器
                 MANAGED  不会自动开启事务!  | JDBC 自动开启事务  , 需要自己提交事务!
            -->
            <transactionManager type="JDBC"/>
            <!-- 配置数据源
                 type=POOLED  mybatis帮助我们维护一个链接池 | UNPOOLED  每次都新建或者释放链接
            -->
            <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="root"/>
                <property name="password" value="123456"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <!-- Mapper注册:指定Mybatis映射文件的具体位置 -->
        <!-- mapper标签:配置一个具体的Mapper映射文件 -->
        <!-- resource属性:指定Mapper映射文件的实际存储位置,这里需要使用一个以类路径根目录为基准的相对路径 -->
        <!--      对Maven工程的目录结构来说,resources目录下的内容会直接放入类路径,所以这里我们可以以resources目录为基准 -->
        <mapper resource="mappers/EmployeeMapper.xml"/>
    </mappers>

</configuration>

7.定义mapper xml

- 方法名和SQL的id一致
- 方法返回值和resultType一致
- 方法的参数和SQL的参数一致

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "https://mybatis.org/dtd/mybatis-3-mapper.dtd">

<!--  namespace =  mapper对应接口的全限定符 -->
<mapper namespace="com.example.mapper.EmployeeMapper">
    <select id="queryById" resultType="com.example.pojo.Employee">
        select emp_id empId , emp_name empName , emp_salary empSalary
        from t_emp where emp_id = ${id}
    </select>
    <insert id="insertEmployee">
        insert into t_emp(emp_name,emp_salary) values(#{empName},#{empSalary})
    </insert>

    <!--zai配置中typeAliases标签声明批量将包下的类给与别名,别名就是类的首字母小写-->
    <select id="queryBySalary" resultType="Employee">
        select emp_id empId , emp_name empName , emp_salary empSalary
        from t_emp where emp_salary = #{ salary }
    </select>

    <!--
        场景3: 传入多个简单类型数据如何取值 key!
                可以不可以随便写? 不可以!
                按照形参名称获取? 也不可以!
                方案1: 注解指定  @Param注解  指定多个简单参数的key   key = @Param("value值")  [推荐]
                方案2: mybatis默认机制
                        argo arg1 .... 形参左到右依次对应 argo arg1..
                        (name,salary) name-> key = arg0  salary -> key = arg1
                        param1 param2 ....
                        (name,salary) name-> key = param1  salary -> key = param2
    -->
    <select id="queryByNameAndSalary" resultType="Employee">
        select emp_id empId , emp_name empName , emp_salary empSalary
        from t_emp where emp_name = #{param1} and emp_salary = #{param2}
    </select>
<!--    <select id="queryByNameAndSalary" resultType="com.example.pojo.Employee">-->
<!--        select emp_id empId , emp_name empName , emp_salary empSalary-->
<!--        from t_emp where emp_name = #{arg0} and emp_salary = #{arg1}-->
<!--    </select>-->

    <!-- 场景4: 传入map 如何指定key的值
                 key = map的key即可!
     -->
    <insert id="insertEmpMap">
        insert into t_emp (emp_name , emp_salary )  values (#{name},#{salary});
    </insert>


    <!--输出:
       场景1: 返回单个简单类型如何指定  resultType的写法! 返回值的数据类型!!
               resultType语法:
                   1.类的全限定符号
                   2.别名简称
                      mybatis给我们提供了72种默认的别名!
                      这些都是我们常用的Java数据类型!  [java的常用数据类型]
                             基本数据类型 int  double  -> _int _double
                             包装数据类型 Integer Double  -> int integer double
                             集合容器类型 Map List  HashMap -> 小写即可 map list hashmap

                扩展:如果没有没有提供的需要自己定义或者写类的全限定符号
                   给自己声明的类如何定义别名:
                   mybatis-config.xml
                     给类单独定义别名!!!
                      <typeAliases>
                          <typeAlias type="com.example.pojo.Employee" alias="hahaha" />
                      </typeAliases>
                      批量设置:
                       <typeAliases>
                           批量将包下的类给与别名,别名就是类的首字母小写!
                           <package name="com.example.pojo"/>
                       </typeAliases>
                       扩展,如果不想使用批量的别名,可以使用注解给与名字!
                       @Alias("hahaha")
    -->

    <select id="queryNameById" resultType="string">
        select emp_name from t_emp where emp_id = #{id}
    </select>

    <select id="querySalaryById" resultType="_double">
        select emp_salary from t_emp where emp_id = #{id}
    </select>

    <!--
       场景2: 返回单个自定义类类型
        //返回单个自定义实体类型
        Employee queryById(Integer id);
        resultType : 返回值类型即可

        默认要求:
           查询,返回单个实体类型,要求列名和属性名要一致!
           这样才可以进行实体类的属性映射!

        但是可以进行设置,设置支持驼峰式自动映射!
           emp_id  -> empId ===  empId
        mybatis-config.xml
        <setting name="mapUnderscoreToCamelCase" value="true"/>
    -->

    <select id="queryById1" resultType="employee" >
        select  *
        from t_emp where emp_id = ${id}
    </select>


    <!-- 场景3: 返回map
                 当没有实体类可以使用接值的时候!
                 我们可以使用map接受数据!
                 key - > 查询的列
                 value -> 查询的值
    -->
    <select id="selectEmpNameAndMaxSalary" resultType="map">
        SELECT
        emp_name 员工姓名,
        emp_salary 员工工资,
        (SELECT AVG(emp_salary) FROM t_emp) 部门平均工资
        FROM t_emp WHERE emp_salary=(
        SELECT MAX(emp_salary) FROM t_emp
        )
    </select>

    <!--
       场景4: 返回的是集合类型如何指定
        //查询工资高于传入值的员工姓名们 200
        List<String> queryNamesBySalary(Double salary);

        //查询全部员工信息
        List<Employee> queryAll();
        Employee queryById();

        切记: 返回值是集合。resultType不需要指定集合类型,只需要指定泛型即可!!
        为什么?
            mybatis -> ibatis -> selectOne 单个  | selectList 集合 ->  selectOne中 调用 [ selectList ]
    -->
    <select id="queryNamesBySalary" resultType="string">
        select emp_name from t_emp where emp_salary > #{ salary }
    </select>

    <select id="queryAll" resultType="employee">
        select * from t_emp
    </select>


    <!--
       场景5: 主键回显 获取插入数据的主键
          1. 自增长主键回显 mysql  auto_increment
            //员工插入
            int insertEmp(Employee employee);
            useGeneratedKeys="true" 我们想要数据库自动增强的主键值
            keyColumn="emp_id" 主键列的值!!!
            keyProperty="empId" 接收主键列值的属性!!!
    -->
    <insert id="insertEmp" useGeneratedKeys="true" keyColumn="emp_id" keyProperty="empId">
        insert into t_emp (emp_name,emp_salary)
        value(#{empName},#{empSalary});
    </insert>

    <!--
       期望,非自增长的主键,交给mybatis帮助我们维护!
    -->
    <insert id="insertxxx">
        <!-- 插入之前,先指定一段sql语句,生成一个主键值!
             order="before|after" sql语句是在插入语句之前还是之后执行!
             resultType = 返回值类型
             keyProperty = 查询结果给哪个属性赋值

              //自己维护主键
                String id = UUID.randomUUID().toString().replaceAll("-", "")
                teacher.settId(id);
        -->
        <selectKey order="BEFORE" resultType="string" keyProperty="tId">
            SELECT  REPLACE(UUID(),'-','');
        </selectKey>

        INSERT INTO teacher (t_id,t_name)
        VALUE(#{tId},#{tName});
    </insert>

    <!--
        Teacher queryById(String tId);
        列名和属性不一致如何解决:
           方案1: 别名  select t_id tId , t_name tName from teacher where t_id = #{tId}
           方案2: 开启驼峰式映射  <setting name="mapUnderscoreToCamelCase" value="true"/>
                  t_id  tId 自动映射
           方案3: resultMap自定义映射  (resultType和resultMap二选一)
                 resultType按照规则自动映射  按照是否开启驼峰式映射,自己映射属性和列名! 只能映射一层结构!
                 深层次的对象结构无法映射,多表查询的时候结果无法映射!

                 Order                  -   数据库
                    orderId                        order_id
                    orderName                      order_name
                    OrderItem orderItem
                                 item_id           item_id

                resultMap标签,自定义映射关系,可以深层次可以单层次!!!
     -->

    <!-- 声明resultMap标签,自己定义映射规则
               id标识 -> select resultMap="标识"
               type   -> 具体的返回值类型 全限定符和别名 | 集合只写泛型即可
                   <id 主键映射关系
                   <result 普通列的映射关系
    -->
    <resultMap id="tMap" type="employee">
        <id column="emp_id" property="empId" />
        <result  column="emp_name" property="empName"/>
    </resultMap>

    <select id="queryById2"  resultMap="tMap">
        select * from teacher where t_id = #{tId}
    <!--select t_id tId , t_name tName from teacher where t_id = #{tId}-->
    </select>
</mapper>

8.测试

public class MyBatisTest {
    @Test
    public void test() throws IOException {
        //读取外部配置文件
        InputStream ips = Resources.getResourceAsStream("mybatis-config.xml");
        SqlSessionFactory sf = new SqlSessionFactoryBuilder().build(ips);
        //openSession自动开启事务,不会自动提交 !
        //openSession(true)自动开启事务,自动提交事务!  不需要sqlSession.commit();
        SqlSession session = sf.openSession(true);
        EmployeeMapper mapper = session.getMapper(EmployeeMapper.class);

        Employee employee = new Employee();
        employee.setEmpSalary(8888.0);
        employee.setEmpName("艾米莉亚");

        System.out.println(employee.getEmpId());

        System.out.println("----------------------");
        int rows =  mapper.insertEmp(employee);
        System.out.println("rows = " + rows);
        System.out.println(employee.getEmpId());
        session.close();
    }
}

  • 8
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值