首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

MyBatis 持久層框架核心用法詳解

     編輯:Java 相關知識

MyBatis 簡介與發展歷程

MyBatis 是一款優秀的持久層框架,支援自定義 SQL、存儲過程以及高級映射。它幾乎消除了所有的 JDBC 代碼、參數手動設置及結果集檢索工作。MyBatis 通過簡單的 XML 或註解進行配置與原始映射,將介面和 Java 的 POJO(Plain Old Java Objects,普通 Java 對象)映射為數據庫中的記錄。

MyBatis 最初是 Apache 的開源項目 iBatis,2010 年遷移至 Google Code 並更名為 MyBatis,2013 年 11 月再遷移至 GitHub(項目地址)。iBATIS 一詞源於 "internet" 與 "abatis" 的組合,提供 SQL Maps 和 Data Access Objects(DAO)功能。

核心架構:SqlSessionFactory

每個 MyBatis 應用的核心都是 SqlSessionFactory 實例,可通過 SqlSessionFactoryBuilder 獲取。構建器支持從 XML 配置文件或預定義的配置類實例中創建工廠。

代碼生成器:MyBatis Generator

MyBatis Generator 可自動生成 Dao 層、Model 層和 Mapper 層代碼,極大提升開發效率。官方下載地址:MyBatis Generator,中文介紹:中文文檔。

依賴包準備

  • mybatis-generator-core-1.3.2.jar
  • mysql-connector-java-5.1.34.jar
  • ojdbc14-10.2.0.1.0.jar (Oracle)
  • sqljdbc4-4.0.jar (SQL Server)

生成器配置文件 generator.xml 關鍵點

<context id="MySQLTables" targetRuntime="MyBatis3" defaultModelType="conditional">
  <commentGenerator>
    <property name="suppressAllComments" value="true" />
  </commentGenerator>
  <jdbcConnection driverClass="com.microsoft.sqlserver.jdbc.SQLServerDriver"
      connectionURL="jdbc:sqlserver://127.0.0.1:1433;DatabaseName=test"
      userId="test" password="1234">
  </jdbcConnection>
  <javaTypeResolver>
    <property name="forceBigDecimals" value="false" />
  </javaTypeResolver>
  <javaModelGenerator targetPackage="com.ouc.model" targetProject="D:\JavaProject\generator\src">
    <property name="enableSubPackages" value="true" />
    <property name="trimStrings" value="true" />
  </javaModelGenerator>
  <sqlMapGenerator targetPackage="com.ouc.mapping" targetProject="D:\JavaProject\generator\src">
    <property name="enableSubPackages" value="true" />
  </sqlMapGenerator>
  <javaClientGenerator type="XMLMAPPER" targetPackage="com.ouc.dao" targetProject="D:\JavaProject\generator\src">
    <property name="enableSubPackages" value="true" />
  </javaClientGenerator>
  <table tableName="V_SupplyUser" domainObjectName="VSupplyUser" ... />
  <table tableName="WJ_GateList" domainObjectName="WJGateList" ... />
</context>

執行生成命令

java -jar mybatis-generator-core-1.3.2.jar -configfile generator.xml -overwrite

MyBatis 框架整合配置

核心配置文件 sqlMapConfig.xml

<configuration>
  <settings>
    <setting name="cacheEnabled" value="true" />
    <setting name="lazyLoadingEnabled" value="true" />
    <setting name="multipleResultSetsEnabled" value="true" />
    <setting name="useColumnLabel" value="true" />
    <setting name="useGeneratedKeys" value="false" />
    <setting name="autoMappingBehavior" value="PARTIAL" />
    <setting name="defaultExecutorType" value="SIMPLE" />
    <setting name="defaultStatementTimeout" value="" />
    <setting name="mapUnderscoreToCamelCase" value="false" />
    <setting name="localCacheScope" value="SESSION" />
    <setting name="jdbcTypeForNull" value="NULL" />
  </settings>
  <typeAliases>
    <typeAlias alias="User" type="com.ouc.mkhl.platform.authority.model.User"/>
    <typeAlias alias="Role" type="com.ouc.mkhl.platform.authority.model.Role"/>
  </typeAliases>
  <typeHandlers>
    <typeHandler handler="com.ouc.openplatform.dao.mybatis.SerializableTypeHandler"/>
  </typeHandlers>
</configuration>

自定義類型處理器:SerializableTypeHandler

public class SerializableTypeHandler extends BaseTypeHandler<Serializable> {
    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, Serializable parameter, JdbcType jdbcType) throws SQLException {
        ps.setObject(i, parameter);
    }
    @Override
    public Serializable getNullableResult(ResultSet rs, String columnName) throws SQLException {
        return (Serializable) rs.getObject(columnName);
    }
    // 其他重寫方法...
}

結果映射 resultMap 詳解

MyBatis 查詢映射時可使用 resultType 或 resultMap,兩者不可共存。resultMap 是最強大的特性,適用於複雜映射場景。

基礎結果映射示例

