1、Mybatis核心對象html
1.1SqlSeesionFactoryjava
SqlSessionFactory主要做用是建立時SqlSession。mysql
SqlSessionFactory可經過SqlSessionFactoryBuild構建,sql
調用器build方法,方法參數爲配置文件的輸入流。 數據庫
String resource = "mybatis-config.xml"; //獲取配置文件輸入流 InputStream inputStream = Resources.getResourceAsStream(resource); //經過配置文件輸入流構建sqlSessionFactory, SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
1.2SqlSessionapache
SqlSession負責程序與持久層之間的交互操做。緩存
SqlSession中包含了全部執行SQL語句的方法,安全
且該對象是線程不安全的。服務器
SqlSession主要方法:session
<T> T selectOne(String statement);
執行查詢方法,statement表明mapper文件中<select>元素對應的id.
方法結束會返回一個對象。
<T> T selectOne(String statement,Object parameter);
執行查詢方法,statement表明mapper文件中<select>元素對應的id,
parameter表明查詢語句所需的參數。
<E> List<E> selectList(String statement, Object parameter)
與上列函數功能相同,返回的是一個List對象。
int insert(String statement)
statement表示mapper文件中<insert>元素的id,執行插入語句後,返回受影響的行數。
int insert(String statement, Object parameter)
parameter表明插入語句所需的參數對象,結果返回受影響函數。
int update(String statement)
執行更新語句,statement爲mapper文件中<update>元素的id,返回受影響函數。
int update(String statement, Object parament);
執行更新語句,parameter爲語句所需參數,返回受影響行數。
int delete(String statement)//執行刪除語句,statement爲<delete>元素id,返回受影響行數
int delete(String statement, Object parameter);執行刪除語句,parameter爲語句所需參數。
void commit()//提交事務
voidrollBack();//回滾事務。
2、mybatis配置元素
2.1<configuration>
<configuration>根元素,mybatis的其餘配置元素都須要在該元素類配置。
2.2<properties>
<properties>:經過外部的配置動態替換內部的配置。
例如:
2.2.1在src目錄下新建一個db.properties
#dataSource #Sat Mar 02 13:31:50 CST 2019 jdbc.url=jdbc\:mysql\://localhost\:3306/mybatis jdbc.driver=com.mysql.jdbc.Driver jdbc.username=root jdbc.password=123456
2.2.2 在mybatis-config.xml中配置<properties>
<properties resource = "db.properties">
2.2.3 修改mybatis-congfig.xml中的DataSource配置
<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>
2.3<settings>
<settings>:更改mybatis的運行行爲,例如開啓二級緩存,開啓延遲等。圖片來自:https://blog.csdn.net/fageweiketang/article/details/80767532
使用時指定屬性name和value便可,具體以下:
<settings> <setting name="cacheEnabled" value="true"/> <setting name="lazyLoadingEnabled" value="true"/> <setting name="multipleResultSetsEnabled" value="true"/>
...
</settings>
2.4<typeAliases>:爲配置文件中的java了設置別名。
<typeAliases> <typeAlias> alias = "user" type = "com.xxx.xxx.User" /> </typeAliases>
將com.xxx.xxx.User起一個別名uesr。若是alias缺省,則會自動將類名首字母小寫後做爲別名。
<typeAliases> <package name = "com.xx.xxx"/> </typeAliases>
自動掃描指定包下全部類,自動將類名首字母爲小寫做爲別名。
例如com.xxx.xxx.User的別名爲user。
可使用註解指定別名
@Alias("author")
public class Author {
...
}
mybatis默認別名:
2.5<typeHandlers>
2.6<objectFactory>
每次MyBatis建立結果對象的新實例時,都會使用ObjectFactory實例來執行此操做。
2.7<plugins>
MyBatis容許在映射語句的執行過程當中的某一點進行攔截調用。
2.8<environments>
<environments>主要對環境進行配置,內部可包含多個<environment>,其實就是數據源的配置,MyBatis容許配置多個數據源。
<environment>中不一樣的id區分不一樣的數據源,須要注意的是每個數據庫都對應一個SqlSessionFactory實例。若是有兩個
數據庫則須要構建兩個實例。
構建不一樣的SqlSessionFactory實例,經過<environment>的id區分。
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader, environment);
例如配置以下:
<environments default = "mysql"> <!-- 配置id爲SQL的數據庫環境 --> <environment id = "my"> <!--區分不一樣數據庫,構建不一樣的SqlSessionFactory--> <!-- 設置事務管理類型爲JDBC --> <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>
<environment id= "you">
...
</environment> </environments>
String resource = "mybatis-config.xml"; //獲取配置文件輸入流 InputStream inputStream = Resources.getResourceAsStream(resource); //經過配置文件輸入流構建sqlSessionFactory, SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream,"my");//不一樣的id區分數據庫
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream,"you");//不一樣的id區分數據庫
2.9<transactionManager>
在MyBatis中能夠配置兩種事務管理類型,一種是JDBC、一種是MANAGED。
JDBC:這種配置只是直接使用JDBC提交和回滾功能。它依賴從數據源檢索到的鏈接來管理事務的範圍。
MANAGED:此配置幾乎不起做用。它從不提交或回滾鏈接。相反,它容許容器管理事務的整個生命週期
(例如,JEE應用程序服務器上下文)。默認狀況下,它會關閉鏈接。可是,有些容器並不指望這樣作,
所以若是須要阻止它關閉鏈接,請將「closeConnection」屬性設置爲false。
<transactionManager type="MANAGED"> <property name="closeConnection" value="false"/> </transactionManager>
注:若是計劃將MyBatis與Spring一塊兒使用,則無需配置任何TransactionManager,由於Spring模塊將設置一個覆蓋之前任何設置的配置。
2.10<dataSource>
<dataSource>:dataSource元素用於配置JDBC鏈接資源對象,使用標準的JDBC數據資源接口。
該元素有三種數據源類型(UNPOOLED、POOLED、JNDI)
UNPOOLED:每次請求數據源時,該數據源的實現只需打開和關閉一個鏈接。雖然速度有點慢,
但對於不須要當即可用鏈接性能的簡單應用程序來講,這是一個不錯的選擇。
所以對於某些人來講,池可能不那麼重要,這種配置將是理想的。
屬性配置:
driver:JDBC驅動的java類,(例如com.mysql.jdbc.Driver)
url:數據庫的鏈接地址。
username:數據庫登陸名
password:登陸密碼
defaultTransactionlsolationLevel:默認的鏈接事務隔離級別。
POOLED:他實現了鏈接池JDBC鏈接對象,以免建立新鏈接實例所需的初始鏈接和身份驗證時間。
這是一種流行的併發Web應用程序實現最快響應的方法。
屬性配置:
除了上述五個配置外,該類型還支持以下配置:
poolMaximumActiveConnections :這是能夠在任何給定時間存在的活動(即正在使用)鏈接數。默認值:10
poolMaximumIdleConnections :任意給定時間可以存在的空閒鏈接數。
poolMaximumCheckoutTime:
poolTimeToWait 使池有機會打印日誌狀態,並在鏈接花費異常長的狀況下從新嘗試獲取鏈接
(以免在池配置錯誤的狀況下永遠無提示地失敗)。默認值:20000ms(即20秒)
poolMaximumLocalBadConnectionTolerance 若是得到一個壞的鏈接,它還有機會從新嘗試得到另外一個有效的鏈接。
但重試時間不該超過該屬性設置的值。
poolPingQuery :ping查詢被髮送到數據庫,以驗證鏈接是否處於良好的工做狀態,並準備好接受請求。
默認值是「no ping query set」,這將致使大多數數據庫驅動程序失敗,並顯示一條錯誤消息。
poolPingEnabled :能夠啓用或禁止ping query,若是啓用,還必須使用有效的SQL語句設置PoolpingQuery屬性.默認爲false.
JNDI:能夠在EJB或者引用服務器等容器中使用,容器能夠集中或在外部配置數據源,而後放置一個JNDI上下文引用。
配置屬性:
initial_context:主要用於在InitialContext中尋找上下文,該屬性爲可選屬性。
data_source:此屬性表示引用數據源實例位置的上下文路徑。
2.11<mappers>
定義了映射SQL語句後,須要告訴MyBtis在哪裏找到映射文件,<mappers>就是提供這樣的功能。
能夠經過一下方法告知映射文件位置:
2.11.1使用類路徑相關資源
2.11.2使用URL路徑
2.11.3使用接口類
2.11.4將包下全部接口註冊爲映射
3、映射文件配置元素
3.1 <select>
<select>元素主要用於編寫查詢語句,可指定屬性:
id:惟一標識符,表明該語句。
parameterType:傳遞的參數類型。
resultType:返回值類型。
flushCache:設置是否清空緩存,默認爲fasle。
userCache:是否開啓緩存,默認爲true.
timeout:設置超時時間。
fetchSize:指定獲取記錄的總條數。
statementType:指定語句的類型.(例如Statement,PreparedStatement...)
resultSetType:表示結果集類型。
<select id="findCustomerById" parameterType = "Integer" resultType = "com.mybatis.first.Customer"> select * from t_customer where id = #{id} </select>
參數類型爲Integer,返回值類型爲Customer,#{}相似佔位符,#{id}表明爲其設置的參數。
3.2<insert>
該元素用於映射插入語句,返回一個數字表示插入的行數。
屬性:
keyProperty:(僅對update、insert有效)將插入或刪除語句的返回值賦給PO類的某個屬性。
useGeneratedKeys:獲取數據庫主鍵(數據庫內部自動增長的字段),默認爲fasle.
二者須要配合使用,設置useGeneratedKeys=「true」並將keyProperty設置爲目標屬性。
<!-- 添加用戶 --> <insert id = "addCustomer" parameterType = "com.mybatis.first.Customer" keyProperty="id" useGeneratedKeys="true"> insert into t_customer(username, jobs,phone) value(#{username}, #{jobs}, #{phone}) </insert>
import java.io.IOException; import java.io.InputStream; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; 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 MybatisTest { public static void main(String[] args) throws IOException { String resource = "mybatis-config.xml"; //獲取配置文件輸入流 InputStream inputStream = Resources.getResourceAsStream(resource); //經過配置文件輸入流構建sqlSessionFactory, SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream,"my"); //經過sqlSessionFactory獲取sqlSession,true表明設置爲自動提交。 SqlSession sqlSession = sqlSessionFactory.openSession(true); //執行CustomerMapper.xml文件中,id爲xxxCustomer的語句,參數爲Integer對象。 Customer customer = new Customer(); customer.setJobs("student"); customer.setPhone("135xxxx9876"); customer.setUsername("zrx"); int customers = sqlSession.insert("com.mybatis.mapper.CustomerMapper.addCustomer", customer); System.out.println(customer.getId()); System.out.println(customers); //若是沒有設置自動提交,使用insert、update、delete時須要使用sqlSession.commit()手動提交。 sqlSession.close(); } }
對於不支持主鍵自動增加的數據庫,可經過以下方式實現主鍵自動增加。
<!-- 添加用戶 --> <insert id = "addCustomer" parameterType = "com.mybatis.first.Customer" > <selectKey keyProperty = "id" resultType = "Integer" order = "BEFORE"> select if(max(id) is null,1,max(id) + 1) as newId from t_customer </selectKey> insert into t_customer(id,username, jobs,phone) value(#{id},#{username}, #{jobs}, #{phone}) </insert>
尋找表中最大id,若是爲空則設置爲1,不爲空則設置爲最大id+1。
order屬性可設置爲:BEFORE,AFTER。BEFORE表明在執行語句以前執行
<selectKey>,AFTER表明在<selectKey>以後執行語句。
3.3 update和delete
update和delete的屬性與上述語句中屬性基本同樣。
<update id = "updateCustomer" parameterType = "com.xxx.xxx.Customer" flushCache = "true" statementType = "PREPARED" timeout = "20"> ...... </update>
<delete id = "updateCustomer" parameterType = "com.xxx.xxx.Customer" flushCache = "true" statementType = "PREPARED" timeout = "20"> ...... </delete>
3.4<sql>
<sql>元素用於定義可重用的SQL代碼片斷,而後在其餘語句中應用這個定義的片斷。
例如:
<sql id = "customerColumns"> id,username,jobs,phone </sql> <select> select <include refid = "customerColumns"/> from t_customer where id = #{id} </select>
其實還能夠更靈活的使用<sql>元素:
<sql id = "customerColumns"> id,username,jobs,phone </sql> <sql id = "tablename"> ${prefix}customer </sql> <sql id = "someinclude"> from <include refid = "${include_target}"/> </sql> <sql> <select id = "findCustomerById" parameterType = "Integer" resultType = "com.xxx.xxx.Customer"> select <include refid = "customerColumns"/> <include refid = "someinclude"> <property name = "prefix" value = "t_"/> <property name = "include_target" value = "tablename"/> </include> where id = #{id} </select>
首先<insert>中首先包含"customerColumns",語句就變成了select id,username,jobs,phone
而後再包含"someinclude", someinclude中首先有from,而後又包含了refid = ${include_targer},
${include_targer}即獲取include_target屬性的值,就變成了refid = "tablename".
tablename中一樣先獲取prefix屬性的值(${prefix})「t_」,因而語句最後就變成了:
select id,username,jobs,phone from t_customer where id = #{id}。
3.5<resultMap>
<resultMap>主要用於創建數據庫中列名與POJO類屬性的映射關係,
當列名與POJO類屬性同名時,MyBatis會自動填充。但若是不一樣名時,
須要指定映射關係,MyBatis纔會對其填充。
屬性:
id:<resutlMap>的惟一標識符
type:須要映射的POJO類。
子元素:
id:指定主鍵與POJO屬性之間映射,property指定POJO類屬性名,column指定列名。
result:指定列名和POJO類屬性映射,property指定POJO類屬性名,column指定列名。
Customer.java
public class Customer { private Integer id; private String username; private String jobs; private String phone; public int getId() { return id; } public void setId(Integer id) { this.id = id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getJobs() { return jobs; } public void setJobs(String jobs) { this.jobs = jobs; } public String getPhone() { return phone; } public void setPhone(String phone) { this.phone = phone; } @Override public String toString() { return "Customer [id=" + id + ", username=" + username + ", jobs=" + jobs + ", phone=" + phone + "]"; } }
建立t_custoemr表:
CREATE TABLE `t_customer` ( `t_id` int(32) NOT NULL AUTO_INCREMENT, `t_username` varchar(50) DEFAULT NULL, `t_jobs` varchar(50) DEFAULT NULL, `t_phone` varchar(16) DEFAULT NULL, PRIMARY KEY (`t_id`) ) ENGINE=InnoDB AUTO_INCREMENT=16 DEFAULT CHARSET=utf8;
CustomerMapper.xml
<?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.mybatis.mapper.CustomerMapper" >
<!--結果映射,將列名與Customer屬性創建映射關係--> <resultMap type="com.mybatis.first.Customer" id="re"> <id property="id" column="t_id"/> <result property = "username" column="t_username"/> <result property = "jobs" column="t_jobs"/> <result property="phone" column="t_phone" /> </resultMap> <!--查找全部用戶--> <select id="findAllCustomer" resultMap="re"> select * from t_customer </select> <!-- 添加用戶 --> <insert id = "addCustomer" parameterType = "com.mybatis.first.Customer" > <selectKey keyProperty = "id" resultType = "Integer" order = "BEFORE"> select if(max(t_id) is null,1,max(t_id) + 1) as newId from t_customer </selectKey> insert into t_customer(t_id,t_username, t_jobs,t_phone) value(#{id},#{username}, #{jobs}, #{phone}) </insert> </mapper>
測試:
import java.io.IOException; import java.io.InputStream; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; 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 MybatisTest { public static void main(String[] args) throws IOException { String resource = "mybatis-config.xml"; //獲取配置文件輸入流 InputStream inputStream = Resources.getResourceAsStream(resource); //經過配置文件輸入流構建sqlSessionFactory, SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream,"my"); //經過sqlSessionFactory獲取sqlSession,true表明設置爲自動提交。 SqlSession sqlSession = sqlSessionFactory.openSession(true); //執行CustomerMapper.xml文件中,id爲xxxCustomer的語句,參數爲Integer對象。 Customer customer = new Customer(); customer.setJobs("student"); customer.setPhone("135xxxx9876"); customer.setUsername("zrx"); int num = sqlSession.insert("com.mybatis.mapper.CustomerMapper.addCustomer",customer); List<Customer> customers = sqlSession.selectList("com.mybatis.mapper.CustomerMapper.findAllCustomer", customer); for(Customer temp : customers) { System.out.println(customers); } //若是沒有設置自動提交,使用insert、update、delete時須要使用sqlSession.commit()手動提交。 sqlSession.close(); } }
參考資料: