Mybatis

MyBatis(下篇)


1.多表映射

前言:MyBatis 思想是:数据库不可能永远是你所想或所需的那个样子。 我们希望每个数据库都具备良好的第三范式或 BCNF 范式,可惜它们并不都是那样。 如果能有一种数据库映射模式,完美适配所有的应用程序查询需求,那就太好了,而 ResultMap 就是 MyBatis 就是完美答案。

对一实体类设计思路:在对一关系下,类中只要包含单个对方对象类型属性即可

对多实体类设计思路:在对多关系下,类中只要包含对方类型集合属性即可

只有真实发生多表查询时,才需要设计和修改实体类,否则不提前设计和修改实体类!

无论多少张表联查,实体类设计都是两两考虑!

在查询映射的时候,只需要关注本次查询相关的属性!例如:查询订单和对应的客户,就不要关注客户中的订单集合!

1.1对一查询

在resultMap中给对象属性赋值时,使用association标签进行赋值

  • property:对象属性的属性名

  • column:数据表中的列名

  • javaType:对象属性的类型的全限定符或全限定符的别名

  • association标签:对一关系映射标签

  • id标签:声明主键列的映射关系

  • result标签:声明非主键列的映射关系

========================数据库sql语句准备===================================
CREATE TABLE `t_customer` (`customer_id` INT NOT NULL AUTO_INCREMENT, `customer_name` CHAR(100), PRIMARY KEY (`customer_id`) );
​
CREATE TABLE `t_order` ( `order_id` INT NOT NULL AUTO_INCREMENT, `order_name` CHAR(100), `customer_id` INT, PRIMARY KEY (`order_id`) ); 
​
INSERT INTO `t_customer` (`customer_name`) VALUES ('c01');
​
INSERT INTO `t_order` (`order_name`, `customer_id`) VALUES ('o1', '1');
INSERT INTO `t_order` (`order_name`, `customer_id`) VALUES ('o2', '1');
INSERT INTO `t_order` (`order_name`, `customer_id`) VALUES ('o3', '1'); 
 
=======================对应多表查询实体类设计================================
@Data
public class Customer {
​
  private Integer customerId;
  private String customerName;
  private List<Order> orderList;// 体现的是对多的关系
  
}  
​
@Data
public class Order {
  private Integer orderId;
  private String orderName;
  private Customer customer;// 体现的是对一的关系
  
}  
 
=======================Mapper接口方法的声明=================================
public interface OrderMapper {
  Order selectOrderWithCustomer(Integer orderId);
}

=====================Mapper.xml文件编写====================================
<?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>">
<mapper namespace="com.ergou.mapper.OrderMapper">
<!-- 创建resultMap实现“对一”关联关系映射 -->
<!-- id属性:通常设置为这个resultMap所服务的那条SQL语句的id加上“ResultMap” -->
<!-- type属性:要设置为这个resultMap所服务的那条SQL语句最终要返回的类型 -->
<resultMap id="selectOrderWithCustomerResultMap" type="order">
​
  <!-- 先设置Order自身属性和字段的对应关系 -->
  <id column="order_id" property="orderId"/>
​
  <result column="order_name" property="orderName"/>
​
  <!-- 使用association标签配置“对一”关联关系 -->
  <!-- property属性:在Order类中对一的一端进行引用时使用的属性名 -->
  <!-- javaType属性:一的一端类的全类名 -->
  <association property="customer" javaType="customer">
​
    <!-- 配置Customer类的属性和字段名之间的对应关系 -->
    <id column="customer_id" property="customerId"/>
    <result column="customer_name" property="customerName"/>
​
  </association>
​
</resultMap>
​
<!-- Order selectOrderWithCustomer(Integer orderId); -->
<select id="selectOrderWithCustomer" resultMap="selectOrderWithCustomerResultMap">
​
  SELECT order_id,order_name,c.customer_id,customer_name
  FROM t_order o
  LEFT JOIN t_customer c
  ON o.customer_id=c.customer_id
  WHERE o.order_id=#{orderId}
​
</select>
</mapper>

1.2对多映射

1.一对多使用collection子标签进行关联多方Order

<collection property="指定 Java 对象中集合属性的名称" javaType="指定集合本身的类型(如 `List`, `Set` 等)" ofType="指定集合中元素的类型" autoMapping="true"> </collection> 2.属性:

1)property="orders" 这里的orders表示User类的成员变量orders