<resultMap id="UserBaseResultMap" type="User">
  <id column="id" property="id" jdbcType="INTEGER" />
  <result column="userName" property="userName" jdbcType="VARCHAR" />
  <result column="password" property="password" jdbcType="VARCHAR" />
  <result column="email" property="email" jdbcType="VARCHAR" />
  <result column="trueName" property="trueName" jdbcType="VARCHAR" />
  <result column="sex" property="sex" jdbcType="VARCHAR" />
  <result column="age" property="age" jdbcType="INTEGER" />
  <result column="telephone" property="telephone" jdbcType="VARCHAR" />
</resultMap>

CRUD 操作映射

查詢

<select id="selectUsers" resultMap="UserBaseResultMap">
  select id, userName, email from user
</select>

新增(主鍵自增)

<insert id="saveUser" parameterType="User">
  insert into user (userName, password, email, trueName, sex, age, telephone)
  values (#{userName,jdbcType=VARCHAR}, #{password,jdbcType=VARCHAR}, #{email,jdbcType=VARCHAR},
          #{trueName,jdbcType=VARCHAR}, #{sex,jdbcType=VARCHAR}, #{age,jdbcType=INTEGER}, #{telephone,jdbcType=VARCHAR})
</insert>

動態更新

<update id="updateUser" parameterType="User">
  update user
  <set>
    <if test="userName != null"> userName = #{userName,jdbcType=VARCHAR}, </if>
    <if test="password != null"> password = #{password,jdbcType=VARCHAR}, </if>
    <if test="email != null"> email = #{email,jdbcType=VARCHAR}, </if>
    <if test="trueName != null"> trueName = #{trueName,jdbcType=VARCHAR}, </if>
    <if test="sex != null"> sex = #{sex,jdbcType=VARCHAR}, </if>
    <if test="age != null"> age = #{age,jdbcType=INTEGER}, </if>
    <if test="telephone != null"> telephone = #{telephone,jdbcType=VARCHAR}, </if>
  </set>
  where id = #{id,jdbcType=INTEGER}
</update>

刪除

<delete id="deleteUser" parameterType="Integer">
  delete from user where id = #{id,jdbcType=INTEGER}
</delete>

SQL 片段複用

<sql id="UserBaseColumnList"> userName, password, email, telephone </sql>
<select id="getUsers" resultMap="UserBaseResultMap">
  select <include refid="UserBaseColumnList" /> from user
</select>

參數傳遞方式

基本類型參數

<select id="getUserByName" resultType="User" parameterType="String">
  select id, userName, email from user where userName = #{userName,jdbcType=VARCHAR}
</select>

實體對象參數

<insert id="saveUser" parameterType="User"> ... </insert>

Map 參數

<select id="selectChildGroupTotalNum" resultType="Integer">
  select count(*) from groupinfo
  <trim prefix="WHERE" prefixOverrides="AND|OR">
    and id in <foreach collection="idStr" item="ids" open="(" separator="," close=")"> #{ids} </foreach>
    <if test="name != null and name != '' "> and name LIKE CONCAT(CONCAT('%', #{name}),'%') </if>
    <if test="description != null and description != '' "> AND description LIKE CONCAT(CONCAT('%', #{description}),'%') </if>
    <if test="type != null and type != -1 "> AND type = #{type,jdbcType=INTEGER} </if>
    <if test="category != null and category != -1 "> AND category = #{category,jdbcType=INTEGER} </if>
  </trim>
</select>

多參數傳遞

方式一:按順序傳遞

<select id="selectSensorNobySensorName" resultType="Integer">
  select SensorNo from sensorconfig where Name = #{0} and TestunitNo = #{1} and LABCODE = #{2}
</select>

方式二:@Param 註解(推薦)

<select id="selectByUserNameAndVCode" resultMap="UserBaseResultMap">
  select id, userName from user
  <trim prefix="WHERE" prefixOverrides="AND|OR">
    <if test="userName != null and userName != ''"> and userName LIKE CONCAT(CONCAT('%', #{userName}),'%') </if>
    <if test="supplierno != null and supplierno != ''"> and supplierNo LIKE CONCAT(CONCAT('%', #{supplierno}),'%') </if>
    and supplierNo != 'test'
  </trim>
  LIMIT #{startIndex}, #{pageSize}
</select>

動態 SQL 核心標籤

MyBatis 動態 SQL 是其最靈活強大的部分,主要標籤包括:

  • <selectKey>:主鍵生成策略
  • <if>:條件判斷
  • <where> / <set>:智能處理 WHERE/SET 子句
  • <trim>:替代 where/set,自定義前綴後綴
  • <choose>, <when>, <otherwise>:類似 switch-case
  • <foreach>:集合遍歷,構建 IN 子句等

綜合動態查詢示例

<select id="selectTotalNumByAccountType" resultType="Integer">
  select count(*) from user
  <trim prefix="WHERE" prefixOverrides="AND|OR">
    and id not in <foreach collection="idStr" item="ids" open="(" separator="," close=")"> #{ids} </foreach>
    <if test="userName != null and userName != ''"> and userName LIKE CONCAT(CONCAT('%', #{userName}),'%') </if>
    <if test="supplierno != null and supplierno != ''"> and supplierNo LIKE CONCAT(CONCAT('%', #{supplierno}),'%') </if>
    <if test="trueName != null and trueName != ''"> and trueName LIKE CONCAT(CONCAT('%', #{trueName}),'%') </if>
    AND accountType = #{accountType}
  </trim>
</select>
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved