Mybatis持久層框架
一、Mybatis簡介
1.1 Mybatis是什麼
- MyBatis 是一款優秀的持久層框架,它支持定製化 SQL、存儲過程以及高級映射。
- MyBatis 避免了幾乎所有的 JDBC代碼和手動設置參數以及獲取結果集。
- MyBatis 可以使用簡單的 XML 或註解來配置和映射原生類型、接口和 Java 的POJO(Plain Old Java Objects,普通老式 Java 對象)爲數據庫中的記錄。
Mybatis 3的官網鏈接>>>
1.2 ORM是什麼
- ORM(Object Relational Mapping)
- 編寫程序的時候,以面向對象的方式處理數據
- 保存數據的時候,卻以關係型數據庫的方式存儲
- ORM解決方案包含下面四個部分
- 在持久化對象上執行基本的增、刪、改、查操作
- 對持久化對象提供一種查詢語言或者API
- 對象關係映射工具
- 提供與事務對象交互、執行檢查、延遲加載以及其他優化功能
1.3 Mybatis與Hibernate
Hibernate優勢
- Hibernate的DAO層開發比MyBatis簡單,Mybatis需要維護SQL和結果映射。
- Hibernate對對象的維護和緩存要比MyBatis好,對增刪改查的對象的維護要方便。
- Hibernate數據庫移植性很好,MyBatis的數據庫移植性不好,不同的數據庫需要寫不同SQL。
- Hibernate有更好的二級緩存機制,可以使用第三方緩存。MyBatis本身提供的緩存機制不佳。
Mybatis優勢
- MyBatis可以進行更爲細緻的SQL優化,可以減少查詢字段。
- MyBatis容易掌握,而Hibernate門檻較高。
總結
我們將Mybatis和Hibernate之間的區別自個用六個詞做總結:
- Mybatis:小巧、方便、高效、簡單、直接、半自動化
- Hibernate:強大、方便、高效、複雜、間接、全自動化
二、Mybatis的使用(SSM)
2.1 Mybatis的配置
- maven配置依賴:
<!--Mybatis-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.3.0</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.2</version>
</dependency>
<!--Alibaba 數據庫連接池-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.10</version>
</dependency>
<!--數據庫驅動-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.connector.version}</version>
</dependency>
- ApplicationContext.xml(Spring核心配置文件)
<!-- 啓用註解 -->
<context:annotation-config />
<context:component-scan base-package="com.bosssoft.core"></context:component-scan>
<!-- 加載數據源配置文件 -->
<context:property-placeholder location="classpath:datasource.properties" />
<!--數據源 Alibaba連接池-->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" destroy-method="close">
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
<property name="driverClassName" value="${jdbc.driver}" />
<property name="maxActive" value="${jdbc.maxActive}" />
<property name="minIdle" value="${jdbc.minIdle}" />
</bean>
<!-- 配置sqlSessionFactory -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!-- 當mybatis的xml文件和mapper接口不在相同包下時,需要用mapperLocations屬性指定xml文件的路徑 -->
<property name="mapperLocations" value="classpath:mapper/*.xml"/>
<!-- 指定mybatis核心配置文件 -->
<property name="configLocation" value="classpath:mybatis-config.xml"/>
<property name="dataSource" ref="dataSource"/>
</bean>
<!-- 配置掃描包,加載mapper代理對象 -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.bosssoft.core.dao"/>
</bean>
<!-- 使用@Transactional進行聲明式事務管理需要聲明下面這行 -->
<tx:annotation-driven proxy-target-class="true" />
<!-- 事務管理 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
<property name="rollbackOnCommitFailure" value="true"/>
</bean>
- datasource.properties(數據庫連接池屬性)
jdbc.url=jdbc:mysql://localhost:3306/login_test?characterEncoding=UTF-8
jdbc.username=root
jdbc.password=123456
jdbc.driver=com.mysql.jdbc.Driver
jdbc.maxActive=10
jdbc.minIdle=5
mybatis-config.xml
- mybatis-config.xml
<configuration>
<!--別名設置-->
<typeAliases>
<package name="com.bosssoft.core.entity"/>
</typeAliases>
</configuration>
其餘屬性詳細設置見 Mybatis官網>>>
2.2 Mybatis-generator實現逆向工程
- 新建數據庫及表,並完成:
2.根據需求更改配置文件generator.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
"http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration>
<!--數據庫驅動-->
<classPathEntry location="mysql-connector-java-5.1.7-bin.jar"/>
<context id="MySQLTables" targetRuntime="MyBatis3">
<commentGenerator>
<property name="suppressDate" value="true"/>
<property name="suppressAllComments" value="true"/>
</commentGenerator>
<!--數據庫鏈接地址賬號密碼-->
<jdbcConnection driverClass="com.mysql.jdbc.Driver" connectionURL="jdbc:mysql://localhost/mybatis_work" userId="root" password="123456">
</jdbcConnection>
<javaTypeResolver>
<property name="forceBigDecimals" value="false"/>
</javaTypeResolver>
<!--生成Model類存放位置-->
<javaModelGenerator targetPackage="com.bosssoft.core.entity" targetProject="src">
<property name="enableSubPackages" value="true"/>
<property name="trimStrings" value="true"/>
</javaModelGenerator>
<!--生成映射文件存放位置-->
<sqlMapGenerator targetPackage="Mapper" targetProject="src">
<property name="enableSubPackages" value="true"/>
</sqlMapGenerator>
<!--生成Dao類存放位置-->
<javaClientGenerator type="XMLMAPPER" targetPackage="com.bosssoft.core.dao" targetProject="src">
<property name="enableSubPackages" value="true"/>
</javaClientGenerator>
<!--生成對應表及類名-->
<table tableName="t_user" domainObjectName="User" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false"></table>
<table tableName="t_role" domainObjectName="Role" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false"></table>
<table tableName="t_resource" domainObjectName="Resource" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false"></table>
<table tableName="t_user_role" domainObjectName="UserRole" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false"></table>
<table tableName="t_role_resource" domainObjectName="RoleResource" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false"></table>
</context>
</generatorConfiguration>
- 打開命令行,運行mybatis-generator-core-1.3.6.jar,則相關文件會自動生成到src中。
java -jar mybatis-generator-core-1.3.6.jar -configfile generator.xml
2.3 Mapper映射文件
- 映射文件中參數的指定
- 如果是單個參數(基本類型、對象、Map對象)使用parameterType;
- 如果是多個參數,則無需要parameterType屬性
- 方法的返回值(對象類類型)
- 如果是單個返回值(基本類型、對象、Map對象)使用resultType;
- 如果是多個參數,則需要resultMap。
<mapper namespace="com.bosssoft.core.dao.UserMapper" >
<resultMap id="BaseResultMap" type="User" >
<constructor >
<idArg column="account" jdbcType="VARCHAR" javaType="java.lang.String" />
<arg column="password" jdbcType="VARCHAR" javaType="java.lang.String" />
</constructor>
</resultMap>
<sql id="Base_Column_List" >
account,password
</sql>
<select id="getUser" resultMap="BaseResultMap">
select
<include refid="Base_Column_List" />
from user
where account = #{account,jdbcType=VARCHAR} and password = #{password,jdbcType=VARCHAR}
</select>
</mapper>
2.4 動態SQL
MyBatis 的強大特性之一便是它的動態 SQL。如果你有使用 JDBC 或其它類似框架的經驗,你就能體會到根據不同條件拼接 SQL 語句的痛苦。例如拼接時要確保不能忘記添加必要的空格,還要注意去掉列表最後一個列名的逗號。利用動態 SQL 這一特性可以徹底擺脫這種痛苦。
雖然在以前使用動態 SQL 並非一件易事,但正是 MyBatis 提供了可以被用在任意 SQL 映射語句中的強大的動態 SQL 語言得以改進這種情形。
動態 SQL 元素和 JSTL 或基於類似 XML 的文本處理器相似。在 MyBatis 之前的版本中,有很多元素需要花時間瞭解。MyBatis 3 大大精簡了元素種類,現在只需學習原來一半的元素便可。MyBatis 採用功能強大的基於 OGNL 的表達式來淘汰其它大部分元素。
- if
- choose (when, otherwise)
- trim (where, set)
- foreach
<select id="findActiveBlogLike"
resultType="Blog">
SELECT * FROM BLOG
<where>
<if test="state != null">
state = #{state}
</if>
<if test="title != null">
AND title like #{title}
</if>
<if test="author != null and author.name != null">
AND author_name like #{author.name}
</if>
</where>
</select>
where 元素只會在至少有一個子元素的條件返回 SQL 子句的情況下才去插入“WHERE”子句。而且,若語句的開頭爲“AND”或“OR”,where 元素也會將它們去除。
2.5 MyBatis關聯配置
- 關聯結果的配置與使用
在一方配置collection節點,在多方配置association 節點。(一對多)
一方:
<resultMap type="blog" id="blogResult">
<id column="id" property="id"/>
<result column="title" property="title"/>
<result column="content" property="content"/>
<result column="create_time" property="createTime"/>
<result column="type" property="type"/>
<collection property="comments" column="id" javaType="ArrayList" ofType="comment" select="selectComments"/> //ofType爲集合中保存的類型
</resultMap>
<select id="selectComments" parameterType="int" resultType="comment">
select * from comment where blog_id = #{id}
</select>
<select id="selectBlogs" resultMap="blogResult" >select * from blog</select>//常規查詢
多方:
<resultMap type="comment" id="commentResult">
<id property="id" column="author_id"/>
<result property="createDate" column="date"/>
<result property="......." column="..."/>
<association property="blog"
column="blog_id"
javaType="blog" select="findBloyById"></association>
</resultMap>
<select id="findUserTypeById" parameterType="int" resultType="blog">
select * from blog where id=#{id}
</select>
- 集合映射的配置與使用
在select中指定一個查詢語句來獲取查詢結果,此查詢語句使用連接查詢來配置:
<select id="selectBlogById" resultMap="blogResult" parameterType="int">
select
B.id,B.title,B.author_id,B.content,
B.create_time,B.type,A.id,A.username,
A.password,A.email,A.address,A.phone
from Blog B left outer join Author A on B.author_id = A.id
</select>
在blogResult中如下聲明:
<resultMap type="blog" id="blogResult">
<id column="id" property="id"/>
<result column="title" property="title"/>
..............
<collection property="comment" column="blog_id"
javaType="java.util.Set" ofType="comment"
resultMap="commentResult"></collection>
commentResult是關聯表的字段聲明,需要注意的是隻包含基本類型的字段,也就是說 這種嵌套map只能用於單向關聯