MyBatis总结篇

183 阅读4分钟

工作原理

  1. 首先,开发人员通过XML或注解配置文件来描述Java对象和SQL语句之间的映射关系。
  2. 当Java程序需要访问数据库时,MyBatis会根据配置文件自动生成SQL语句,并将Java对象转换为数据库中的数据类型。
  3. MyBatis使用JDBC API来执行SQL语句,并将查询结果映射回Java对象中。
  4. 最后,Java程序可以通过MyBatis提供的API来访问数据库,并对数据进行增删改查等操作。

MyBatis的使用

  • 添加依赖
<dependency>
  <groupId>org.mybatis</groupId>
  <artifactId>mybatis</artifactId>
  <version>3.5.2</version>
</dependency
  • 相关配置文件 主配置文件(在resources资源文件夹下)
<configuration>
    <!--设置数据库连接的信息-->
    <properties resource="db.properties"/>
    <!--给实体类别名-->
    <typeAliases>
        <package name="com.woniu.mybatis.entity"/>
    </typeAliases>
    <!--环境-->
    <environments default="development">
        <environment id="development">
            <!--事务处理器-->
            <transactionManager type="JDBC"></transactionManager>
            <!--数据源类型POOLED池-->
            <dataSource type="POOLED">
                <property name="driver" value="${jdbc.driver}"/>
                <property name="url" value="${jdbc.url}"/>
                <property name="username" value="${jdbc.user}"/>
                <property name="password" value="${jdbc.password}"/>
            </dataSource>
        </environment>
    </environments>
    <!--配置mapper映射文件的位置-->
    <mappers>
        <!--当要映射单个mapper映射文件-->
        <!--<mapper resource="com/...../xml文件名"></mapper>-->
        <!--映射整个mapper包下的接口-->
        <package name="包名.mapper"/>
    </mappers>
</configuration>
  • 映射文件Mapper.xml

    这个xml文件必须和每一个mapper接口映射,xml文件里面写的是mapper接口的sql实现

<mapper namespace="对应mapper接口的完整名称">
    <select id="接口方法名" resultType="返回结果类型" parameterType="复杂类型(这个用于包装类型)"> 
        sql语句
    </select>
    <!--假设在这个例子中,`selectUserById`是这个select标签的唯一标识,`com.example.User`是返回结果的类型(这里假设返回的结果是一个名为User的Java对象),`com.example.User`是传入参数的类型(这里假设传入的参数是一个名为User的对象,包含id和name两个属性)。当调用`selectUserById`方法时,MyBatis会执行对应的SQL语句,并将结果封装成User对象返回。在这个例子中,SQL语句中还包含了对name属性的判断,确保只有当传入的User对象的name属性不为空时,才会根据id查询用户信息。-->
    <select id="selectUserById" resultType="com.example.User" parameterType="com.example.User">
        SELECT * FROM user WHERE id = #{id} AND name = #{name}
    </select>
</mapper>
  • 添加resultMap为结果集赋值
<resultMap id="houseResultMap" type="House">
    <!--主键列用id,其他列用result-->
    <id column="id" property="id"/>
    <result column="numbers" property="numbers"/>
    <!--对于复杂类型,使用关联配置association-->
    <association property="building" javaType="Building">
        <id column="bid" property="id"/>
        <result column="bnumbers" property="numbers"/>
    </association>
</resultMap>
<select id="selectAllHouses" resultMap="houseResultMap">
   sql语句(用到关联查询)
</select>
  • 案例 接口中的方法
int insertUser(User user);