2)javaType="List" 表示User类的成员变量orders存储的Order对象使用的类型,这里是List 一般不书写,通常,MyBatis 能够根据 ofType 自动推断出合适的 javaType

  1. ofType="Order" 表示List集合中存储数据的类型 Order 3.一定要记住这里给user表的id起别名是uid,order表的id起别名是oid.在resultMap标签的id子标签中的column属性值书写对应的uid和oid

<!-- 配置resultMap实现从Customer到OrderList的“对多”关联关系 -->
<resultMap id="selectCustomerWithOrderListResultMap"
​
  type="customer">
​
  <!-- 映射Customer本身的属性 -->
  <id column="customer_id" property="customerId"/>
​
  <result column="customer_name" property="customerName"/>
​
  <!-- collection标签:映射“对多”的关联关系 -->
  <!-- property属性:在Customer类中,关联“多”的一端的属性名 -->
  <!-- ofType属性:集合属性中元素的类型 -->
  <collection property="orderList" ofType="order">
​
    <!-- 映射Order的属性 -->
    <id column="order_id" property="orderId"/>
​
    <result column="order_name" property="orderName"/>
​
  </collection>
​
</resultMap>
​
<!-- Customer selectCustomerWithOrderList(Integer customerId); -->
<select id="selectCustomerWithOrderList" resultMap="selectCustomerWithOrderListResultMap">
  SELECT c.customer_id,c.customer_name,o.order_id,o.order_name
  FROM t_customer c
  LEFT JOIN t_order o
  ON c.customer_id=o.customer_id
  WHERE c.customer_id=#{customerId}
</select>

1.3分步查询(了解) 

相关标签声明:

在 association 和 collection 的封装过程中,可以使用 select + column 指定分步查询逻辑

  • select:指定分步查询调用的方法。
  •  column:指定分步查询传递的参数。
    • 传递单个:直接写列名,表示将这列的值作为参数传递给下一个查询
    • 传递多个:column="{prop1=col1,prop2=col2}",下一个查询使用prop1、prop2取值
===========================Mapper接口声明==========================================
@Mapper
public interface StepMapper {

    /**
     * 根据id查询客户信息
     * @param id
     * @return
     */
    Customer selectCustomerByid(Long id);

    /**
     * 根据id查询订单信息
     * @param id
     * @return
     */
    List<Order> selectOrderById(Long id);


    Customer selectCustomerByIdStep(Long id);
}

=========================Mapper.xmlsql语句编写=======================================
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.atguigu.cloud.mybatis.mapper.StepMapper">
    <select id="selectCustomerByid" resultType="com.atguigu.cloud.mybatis.bean.Customer">
        select * from t_customer where id = #{id}
    </select>

    <select id="selectOrderById" resultType="com.atguigu.cloud.mybatis.bean.Order">
        select * from t_order where t_order.customer_id = #{id}
    </select>


    <!--
    分步骤查询,第一步查询客户信息,第二步根据客户id查询订单。理解为自定义返回类型将多步查询封装到一起。
    select标签用来声明被应用的sql查询方法
    column标签用来声明第二次查询所需要的参数,从第一次查询的属性栏中得到。
    -->
    <resultMap id="selectByIdCustomerAndOrder" type="com.atguigu.cloud.mybatis.bean.Customer">
        <id column="customer_id" property="id"/>
        <result column="phone" property="phone"/>
        <result column="customer_name" property="customerName"/>
        <association property="orders"
                        select="com.atguigu.cloud.mybatis.mapper.StepMapper.selectOrderById"
                        column="id">
        </association>
    </resultMap>

    <select id="selectCustomerByIdStep" resultMap="selectByIdCustomerAndOrder">
        select * from t_customer where id = #{id}
    </select>
</mapper>

==============================方法测试启动===========================================
@SpringBootTest
public class StepMapperTest {

    //分布查询测试,我们希望查询出顾客信息的同时,发现顾客购买的商品信息,
    // Mybatis框架可以帮我们自动完成后续查询,并将信息装配到对应的实体类中

    @Autowired
    private StepMapper stepMapper;


    @Test
    public void StepTest(){

        //①查询顾客信息
        Customer customer = stepMapper.selectCustomerByid(1L);
        System.out.println("customer = " + customer);

        //②查询顾客购买的商品信息
        List<Order> order = stepMapper.selectOrderById(customer.getId());
        System.out.println("order = " + order);

        customer.setOrders(order);
        System.out.println("customer = " + customer);
    }

