mybatis體系結(jié)構(gòu)

開發(fā)步驟
配置文件
mybatis.xml
<?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://localhost:3306/java?"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="org/mybatis/example/BlogMapper.xml"/>
</mappers>
</configuration>
mapper.xml
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="xxx"> <insert id="insertTeacher" parameterType="com.mybatisLearn.beans.Teacher">
insert into teacher(name,age,lesson) values (#{name},#{age},#{lesson})
</insert>
</mapper>
它根據(jù)傳進(jìn)來的類的屬性來找值,屬性是指實現(xiàn)了get set方法的。
一個簡單的Teacher實體類,該類用來定義表的結(jié)構(gòu),對于必要的屬性,必須實現(xiàn)get set方法。
package com.mybatisLearn.beans; public class Teacher { private String name; private Integer age; private String lesson;
//記得實現(xiàn)一個無參方法,不然mybatis只會調(diào)用有參構(gòu)造器,從而報錯。
public Teacher(){}
public Teacher(String name, Integer age, String lesson) { this.name = name; this.age = age; this.lesson = lesson; } @Override public String toString() { return "Teacher{" + "name='" + name + '\'' + ", age=" + age + ", lesson='" + lesson + '\'' + '}'; } public String getName() {return name;} public void setName(String name) {this.name = name;} public Integer getAge() {return age;} public void setAge(Integer age) {this.age = age;} public String getLesson() {return lesson;} public void setLesson(String lesson) {this.lesson = lesson;} }
Dao層的實現(xiàn)
package com.mybatisLearn.dao;
import com.mybatisLearn.beans.Teacher;
import java.io.IOException;
import java.io.InputStream;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
public class ITeacherDaoImpl implements ITeacherDao {
@Override
public void insert(Teacher teacher) {
SqlSession sqlSession = null;
try {
// 加載主配置文件
InputStream inputStream = Resources.getResourceAsStream("mybatis.xml");
// 創(chuàng)建sqlsessionFactory
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
// 創(chuàng)建sqlSession
sqlSession = sqlSessionFactory.openSession();
// 操作
sqlSession.insert("insertTeacher", teacher);
// 提交操作
sqlSession.commit();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (sqlSession != null) {
sqlSession.close();
}
}
}
}
測試一下
package com.mybatisLearn.Test; import com.mybatisLearn.beans.Teacher; import com.mybatisLearn.dao.ITeacherDao; import com.mybatisLearn.dao.ITeacherDaoImpl; import org.junit.Before; import org.junit.Test; public class ATest { private ITeacherDao dao; @Before public void before(){ dao = new ITeacherDaoImpl(); } @Test public void test(){ Teacher teacher = new Teacher("李花",22,"人工智能"); dao.insert(teacher); } }
Done!
Mapper中namespace
當(dāng)多個mapper文件中有重名的sql時,會報錯
Error updating database. Cause: java.lang.IllegalArgumentException: insertTeacher is ambiguous in Mapped Statements collection (try using the full name including the namespace, or rename one of the entries)
需要指明使用
sqlSession.insert("test01.insertTeacher", teacher);
從屬性文件中讀取jdbc連接要素
jdbc_mysql.properties
jdbc.driver=com.mysql.cj.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/java?serverTimezone=GMT%2B8 jdbc.username=root jdbc.password=baobao521
mybatis.xml
<properties resource="jdbc_mysql.properties"/>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>
</environment>
</environments>
別名
mapper.xml 中每條語句都要寫parameterType太冗余,可以使用別名
在mybatis.xml中配置
<typeAliases>
<typeAlias type="com.mybatisLearn.beans.Teacher" alias="Teacher"/>
</typeAliases>
mapper.xml中可以簡寫
<insert id="insertTeacher" parameterType="Teacher">
insert into teacher(name,age,lesson) values (#{name},#{age},#{lesson})
</insert>
但是每個表都要寫的話還是很冗余,使用package可以更簡單,可以將包中的簡單類名當(dāng)作別名。
<typeAliases>
<package name="com.mybatisLearn.beans"/>
</typeAliases>
使用別名解決字段不一致問題
有時候,實體類的字段名和屬性名可能不一致,這時可以通過別名來解決
<select id="xx" resultType="Teacher">
select tid id, tname name, tage age from teacher
</select>
使用resultmap來解決不一致問題
<resultMap id="studentMapper" type="Student">
<id column="id" property="id"></id>
<result column="sname" property="age"></result>
<result column="sname" property="name"></result>
</resultMap>
實現(xiàn)mapper的動態(tài)代理
// 通過sqlSession中的getMapper方法來動態(tài)加載Dao類,
sqlSession = MyBatisUtils.getSqlSession(); studentdao = sqlSession.getMapper(IStudentDao.class);
// 保證命名一致, 只需調(diào)用mapper中注冊方法的id就可以
List<Student> students = studentdao.queryAll();
使用Map實現(xiàn)多條件查詢
Map<String, Object> map = new HashMap<String, Object>(); map.put("name", "李"); map.put("age",15); List<Student> students = studentdao.queryMuti(map);
<select id="queryMuti" resultType="Student"> select name,age,id from student where name like '%' #{name} '%' and age > #{age} </select>
使用索引號實現(xiàn)多條件查詢
List<Student> students = studentdao.queryMuti2("李", 15);
<select id="queryMuti2" resultType="Student">
select name,age,id from student where name like '%' #{arg0} '%' and age > #{arg1}
</select>
動態(tài)SQL
<mapper namespace="com.DymicSqlLearn.Dao.IUserDao">
<select id="selectStudentByCondition" resultType="User">
select id, username, password, role
from user
<where>
<if test="arg0 != null and arg0 != ''">
and username like '%' #{arg0} '%'
</if>
<if test="arg1 > 0">
and role < #{arg1}
</if>
</where>
</select>
</mapper>
一些符號不能使用需要替換
< <= > >= & ' "
< <;= > >= & ' "
choose的行為類似于switch
<select id="queryByChoose" resultType="User"> select * from user <where> <choose> <when test="arg0 != null and arg0 != ''"> and username like '%' #{arg0} '%' </when> <when test="arg1 > 0"> and role < #{arg1} </when> </choose> </where> </select>
foreach
<select id="quertByForeach" resultType="User"> select * from user <if test="array.length > 0"> where id in <foreach collection="array" item="roleid" open="(" close=")" separator=","> #{roleid} </foreach> </if> </select>
foreach-list
<select id="quertByForeachList" resultType="User"> select * from user <if test="list.size > 0"> where id in <foreach collection="array" item="roleid" open="(" close=")" separator=","> #{roleid} </foreach> </if> </select>
SQL片段
<sql id="parms">
id, username, password, role
</sql>
select <include refid="parms"></include>from user
一對多
簡化版
public class User { private Set<Article> articles; }
public class Article { private User author; }
查詢
<resultMap id="userMapper" type="com.foreignkeyMybatis.beans.User">
<id column="id" property="id"/>
<result column="username" property="username"/>
<collection property="articles" ofType="com.foreignkeyMybatis.beans.Article">
<id column="aid" property="id"/>
<result column="title" property="title"/>
</collection>
</resultMap>
<select id="getAll" resultMap="userMapper">
select user.id, username, title, uid, aid
from user, article
where uid = user.id
</select>
或者也可以
<select id="selectArtByUid" resultType="com.foreignkeyMybatis.beans.Article"> select title from article where uid=#{xxx} </select> <resultMap id="userMapper2" type="com.foreignkeyMybatis.beans.User"> <id column="id" property="id"/> <result column="username" property="username"/> <collection property="articles" ofType="com.foreignkeyMybatis.beans.Article" select="selectArtByUid" column="id"> </collection> </resultMap> <select id="getByName" parameterType="string" resultMap="userMapper2"> select id, username from user where username=#{xxx} </select>
當(dāng)多對一時,只需將collection替換成associate就可以
懶加載
mybatis.xml 中配置, 必須是多次查詢。
侵入式懶加載
<settings>
<!-- 訪問實體時才觸發(fā)加載, 實體內(nèi)的關(guān)聯(lián)表作為實體的一部分-->
<setting name="lazyLoadingEnable" value="true"/>
<setting name="aggresiveLayLoading" value="false"/>
</settings>
深度懶加載
<settings>
<!-- 訪問實體內(nèi)的關(guān)聯(lián)表時才觸發(fā)加載-->
<setting name="lazyLoadingEnable" value="true"/>
<setting name="aggresiveLayLoading" value="true"/>
</settings>
緩存
- 一級緩存: 基于PerpetualCache 的 HashMap本地緩存,其存儲作用域為 SQLSession,當(dāng) Session flush 或 close 之后,該Session中的所有 Cache 就將清空。默認(rèn)開啟
2.二級緩存與一級緩存其機制相同,默認(rèn)也是采用 PerpetualCache,HashMap存儲,不同在于其存儲作用域為 Mapper(Namespace),并且可自定義存儲源,如 Ehcache。
二級緩存開啟
<mapper namespace="com.cache.dao.IUserDao"> <!-- 開啟二級緩存 --> <cache/>
</mapper>
常用屬性
<cache eviction="FIFO" <!--回收策略為先進(jìn)先出--> flushInterval="60000" <!--自動刷新時間60s--> size="512" <!--最多緩存512個引用對象--> readOnly="true"/>
使用ehcache緩存
需要 mybatis-ehcache.jar 和 ehcache-core.jar
<cache type="org.mybatis.caches.ehcache.EhcacheCache">
配置
ehcache.xml
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../config/ehcache.xsd"> <diskStore path="F:\develop\ehcache" /> 磁盤中的存儲位置 <defaultCache maxElementsInMemory="1000" 內(nèi)存中緩存的element的最大數(shù)目 maxElementsOnDisk="10000000" 磁盤上緩存的element的最大數(shù)目 eternal="false" 設(shè)定緩存的elements是否永遠(yuǎn)不過期 overflowToDisk="false" 內(nèi)存緩存溢出的時候是否將過期的element緩存到磁盤上 timeToIdleSeconds="120" 兩次訪問的間隔時間,超過便被刪除 timeToLiveSeconds="120" 緩存element的有效生命期 diskExpiryThreadIntervalSeconds="120" 磁盤緩存的清理線程運行間隔,默認(rèn)是120秒 memoryStoreEvictionPolicy="LRU"> 內(nèi)存緩存達(dá)到最大,有新的element加入的時候, 移除緩存中element的策略 </defaultCache> </ehcache>
浙公網(wǎng)安備 33010602011771號