映射文件(#{}中的属性值和实体类的属性一一对应)

<insert id="insertUser" parameterType="com.example.User" keyProperty="id" keyColumn="id"> 
    INSERT INTO user (name, age) VALUES (#{name}, #{age}) 
</insert>
  • 日志信息查看sql语句 首先导入依赖
<dependency>  
    <groupId>org.slf4j</groupId>  
    <artifactId>slf4j-log4j12</artifactId>  
    <version>1.7.25</version>
</dependency>

然后加入log4j.properties

#避免了自己常见Logger日志对象
#console表示在控制台输出
log4j.rootLogger=debug,console
log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=%p %c %d{yyyy-MM-dd HH:mm:ss} %m%n
  • 多参数查询 常用的方法是 添加@Param注解,添加了注解之后才能被识别
List<House> queryHouses(@Param("buildingId") int buildingId, @Param("area") double area);
  • 动态查询 最主要的是if、choose、when、otherwise、trim、where以及set标签
<!--if标签的使用-->
<select id="findUserByCondition" resultType="User">
  select * from user
  <where>
    <if test="username != null">
      and username like '%${username}%'
    </if>
    <if test="age != null">
      and age = #{age}
    </if>
  </where>
</select>
<!--choose、when、otherwise标签的使用-->
<!--在这个例子中,我们使用了标签来根据不同的条件执行不同的SQL语句块。当传入的参数中name属性不为空时,会执行第一个SQL语句块;否则,会执行第二个SQL语句块-->
<select id="selectUserById" resultType="com.example.User"> 
    SELECT * FROM user WHERE id = #{id} 
    <choose> 
        <when test="name != null and name != ''">
            AND name = #{name} 
        </when>
        <otherwise> 
            AND age = #{age}
        </otherwise> 
    </choose>
</select>
<!--trim标签的使用-->
<select id="selectUserByAge" resultType="com.example.User">
  SELECT * FROM user
    <!--这里为什么要使用prefixOverrides呢?我的理解是where后面不能拼接and,但是呢,加入prefixOverrides的话可以自动去掉and,这样sql语句就可以正常拼接了-->
    <trim prefix="WHERE" prefixOverrides="AND |OR ">
      <if test="id != null">
        AND id = #{id}
      </if>
      <if test="name != null and name != ''">
        AND name = #{name}
      </if>
      <if test="age != null">
        AND age &gt;= #{age}
      </if>
    </trim>
</select>
<!--在这个例子中,我们使用了set标签来根据条件对查询结果进行排序。在标签中,我们使用元素来指定排序条件。在元素中,我们使用test属性来指定条件表达式,以判断是否应该执行该SQL片段-->
<select id="selectUserByAge" resultType="com.example.User"> 
    SELECT * FROM user
    <set>
        <if test="id != null"> 
            ORDER BY id ASC 
        </if>
        <if test="name != null and name != ''">
            ORDER BY name ASC
        </if>
        <if test="age != null">
            ORDER BY age ASC 
        </if> 
    </set>
</select>

分页查询

  • 第一种方式 使用RowBounds(MyBatis自带的一个简单分页功能)方式
//接口
List<User> getUsersByPage(RowBounds rowBounds);
<!--映射文件-->
<select id="getUsersByPage" resultType="User">
    select * from user limit #{offset}, #{limit}
</select>
//service层调用mapper层
javaCopy codeint offset = 0;
int limit = 10;
RowBounds rowBounds = new RowBounds(offset, limit);
List<User> users = userMapper.getUsersByPage(rowBounds);
  • 第二种方式 使用PageHelper插件 优点:可以实现物理分页和逻辑分页,同时还支持多种数据库方言(数据库方言是指不同数据库系统在 SQL 语法、数据类型、函数和存储过程等方面存在的差异。引入数据库方言的目的是为了实现对查询的优化,实现分页语句以及count语句的自动生成,方言会生成适合于该特定数据库的效率较高的SQL语法)
<!--首先导入依赖-->
<dependency>
    <groupId>com.github.pagehelper</groupId>
    <artifactId>pagehelper</artifactId>
    <version>5.2.0</version>
</dependency>
<!--在配置文件中配置PageHeler插件-->
<plugins>
    <plugin interceptor="com.github.pagehelper.PageInterceptor">
        <!--配置datebase方言,表示我们要为哪种数据库添加分页支持,每种数据库的分页指令不同-->
        <property name="helperDialect" value="mysql"/>
        <!--配置合理化查询,作用:当页码超出范围时,返回最后一页的数据-->
        <property name="reasonable" value="true"/>
    </plugin>
</plugins>
//接口
List<User> getUsersByPage();
<!--映射文件-->
<select id="getUsersByPage" resultType="User">
    select * from user
</select>
int pageNum = 1;
int pageSize = 10;
//开启分页操作
PageHelper.startPage(pageNum, pageSize);
//下面一行返回一个Page对象,包含了查询结果以及分页相关的信息,如当前页码、每页显示的数据条数、总记录数等
List<User> list = userMapper.selectUsers();
//PageInfo<User> 是通过 Page 对象生成的分页信息对象
PageInfo<User> pageInfo = new PageInfo<>(list);
List<User> users = userMapper.getUsersByPage(page);