    @Test
    public void Step01Test(){
        //一步到位调用一个方法,该方法内部完成顾客信息和商品信息的查询和装配
        
        Customer customer = stepMapper.selectCustomerByIdStep(1L);
        System.out.println("customer = " + customer);
    }
}

多表映射配置优化

setting属性属性含义可选值默认值
autoMappingBehavior指定 MyBatis 应如何自动映射列到字段或属性。 NONE 表示关闭自动映射;PARTIAL 只会自动映射没有定义嵌套结果映射的字段。 FULL 会自动映射任何复杂的结果集(无论是否嵌套)。NONE, PARTIAL, FULLPARTIAL
关联关系配置项关键词所在配置文件和具体位置
对一①association标签:对一关系映射标签②javaType属性:对象属性的类型③column属性:数据表中的列名④property属性:映射的属性名Mapper配置文件中的resultMap标签内
对多①collection标签:对多关系映射标签②ofType属性:集合中存储的数据类型③column属性:数据表中的列名④property属性:映射的属性名Mapper配置文件的resultMap标签内

有用的mybatis配置设置

①logImpl:开启控制台的日志输出功能,可以看到后台执行的sql语句

②mapUnderscoreToCamelCase:自动开启驼峰式映射(不适合嵌套)

③autoMappingBehavior:自动映射字段和属性(适用多层嵌套)

④typeAliases:自动类型别名转换

<settings>
    <setting name="logImpl" value="STDOUT_LOGGING"/>
    <setting name="mapUnderscoreToCamelCase" value="true"/>
    <setting name="autoMappingBehavior" value="FULL"/>
</settings>
​
​
<typeAliases>
        <package name="com.atguigu.pojo"/>
</typeAliases>
<typeAliases>
        <typeAlias type="com.atguigu.pojo.Employee" alias="huermosi"/>
</typeAliases>

相关配置项 

spring.application.name=mybatis-01helloworld


#数据库信息相关配置
spring.datasource.url=jdbc:mysql://localhost:3306/mybatis-example
spring.datasource.username=root
spring.datasource.password=hh123
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver


