MyBatis 開發詳解
Mybatis是什麼—基於Java的持久層框架
MyBatis 本是apache的一個開源專案iBatis, 2010年這個專案由apache software foundation 遷移到了google code,並且改名為MyBatis 。2013年11月遷移到Github。
iBATIS一詞來源於“internet”和“abatis”的組合,是一個基於Java的持久層框架。iBATIS提供的持久層框架包括SQL Maps和Data Access Objects(DAO)。
MyBatis 是支援普通 SQL查詢,儲存過程和高階對映的優秀持久層框架。MyBatis 消除了幾乎所有的JDBC程式碼和引數的手工設定以及結果集的檢索。MyBatis 使用簡單的 XML或註解用於配置和原始對映,將介面和 Java 的POJOs(Plain Ordinary Java Objects,普通的 Java物件)對映成資料庫中的記錄。
Mybatis作用:封裝了JDBC操作,簡化資料庫訪問程式碼。
封裝的功能:
- 獲取連線,執行SQL,釋放連線。
- SQL引數設定(可以直接傳入物件,Mybtis會將物件的屬性傳入SQL語句) #{屬性值}取代JDBC的?佔位符。
- 執行結果對映成實體物件。JDBC中需要開發者自己轉換。 實體類的屬性名與查詢結果集ResultSet的列名保持一致,結果集有別名的話以別名為屬性名。
開發者工作:寫SQL語句和實體類,然後使用SqlSession物件執行SQL操作。
Mybatis結構
SqlMapconfig.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.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/mybatis" />
<property name="username" value="root" />
<property name="password" value="XDP" />
</dataSource>
</environment>
</environments>
<mappers>
<!--註冊uerMapper.xml檔案,resource是其路徑,通常和實體類在一個目錄中,也可單獨建一個檔案專門放Mapper.xml-->
<mapper resource="org/tarena/entity/userMapper.xml"/>
</mappers>
</configuration>
userMapper.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,通常設定成包名+sql對映的檔名-->
<mapper namespace="myBatis.test.Demo.userMapper">
<!-- 在select/insert/delete標籤中編寫SQL語句;
設定唯一的id屬性,將來SqlSession通過id呼叫sql語句;
parameterType指明查詢時使用的引數型別。如果引數只有1個則用簡單型別,引數為多個時可用Map集合或實體物件,佔位符用物件的屬性名;
resultType表示查詢結果將要封裝成的實體類,也可以為Map型別或基本型別-->
<select id="getUserByID" parameterType="int" resultType="myBatis.test.User">
select * from users where id=#{propertyName}
</select>
<insert id="save" parameterType="myBatis.test.User">
insert into user(name,salary,age) values (#{name},#{salary},#{age})
</insert>
</mapper>
獲取SqlSession操作sql語句:
//工具類
public class MyBatisUtil {
public static SqlSession getSqlSession {
//mybatis的配置檔案
String conf = "SqlMapConfig.xml";
//使用類載入器載入mybatis的配置檔案
InputStream is = MyBatisUtil.class.getClassLoader().getResourceAsStream(conf);
//構建sqlSession的工廠
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory factory = builder.build(is);
SqlSession session = sessionFactory.openSession();
return session;
}
}
//執行SQL語句
public class TestEMP {
public static void main(String[] args) throws IOException {
SqlSession session=MyBatisUtil.getSqlSession();
//直接返回封裝好的物件
User user=session.selectOne("getUserByID",10);
//other word
session.commit(); //增刪改必須提交事務
session.close(); //釋放session
}
}
返回Map型別的結果集
如果需要全部欄位時可以和實體類對映。如果僅查詢部分欄位,沒必要用實體類封裝,可以用Map進行封裝,key為列名,value為對應的欄位值。
resultType =”java.util.HashMap”
當封裝的實體物件的屬性和查詢結果的欄位名不一致時,可以將結果集的別名改為和實體物件的屬性一致。或者使用resultMap屬性代替resultType屬性,顯式指定對映關係。如下所示:
<!-- type為返回的封裝物件,property為實體類屬性名,column為表的列名-->
<!-- 主鍵用id元素指定匹配規則,非主鍵用result指定匹配規則;一致時可以省略-->
<resultMap id="userMap" type="myBatis.test.User">
<id property="id" column="user_id"></id>
<result prompt="name" column="name"></result>
</resultMap>
Mapper對映介面規則
需要編寫DAO介面的實現類,給controll或service使用。
如果開發者按照MyBatis的規則定義DAO介面,實現類就不用寫了,框架會動態地在記憶體中建立實現類。
- 根據SQL定義檔案中的id屬性當介面的方法名
- 根據SQL定義檔案中的parameterType型別當方法引數型別
- 根據SQL定義檔案中的resultType型別定義方法返回的型別
(多行使用List;單行使用T型別) - 將SQL定義檔案的namespace屬性指定成包名+DAO的介面名
//定義DAO介面
public interface UserDao{
public User getUserByID(int id);
public void save(User user);
}
使用:
UserDao userDao = Session.getMapper(UserDao.class);//介面實現的物件
User user=userDao.getUserByID("10");
Mybatis與Spring的整合
Mybatis-spring.jar整合包,包含以下元件:
1) SqlSessionFactoryBean元件:封裝了建立SqlSessinFactory的過程。
在applictionContext.xml中配置MapperFactoryBean元件
2) MapperFactoryBean元件:封裝了根據Mapper對映器介面生成實現元件的功能。
不用再呼叫session.getMapper(UserDao.class),生成的bean會加入spring容器中,直接呼叫該bean例項的方法執行sql語句。
一個bean只能給一個mapper介面生成實現元件。
<!--定義MapperFactoryBean
一次只能為一個Mapper介面生成實現元件;id為實現介面的物件,value為實現的mapper介面;ref為引用的SqlSession資源;可以注入到service中直接使用。-->
<bean id="userDao" class="org.mybatis.spring.mapper.MapperFactoryBean">
<property name="mapperInterface" value="myBatis.test.Demo.userMapper"></property>
<property name="sqlSessionFactory" ref="ssf"></property>
</bean>
<!--建立SqlSessionFactory,定義SqlSession資源-->
<!-- 整合後不需要myBatis主配置檔案,相關資訊以注入的方式加入到此 -->
<bean id="ssf" class="org.mybatis.spring.SqlSessionFactoryBean">
<!-- 注入dataSource -->
<property name="dataSource" ref="dbcp" />
<!-- 注入SQL語句檔案 -->
<property name="configLocation" value="classpath:org/mybaits/*.xml"></property>
</bean>
<!-- 定義dbcp的DataSource -->
<bean id="dbcp" class="org.apache.commons.dbcp.BasicDataSource">
<property name="username" value="root" />
<property name="password" value="123" />
<property name="url" value="jdbc:mysql://localhost:3306/mydb?useUnicode=true&characterEncoding=UTF-8"></property>
<property name="driver" value="com.mysql.jdbc.Driver"/>
</bean>
測試與使用
public class TestMybatis {
private static ApplicationContext cxt;
public static void main(String[] args) {
// TODO 自動生成的方法存根
cxt = new ClassPathXmlApplicationContext("applicationContext.xml");
UserDao userDao = cxt.getBean("UserDao",UserDao.class);
List<User> list = userDao.findAll();
for (User user : list){
System.out.println(user.getName());
}
}
}
3) MapperScannerConfiger元件,封裝了批量生成Mapper介面元件的功能。
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!-- value設定包路徑,可以使用分號或逗號作為分隔符設定多個包路徑。 -->
<property name="basePackage" value="myBatis.test.Demo" />
<!-- 只有具備該註解標記的接口才會被自動實現 -->
<property name="annotationClass" value="myBatis.test.annotation.MyBatisDao" />
<!-- sqlSessionFactory會自動注入 -->
<property name="sqlSessionFactory" ref="ssf"></property>
</bean>
4) SqlSessionTemplate元件:自己編寫Dao介面實現類時可以簡化程式設計。