public class MybatisTest { public static void main(String[] args) throws IOException { InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml"); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); SqlSession sqlSession = sqlSessionFactory.openSession(); User user = sqlSession.selectOne("MyMapper.selectUser",1); System.out.println(user); } }
<build> <resources> <resource> <directory>src/main/java</directory> <includes> <include>**/*.properties</include> <include>**/*.xml</include> </includes> <filtering>false</filtering> </resource> <resource> <directory>src/main/resources</directory> <includes> <include>**/*.properties</include> <include>**/*.xml</include> </includes> <filtering>false</filtering> </resource> </resources> </build>
<!--配置全局屬性--> <settings> <!-- 開啓駝峯命名轉換 :{name_id} -> {nameId} --> <setting name="mapUnderscoreToCamelCase" value="true"/> </settings>
在四大對象的建立過程當中都會有插件的介入;html
(1)useGeneratedKeys 和 keyProperty 屬性配合使用便可獲取到自增主鍵的值;java
(2)使用 selectkey 標籤也能夠實現,不過 order 的屬性值要設置爲 after 才能獲取獲得;mysql
<selectKey order="AFTER"keyProperty="id" resultType="String">select last_insert_id()</selectKey>
(1)在要執行的sql前用 selectKey 標籤來實現;git
(2)相關的三個屬性分別是 keyProperty、resultType 和 order;github
(3)有兩種寫法分別是 order 的屬性值爲 before 和 after;Oracle 用 before;web
<selectKey keyColumn="id" keyProperty="id" order="BEFORE" resultType="int"> select max(id)+1 as myNo from emp </selectKey>
<!--序列實現自增主鍵-->
SQL >create sequence autoID increment by 1 start with 1 maxvalue 999999 cycle;
SQL >insert into tablename values(autoID.nextval,...);
一、int、long 和 boolean 類型的返回值咱們能夠直接用;spring
二、增刪改後必定要 commit,不然對於數據庫的修改不會生效;sql
<resultMap id="myuser" type="com.stan.hello.User"> <!--<id column="id" property="id"></id>--> <result column="user_name" property="userName"></result> </resultMap> <select id="queryUserById" resultMap="myuser" parameterType="java.lang.String"> select * from tb_user where id = #{id} </select>
(1)OGNL(對象圖導航語言):數據庫
(2)if 判斷編程
<select id="queryUserList" resultType="com.stan.pojo.User"> select * from tb_user WHERE 1=1 <if test="name!=null and name.trim()!=''"> and name like '%${name}%' </if> </select>
<!--if 判斷拼接 where 條件存在多餘 and 的解決方法:加一個 1=1;使用where 或者 trim標籤;-->
(1)語法:choose----when----when----otherwise-----choose;
(2)理解:相似於 java 中帶break 的 switch語句,只匹配一個條件;
<select id="queryUserByNameOrAge" resultType="com.stan.pojo.User"> select * from tb_user WHERE 1=1 <choose> <when test="name!=null and name.trim()!=''"> and name like '%${name}%' </when> <when test="age!=null"> and age = #{age} </when> <otherwise> and name='allen' </otherwise> </choose> </select>
(1)遍歷集合拼接 where 條件(如:in 集合):幾個經常使用的屬性 collection、item、separator、open、close、index(map的key)
List<User> queryUserByIds(@Param("ids") String[] ids); <select id="queryUserByIds" resultType="com.stan.pojo.User"> select * from tb_user where id in <foreach collection="ids" item="id" open="(" close=")" separator=","> #{id} </foreach> </select>
(2)數據批量插入
<select id="queryUserByNameAndAge" resultType="com.stan.pojo.User"> select * from tb_user <where> <if test="name!=null and name.trim()!=''"> and name like '%${name}%' </if> <if test="age!=null"> and age = #{age} </if> </where> </select>
<update id="updateUser"> update tb_user <set> <if test="userName != null and userName.trim() != ''"> user_name=#{userName} </if> <if test="password != null and password.trim() != ''"> password=#{password} </if> </set> where id = #{id} </update>
update tb_user <trim prefix="set" suffixoverride="," suffix=" where id = #{id} "> <if test="userName != null and userName.length()>0"> user_name=#{userName} , </if> <if test="password != null and password.length()>0"> password=#{password} , </if> </trim>
<select id="getEmpsTestInnerParameter" resultType="com.hand.mybatis.bean.Employee"> <bind name="bindeName" value="'%'+userName+'%'"/> SELECT * FROM tb_user <if test="userName!=null"> where user_name like #{bindeName} </if> </select>
(1)內置參數:
(2)sql 片斷:
<sql id="commonSql">id,user_name,password</sql> <select id="queryUserById" resultMap="userResultMap"> select <include refid="commonSql"></include> from tb_user where id = #{id} </select>
(1)做用:就是提高查詢的效率;
(2)分類:
(1)一級緩存失效的四種狀況
(1)做用:能夠實現不一樣的 session 之間的數據共享,一個 namespace(一個接口)對應一個map(二級緩存);
(2)原理:
(3)使用:
(1)緩存相關設置
(2)原理圖示
(1)導入緩存的包和整合包;測試的時候採用的maven
<dependency> <groupId>org.mybatis.caches</groupId> <artifactId>mybatis-ehcache</artifactId> <version>1.1.0</version> </dependency> <dependency> <groupId>net.sf.ehcache</groupId> <artifactId>ehcache</artifactId> <version>2.10.5</version> </dependency>
(2)classpath 下編寫 ehcache-xml 配置文件;
<?xml version="1.0" encoding="UTF-8"?> <ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd"> <diskStore path="D:\ehcache" /> <defaultCache maxElementsInMemory="1000" maxElementsOnDisk="10000000" eternal="false" overflowToDisk="false" timeToIdleSeconds="120" timeToLiveSeconds="120" diskExpiryThreadIntervalSeconds="120" memoryStoreEvictionPolicy="LRU"> </defaultCache> </ehcache>
(3)打開二級緩存的總開關,直接在mapper xml 中用 cache 標籤引用;
<cache type="org.mybatis.caches.ehcache.EhcacheCache" > <property name="timeToIdleSeconds" value="3600"/> <property name="timeToLiveSeconds" value="3600"/> <property name="maxEntriesLocalHeap" value="1000"/> <property name="maxEntriesLocalDisk" value="10000000"/> <property name="memoryStoreEvictionPolicy" value="LRU"/> </cache>
(4)另外一個 mapper 能夠用 cache-ref 標籤來引用其餘 mapper 的緩存策略;
<cache-ref namespace="com.stan.crud.UserDaoMapper"/>
(5)相關配置參數的說明
diskStore標籤:指定數據在磁盤中的存儲位置。 defaultCache標籤:當藉助CacheManager.add("demoCache")建立Cache時,EhCache便會採用<defalutCache/>指定的的管理策略 如下屬性是必須的: maxElementsInMemory - 在內存中緩存的element的最大數目 maxElementsOnDisk - 在磁盤上緩存的element的最大數目,如果0表示無窮大 eternal - 設定緩存的elements是否永遠不過時。若是爲true,則緩存的數據始終有效,若是爲false那麼還要根據timeToIdleSeconds,timeToLiveSeconds判斷 overflowToDisk - 設定當內存緩存溢出的時候是否將過時的element緩存到磁盤上 如下屬性是可選的: timeToIdleSeconds - 當緩存在EhCache中的數據先後兩次訪問的時間超過timeToIdleSeconds的屬性取值時,這些數據便會刪除,默認值是0,也就是可閒置時間無窮大 timeToLiveSeconds - 緩存element的有效生命期,默認是0.,也就是element存活時間無窮大 diskSpoolBufferSizeMB 這個參數設置DiskStore(磁盤緩存)的緩存區大小.默認是30MB.每一個Cache都應該有本身的一個緩衝區. diskPersistent - 在VM重啓的時候是否啓用磁盤保存EhCache中的數據,默認是false。 diskExpiryThreadIntervalSeconds - 磁盤緩存的清理線程運行間隔,默認是120秒。每一個120s,相應的線程會進行一次EhCache中數據的清理工做 memoryStoreEvictionPolicy - 當內存緩存達到最大,有新的element加入的時候, 移除緩存中element的策略。默認是LRU(最近最少使用),可選的有LFU(最不常使用)和FIFO(先進先出)
一、具體的代碼和數據庫腳本參考:https://blog.csdn.net/hellozpc/article/details/80878563#12_1741
<resultMap id="orderUserRM" type="com.stan.pojo.OrderUser" autoMapping="true"> <association property="user" javaType="com.stan.pojo.User" autoMapping="true"> <id property="id" column="user_id"></id> </association> </resultMap> <select id="queryOrderUserByOrderNumber" resultMap="orderUserRM" parameterType="String"> select * from tb_order o left join tb_user u on o.user_id = u.id where o.order_number = #{number} </select>
<resultMap id="orderUserRM" type="com.stan.pojo.OrderUser" autoMapping="true"> <association property="user" javaType="com.stan.pojo.User" autoMapping="true"> <id property="id" column="user_id"></id> </association> <collection property="details" autoMapping="true" javaType="list" ofType="com.stan.pojo.OrderDetail" >
<!--這裏的 OrderDetail 是訂單和商品關係的媒介--> <id property="id" column="detial_id"></id> <association property="item" javaType="com.stan.pojo.Item" autoMapping="true"> <id property="id" column="item_id"></id> </association> </collection> </resultMap> <select id="queryOrderItemByOrderNumber" resultMap="orderUserRM2" parameterType="String"> select *,d.id as detial_id from tb_order o left join tb_user u on o.user_id = u.id left join tb_orderdetail d on o.id = d.order_id left join tb_item i on i.id = d.item_id where o.order_number = #{number} </select>
<!--延遲加載關聯查詢總開關,association和collection標籤裏的fetchType也是設置加載的模式的--> <setting name="lazyLoadingEnabled" value="true"/> <!--設置爲true的話,只要get一個關聯的屬性,全部的關聯查詢都會發出--> <setting name="aggressiveLazyLoading" value="false"/>
<resultMap id="rm2" type="com.stan.pojo.OrderUser" autoMapping="true"> <association property="user" javaType="com.stan.pojo.User" autoMapping="true" select="queryUserById" column="user_id">
<!--這裏的select指定關聯的查詢的 id,這裏的column是傳過去的參數-->
<!--多個參數的傳遞能夠用map,就是這樣的形式:{key1=col1,key2=col2}-->
</association> </resultMap> <select id="queryOrderByNumber" resultMap="rm2"> select * from tb_order where order_number = #{number} </select>
<!--這個方法不單獨使用的話能夠不在 mapper 接口中書寫方法定義--> <select id="queryUserById" resultType="com.stan.pojo.User"> select * from tb_user where id = #{number} </select>
OrderUser queryOrderByNumber(@Param("number") String number);
@Test public void queryOrderByNumber() throws IOException { OrderMapper mapper = sqlSession.getMapper(OrderMapper.class); OrderUser orderUser = mapper.queryOrderByNumber("201807010001"); System.out.println("----------------------"); System.out.println(orderUser.getOrderNumber()); System.out.println("--------------------"); System.out.println(orderUser.getUser()); }
<dependency> <groupId>cglib</groupId> <artifactId>cglib</artifactId> <version>3.1</version> </dependency>
(1)核心包:spring包、springmvc包、mybatis包、spring-mybatis整合包
(2)其餘包:日誌包、鏈接池包
(1)主要就是配全局 settings 等;
(1)controller 掃描;
(2)視圖解析器;
(3)註解驅動;
(4)默認servlet 處理;
(1)包掃描;
(2)數據源的配置;
(3)事務管理(基於註解的事務);
(4)sqlSessionFactory配置;
(5)配置能夠批量執行的 sqlSession;
(6)配置Mapper 接口的掃描(不可少);
(1)全局參數配置 spring配置文件的路徑;
(2)配置spring 監聽;
(3)配置 springmvc 的DispatcherServlet;
(4)spring框架會自動加載 web-inf 下的配置文件,classpath 路徑下的配置文件須要配置路徑;
(5)SSM框架整合示例;
(1)導包
(2)配置文件(mbg.xml)
(3)運行生成器 java 代碼
EmployeeExample example = new EmployeeExample(); Criteria criteria = example.createCriteria(); criteria.andLastNameLike("%e%"); criteria.andGenderEqualTo("1"); Criteria criteria2 = example.createCriteria(); criteria2.andEmailLike("%e%"); example.or(criteria2);
(1)原理
(2)簡單實現:單個插件
(3)多個插件:攔截同一個對象同一個方法
(4)開發示例:
@Intercepts({@Signature(type= ParameterHandler.class,method = "setParameters",args = {PreparedStatement.class})}) public class MyIntercepter implements Interceptor { public Object intercept(Invocation invocation) throws Throwable { System.out.println("要攔截的方法:"+invocation.getMethod()); MetaObject metaObject = SystemMetaObject.forObject(invocation.getTarget()); Object para = metaObject.getValue("parameterObject"); System.out.println("原來的參數是:"+para); metaObject.setValue("parameterObject","5"); return invocation.proceed(); } public Object plugin(Object o) { System.out.println("包裝的對象:"+o.toString()); return Plugin.wrap(o,this); } public void setProperties(Properties properties) { System.out.println(properties.getProperty("test")); } }
(5)PageHelper 插件使用:實現查詢數據的分頁功能
<dependency> <groupId>com.github.pagehelper</groupId> <artifactId>pagehelper</artifactId> <version>4.1.4</version> </dependency>
<plugins> <plugin interceptor="com.github.pagehelper.PageHelper"> <property name="dialect" value="mysql"/> <property name="offsetAsPageNum" value="false"/> <property name="rowBoundsWithCount" value="false"/> <property name="pageSizeZero" value="true"/> <property name="reasonable" value="false"/> <property name="supportMethodsArguments" value="false"/> <property name="returnPageInfo" value="none"/> </plugin> </plugins>
<select id="queryUserPage" resultType="com.stan.pojo.User"> select * from tb_user </select>
public List<User> queryUserPage();
@Test public void queryPage() throws IOException { Page<User> page = PageHelper.startPage(2,4); List<User> users = mapper.queryUserPage(); for (User user : users) { System.out.println(user); } System.out.println(page); }
(1)批量執行sql語句
(2)mybatis 調用存儲過程:示例參考
(3)自定義類型處理器處理枚舉類型
一、枚舉類型
二、自定義類型處理器:參考示例