#声明Mapper.xml所在包地址,方便底层调用sql语句对数据库操作
mybatis.mapper-locations=classpath:mapper/**.xml
#设置MyBatis日志打印级别
logging.level.com.atguigu.cloud.mybatis.mapper=debug
#开启MyBatis自动驼峰映射规则
mybatis.configuration.map-underscore-to-camel-case=true
#开启延迟加载功能,当某个数据要使用时才进行数据库查询
mybatis.configuration.lazy-loading-enabled=true
mybatis.configuration.aggressive-lazy-loading=false

2.动态语句

前言动态 SQL 是 MyBatis 的强大特性之一。如果你使用过 JDBC 或其它类似的框架,你应该能理解根据不同条件拼接 SQL 语句有多痛苦,例如拼接时要确保不能忘记添加必要的空格,还要注意去掉列表最后一个列名的逗号。利用动态 SQL,可以彻底摆脱这种痛苦。

使用动态 SQL 并非一件易事,但借助可用于任何 SQL 映射语句中的强大的动态 SQL 语言,MyBatis 显著地提升了这一特性的易用性。

if和where标签

①if标签

可以让我们有选择的加入Sql语句的片段。

在if标签的test属性里面,可以访问实体类的属性,不可以访问数据库表的字段

若test标签里面内容为true则添加if标签里面的语句

②where标签

可以帮助我们自动去掉“标签里面多余的and/or”,自动连接where关键字,防止报错

<select id="queryByNameAndSalary" resultType="com.ergou.pojo.Employee">
    SELECT * FROM t_emp
    <where>
    <if test="name != null">
        emp_name = #{name}
    </if>
    <if test="salary != null and salary &gt; 100">
        AND emp_salary = #{salary}
    </if>
    </where>
</select>

set标签

自动去掉多余的逗号,自动连接set关键字

<update id="update">
    UPDATE t_emp 
    <set>
        <if test="empName != null">
            emp_name = #{empName},
        </if>
        <if test="empSalary != null">
            emp_salary = #{empSalary}
        </if>
    </set>
    WHERE emp_id = #{empId}
</update>

trim标签

  • prefix属性:指定要动态添加的前缀

  • suffix属性:指定要动态添加的后缀

  • prefixOverrides属性:指定要动态去掉的前缀,使用“|”分隔有可能的多个值

  • suffixOverrides属性:指定要动态去掉的后缀,使用“|”分隔有可能的多个值

 <select id="querytrim" resultType="employee">
        <trim prefix="where" prefixOverrides="and | or">
            <if test="name!=null">
                emp_name=#{name}
            </if>
​
            <if test="salary!=null and salary &gt; 100">
                and emp_salary=#{salary}
            </if>
        </trim>
    </select>
==========================================================================
    <update id="updatatrim" >
        updata t_emp
​
        <trim prefix="set" suffixOverrides=",">
            <if test="empName!=null">
                emp_name=#{empName},
            </if>
​
            <if test="empSalary!=null">
                emp_salary=#{empSalary}
            </if>
        </trim>
        where emp_id=#{empId}
​
    </update>

choose/when/otherwise标签

  • 从上到下依次执行条件判断

  • 遇到的第一个满足条件的分支会被采纳

  • 被采纳分支后面的分支都将不被考虑

  • 如果所有的when分支都不满足,那么就执行otherwise分支

<!-- List<Employee> selectEmployeeByConditionByChoose(Employee employee) -->
<select id="selectEmployeeByConditionByChoose" resultType="com.atguigu.mybatis.entity.Employee">
    select emp_id,emp_name,emp_salary from t_emp
    where
    <choose>
        <when test="empName != null">emp_name=#{empName}</when>
        <when test="empSalary &lt; 3000">emp_salary &lt; 3000</when>
        <otherwise>1=1</otherwise>
    </choose>
    
</select>

foreach标签

①collection属性:指定要遍历的集合

②item属性:遍历集合的过程中能得到每一个具体对象,在item属性中设置一个名字,将来通过这个名字引用遍历出来的对象

③separator属性:指定当foreach标签的标签体重复拼接字符串时,各个标签体字符串之间的分隔符

④open属性:指定整个循环把字符串拼好后,字符串整体的前面要添加的字符串

⑤close属性:指定整个循环把字符串拼好后,字符串整体的后面要添加的字符串

<select id="querybatch" resultType="employee">
        select * from t_emp
        where emp_id in
        <foreach collection="ids" open="(" separator="," close=")" item="id">
            #{id}
        </foreach>
    </select>
​
​
    <delete id="deletebatch" >
        delete from t_emp
        where emp_id in
        <foreach collection="ids" open="(" separator="," close=")" item="id">
            #{id}
        </foreach>
    </delete>
            
            
    <insert id="insertbatch" >
        insert into t_emp(emp_name,emp_salary)
        values
        <foreach collection="list" separator="," item="employee">
            (#{employee.empName},#{employee.empSalary})
        </foreach>
    </insert>
    
<!-- 如果一个标签涉及到多条执行sql语句,一定要在mybatis的配置中打开多语句执行权限-->            
    <update id="updatebatch" >
      <foreach collection="list" item="emp">
          update t_emp set emp_name=#{emp.empName},emp_salary=#{emp.empSalary}
          where emp_id=#{emp.empId}
      </foreach>
    </update>
在mybatis中开启多语句执行权限
atguigu.dev.url=jdbc:mysql:///mybatis-example?allowMultiQueries=true

sql片段

作用:提取出重复的sql语句,方便以后调用,简化代码量

标签:<sql></sql>

<!-- 使用sql标签抽取重复出现的SQL片段 -->
<sql id="mySelectSql">
    select emp_id,emp_name,emp_age,emp_salary,emp_gender from t_emp
</sql>
​
​
<!-- 使用include标签引用声明的SQL片段 -->
<include refid="mySelectSql"/>

3.高级扩展

3.1批量扫描mapper接口

要求:

1.要求Mapperxml文件和mapper接口的命名必须相同

2.最终打包的位置要一致,都是在指定的包地址下面

①将xml文件放到mapper接口所在的包下

②在resource文件夹下创建与mapper接口相同的文件夹结构

<mappers>
    <package name="com.atguigu.mapper"/>
</mappers>

3.2插件

插件可以在用于语句执行过程中进行拦截,并允许通过自定义处理程序来拦截和修改 SQL 语句、映射语句的结果等。

MyBatis 的插件机制包括以下三个组件:

①Interceptor(拦截器):定义一个拦截方法 intercept,该方法在执行 SQL 语句、执行查询、查询结果的映射时会被调用。

②Invocation(调用):实际上是对被拦截的方法的封装,封装了 Object target、Method method 和 Object[] args 这三个字段。

③InterceptorChain(拦截器链):对所有的拦截器进行管理,包括将所有的 Interceptor 链接成一条链,并在执行 SQL 语句时按顺序调用。

  • MyBatis 底层使用 拦截器机制提供插件功能,方便用户在SQL执行前后进行拦截增强。
  • 拦截器:Interceptor
  • 拦截器可以拦截 四大对象 的执行
    • ParameterHandler:处理SQL的参数对象
    • ResultSetHandler:处理SQL的返回结果集
    • statementHandler:数据库的处理对象,用于执行SQL语句
    • Executor:MyBatis的执行器,用于执行增删改查操作 
分页插件(PageHelper):
          原理
          原业务底层:select * from t_emp;
          拦截器要做的事
          1):统计这个表的总数量
          2):在SQL语句后面自动拼接limit查询条件
          3):跟据传入的pageNum和pageSize计算出数据库查询的起始索引
         
          为什么要在紧跟在PageHelper.startPage后面立即执行业务查询方法,才能实现分页?
          因为PageHelper.startPage方法内部会创建一个线程局部变量,存储了当前的页码(pageNum)和页面大小(pageSize)。
         这个线程局部变量在整个业务查询过程中保持不变,直到PageHelper.startPage方法执行完毕。
         只有在业务查询方法执行时,才能通过这个线程局部变量获取到当前的页码和页面大小,从而计算出正确的数据库查询起始索引。
         因此,必须在紧跟在PageHelper.startPage后面立即执行业务查询方法,才能实现分页。
         
         原理
         ThreadLocal:同一个线程内可以共享数据
         1.第一个查询会从线程中拿到分页所需要的数据,进行分页查询
         2.第一个查询执行完毕后,会将线程中的数据清除
         3.以后的查询就不能从ThreadLocal拿到分页数据,不会再进行分页了
         

导入依赖(pom.xml):

<dependency>
    <groupId>com.github.pagehelper</groupId>
    <artifactId>pagehelper</artifactId>
    <version>5.1.11</version>
</dependency>
 

配置分页插件(MyBatis-config.xml):

1com.github.pagehelper.PageInterceptor:插件名称

2Dialect:指定数据库类型

<plugins>
    <plugin interceptor="com.github.pagehelper.PageInterceptor">
        <property name="helperDialect" value="mysql"/>
    </plugin>
</plugins>
​
@Configuration
public class MyBatisConfig {

    // 配置PageHelper插件

    @Bean
    public PageInterceptor pageInterceptor() {

        // 创建pageInterceptor分页拦截器对象,加入到Spring容器中
        PageInterceptor pageInterceptor = new PageInterceptor();


        // 设置属性,开启分页合理化
        // 合理化:如果当前页码超出范围,则返回最后一页数据。如果当前页码小于1,则返回第一页数据。
        Properties properties = new Properties();
        properties.setProperty("reasonable", "true");
        pageInterceptor.setProperties(properties);


        return pageInterceptor;
    }

}

 

插件的使用:

@Test
public void testTeacherRelationshipToMulti() {
​
    TeacherMapper teacherMapper = session.getMapper(TeacherMapper.class);
​
    PageHelper.startPage(1,2);
    // 查询Customer对象同时将关联的Order集合查询出来
    List<Teacher> allTeachers = teacherMapper.findAllTeachers();
//
    PageInfo<Teacher> pageInfo = new PageInfo<>(allTeachers);
​
    System.out.println("pageInfo = " + pageInfo);
    long total = pageInfo.getTotal(); // 获取总记录数
    System.out.println("total = " + total);
    int pages = pageInfo.getPages();  // 获取总页数
    System.out.println("pages = " + pages);
    int pageNum = pageInfo.getPageNum(); // 获取当前页码
    System.out.println("pageNum = " + pageNum);
    int pageSize = pageInfo.getPageSize(); // 获取每页显示记录数
    System.out.println("pageSize = " + pageSize);
    List<Teacher> teachers = pageInfo.getList(); //获取查询页的数据集合
    System.out.println("teachers = " + teachers);
    teachers.forEach(System.out::println);
​
}

=========================================================================================
/**
 * packageName com.atguigu.cloud.mybatis
 *
 * @author 胡浩
 * @version 1.0
 * @version0 JDK 17
 * @className PageTest
 * @date 2025/1/22 10:31
 * @description TODO
 */
