MyBatis相關記錄
mybatis 專案初始化
maven依賴
<dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.4.6</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.13</version> </dependency> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <version>1.2.3</version> </dependency>
Mybatis 全域性配置檔案
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <environments default="development"> <environment id="development"> <transactionManager type="JDBC"/> <dataSource type="POOLED"> <property name="driver" value="com.mysql.cj.jdbc.Driver"/> <property name="url" value="jdbc:mysql://192.168.31.136:3306/mybatis"/> <property name="username" value="root"/> <property name="password" value="123456"/> </dataSource> </environment> </environments> <mappers> <mapper resource="UserMapper.xml"/> </mappers> </configuration>
建立實體類和Mapper配置檔案
public class User { private Long id; private String name; private Integer age; }
<?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.godfunc.UserMapper"> <select id="selectUser" resultType="com.godfunc.User"> select * from user where id = #{id} </select> </mapper>
測試
@Test public void func1() throws IOException { String resource = "mybatis-config.xml"; InputStream resourceAsStream = Resources.getResourceAsStream(resource); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream); SqlSession sqlSession = sqlSessionFactory.openSession(); User user = sqlSession.selectOne("com.godfunc.UserMapper.selectUser", 1L); log.error("result: {}", user); } sqlSession.close();
介面式程式設計
建立
UserMapper.java
public interface UserMapper { User selectUser(Long id); }
將
UserMapper.xml
的namespace
改為UserMapper.java
的全類名。測試
@Test public void func2() throws IOException { String resource = "mybatis-config.xml"; InputStream resourceAsStream = Resources.getResourceAsStream(resource); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream); SqlSession sqlSession = sqlSessionFactory.openSession(); UserMapper userMapper = sqlSession.getMapper(UserMapper.class); User user = userMapper.selectUser(1L); log.error("type {}", userMapper.getClass()); log.error("result: {}", user); sqlSession.close(); }
此時我們看到控制檯將
userMapper
的 type 打印出來了:[main] ERROR com.godfunc.Demo1 - type class com.sun.proxy.$Proxy5
在這裡我們可以看到,
myBatis
為userMapper
建立了一個代理物件(也就是UserMapper
的實現類 ),此時我們就知道了,Mybatis
的介面式程式設計,其實最終還是為介面建立了實現類,然後呼叫實現方法,對資料庫進行操作。INSERT
返回主鍵在
UserMapper.java
中加上insert
void insert(User user);
在
UserMapper.xml
中配置sql
<insert id="insert" parameterType="com.godfunc.User" useGeneratedKeys="true" keyProperty="id"> INSERT INTO user(name, age) values(#{name}, #{age}) </insert>
note: 如果引數是一個物件,我們是可以直接通過屬性名就行取值的。
Mybatis 多引數
多個引數,Mybatis
會做特殊處理,會將多個引數封裝到一個 map
中。map
的 key 是從 param1...paramn
介面方法和 sql 配置
<update id="update"> update user set name = #{param1}, age = #{param2} where id = #{param3} </update>
void update(String name, Integer age, Long id);
這樣,我們可以通過取出
map
中的多個引數,進行資料的更新。note: 如果引數是
List
獲取Array
, 裝到map
中 key 的名字是list
和array
Mybatis 引數封裝
以
update
為例(這裡用的是@Param註解)void update(@Param("name") String name, @Param("age") Integer age, @Param("id") Long id);
在執行
update
方法時,會進入org.apache.ibatis.binding.MapperProxy
類中,執行invoke
方法,從類的命名上我們可以清楚的知道,MapperProxy
是Mapper的動態代理類
查詢返回 Map
介面和配置檔案如下
@MapKey("id") Map<Long, User> selectResultMap();
<select id="selectResultMap" resultType="com.godfunc.User"> select * from user </select>
11:23:24.543 [main] ERROR com.godfunc.Demo1 - result {1=User{id=1, name='里斯', age=2}, 3=User{id=3, name='天全', age=3}, 8=User{id=8, name='王大山', age=34}, 9=User{id=9, name='天全11', age=3}}
Mapper 配置檔案中返回值型別依舊是
User
,在介面方法宣告上使用@MapKey("id")
將 返回結果中的id
作為Map
的key
.
級聯查詢
介面和配置檔案如下
public class User { private Long id; private String name; private Integer age; private Job job; }
User selectUserWithJob(Long id);
<resultMap id="userMap" type="com.godfunc.User">
<result column="id" property="id"/>
<result column="name" property="name"/>
<result column="age" property="age"/>
<result column="job_id" property="job.id"/>
<result column="job_name" property="job.name"/>
<result column="u_id" property="job.uid"/>
</resultMap>
<select id="selectUserWithJob" resultMap="userMap">
select u.*, b.id job_id, b.name job_name, b.u_id from user u left join job b on b.u_id = u.id where u.id = #{id}
</select>
這裡是一個對一關聯,也可以使用 association
標籤做,但是這裡直接使用了 .
的方式。
子查詢
當我們進行子查詢,想要傳遞多個引數時,可以這樣做
column="{key1=column1,key2=column2}"
*fetchType="eager|lazy"
設定子查詢立即載入|懶載入bind
將一個表示式的值繫結到一個變數中(可以用來做模糊查詢的%
拼接)<select id="selectByUserName" resultType="com.godfunc.User"> <bind name="_name" value="'%'+name+'%'"/> select * from user where name like #{_name} </select>
Note: 如果只有一個引數,也要加
@Param
註解,不然會報錯
快取
- 一級快取 預設是開啟的
- 二級快取
- 快取的回收策略(eviction):
- LRU - 最近最少使用的 :移除最長時間不被使用的物件。
- FIFO - 先進先出:按物件進入快取的順序來移除他們。
- SOFT - 軟引用:移除基於垃圾回收器狀態和軟引用規則的物件。
- WEAK - 弱引用:更積極地移除基於垃圾收集器狀態和弱引用規則的物件。
- 快取重新整理間隔(flushInterval):快取多久時間清空一次,預設不清空,設定一個毫秒值。
- 是否只讀(readOnly)
- 快取的回收策略(eviction):