@SpringBootTest
public class PageTest {


    @Autowired
    private EmpMapper empMapper;
    @Test
    void test(){


        /**
         * 原理
         * 原业务底层:select * from t_emp;
         * 拦截器要做的事
         * 1):统计这个表的总数量
         * 2):在SQL语句后面自动拼接limit查询条件
         * 3):跟据传入的pageNum和pageSize计算出数据库查询的起始索引
         *
         * 为什么要在紧跟在PageHelper.startPage后面立即执行业务查询方法,才能实现分页?
         * 因为PageHelper.startPage方法内部会创建一个线程局部变量,存储了当前的页码(pageNum)和页面大小(pageSize)。
         * 这个线程局部变量在整个业务查询过程中保持不变,直到PageHelper.startPage方法执行完毕。
         * 只有在业务查询方法执行时,才能通过这个线程局部变量获取到当前的页码和页面大小,从而计算出正确的数据库查询起始索引。
         * 因此,必须在紧跟在PageHelper.startPage后面立即执行业务查询方法,才能实现分页。
         *
         * 原理
         * ThreadLocal:同一个线程内可以共享数据
         * 1.第一个查询会从线程中拿到分页所需要的数据,进行分页查询
         * 2.第一个查询执行完毕后,会将线程中的数据清除
         * 3.以后的查询就不能从ThreadLocal拿到分页数据,不会再进行分页了
         */
        PageHelper.startPage(1, 2);
        //紧跟在PageHelper.startPage后面立即执行业务查询方法,才能实现分页
        List<Emp> emps = empMapper.selectAllEmp();
        for (Emp emp : emps) {
            System.out.println(emp);
        }

        System.out.println("===================================");
        List<Emp> empss = empMapper.selectAllEmp();
        for (Emp emp : empss) {
            System.out.println(emp);
        }
    }



    @Test
    void test02(){

        //与前端交互的信息,全部都封装在PageInfo对象中

        PageHelper.startPage(1, 2);

        List<Emp> emps = empMapper.selectAllEmp();
        //创建PageInfo对象,封装了分页的所有信息
        PageInfo<Emp> empPageInfo = new PageInfo<>(emps);
        System.out.println(empPageInfo.getPages());//总页数
        System.out.println(empPageInfo.getList());//当前页的数据
        System.out.println(empPageInfo.getTotal());//总记录数
        System.out.println(empPageInfo.getNavigatepageNums());//导航页码数组
        System.out.println(empPageInfo.getNavigatePages());//导航页码的数量
        System.out.println(empPageInfo.getNavigateFirstPage());//导航页码的起始值
        System.out.println(empPageInfo.getNavigateLastPage());//导航页码的结束值
        System.out.println(empPageInfo.isIsFirstPage());//是否是第一页
        System.out.println(empPageInfo.isIsLastPage());//是否是最后一页

    }
}

3.3逆向工程

MyBatis 的逆向工程是一种自动化生成持久层代码和映射文件的工具,它可以根据数据库表结构和设置的参数生成对应的实体类、Mapper.xml 文件、Mapper 接口等代码文件,简化了开发者手动生成的过程。逆向工程使开发者可以快速地构建起 DAO 层,并快速上手进行业务开发。 MyBatis 的逆向工程有两种方式:通过 MyBatis Generator 插件实现和通过 Maven 插件实现。无论是哪种方式,逆向工程一般需要指定一些配置参数,例如数据库连接 URL、用户名、密码、要生成的表名、生成的文件路径等等。 总的来说,MyBatis 的逆向工程为程序员提供了一种方便快捷的方式,能够快速地生成持久层代码和映射文件,是半自动 ORM 思维像全自动发展的过程,提高程序员的开发效率。

注意:逆向工程只能生成单表crud的操作,多表查询依然需要我们自己编写!

逆向工程插件MyBatisX使用

MyBatisX 是一个 MyBatis 的代码生成插件,可以通过简单的配置和操作快速生成 MyBatis Mapper、pojo 类和 Mapper.xml 文件。下面是使用 MyBatisX 插件实现逆向工程的步骤:

  • 安装插件:在Intellij IDEA中打开插件市场,搜索MyBatisX并进行安装

  • 使用Intellij IDEA连接数据库

  • 填写信息

  • 展示数据库

  • 逆向工程使用

  • 效果展示

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值