Mybatis學習一開發流程及核心API
- 一 MyBatis介紹
MyBatis 本是apache的一個開源專案iBatis,2010年這個專案由apache software foundation 遷移到了google code,並且改名為MyBatis。2013年11月遷移到Github。
MyBatis是一個優秀的持久層框架,它對jdbc的操作資料庫的過程進行封裝,使開發者只需要關注 SQL 本身,而不需要花費精力去處理例如註冊驅動、建立connection、建立statement、手動設定引數、結果集檢索等jdbc繁雜的過程程式碼。
Mybatis通過xml或註解的方式將要執行的各種statement(statement、preparedStatemnt、CallableStatement)配置起來,並通過java物件和statement中的sql進行對映生成最終執行的sql語句,最後由mybatis框架執行sql並將結果對映成java物件並返回。
- 二MyBatis架構
1、mybatis配置
SqlMapConfig.xml,此檔案作為mybatis的全域性配置檔案,配置了mybatis的執行環境等資訊。
mapper.xml檔案即sql對映檔案,檔案中配置了操作資料庫的sql語句。此檔案需要在SqlMapConfig.xml中載入。
2、通過mybatis環境等配置資訊構造SqlSessionFactory即會話工廠
3、由會話工廠建立sqlSession即會話,操作資料庫需要通過sqlSession進行。
4、mybatis底層自定義了Executor執行器介面操作資料庫,Executor介面有兩個實現,一個是基本執行器、一個是快取執行器。
5、MappedStatement也是mybatis一個底層封裝物件,它包裝了mybatis配置資訊及sql對映資訊等。mapper.xml檔案中一個sql對應一個Mapped Statement物件,sql的id即是Mapped statement的id。
6、MappedStatement對sql執行輸入引數進行定義,包括HashMap、基本型別、pojo,Executor通過Mapped Statement在執行sql前將輸入的java物件對映至sql中,輸入引數對映就是jdbc程式設計中對preparedStatement設定引數。
7、MappedStatement對sql執行輸出結果進行定義,包括HashMap、基本型別、pojo,Executor通過Mapped Statement在執行sql後將輸出結果對映至java物件中,輸出結果對映過程相當於jdbc程式設計中對結果的解析處理過程。
- 三 環境搭建
1.導包
需要的jar包:mybatis核心包,依賴包,資料庫驅動包
mybaits的程式碼由github.com管理
下載地址:https://github.com/mybatis/mybatis-3/releases
mybatis核心包
mybatis依賴包
2.加入配置檔案
建立log4j.properties和SqlMapConfig.xml配置檔案,
建立名稱為MyBatisConfig的source folder型別的檔案存放主配置檔案和日誌檔案
在MyBatisConfig下建立log4j.properties如下:mybatis預設使用log4j作為輸出日誌資訊。
# Global logging configuration
log4j.rootLogger=DEBUG, stdout
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n
在MyBatisConfig下建立SqlMapConfig.xml,如下:SqlMapConfig.xml是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>
<!-- 別名 -->
<typeAliases>
<!-- 批量別名定義,掃描整個包下的類,別名為類名(大小寫不敏感) -->
<package name="com.itheima.bean"/>
</typeAliases>
<!-- 和spring整合後 environments配置將廢除 -->
<environments default="development">
<environment id="development">
<!-- 使用jdbc事務管理 -->
<transactionManager type="JDBC" />
<!-- 資料庫連線池 -->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver" />
<property name="url"
value="jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8" />
<property name="username" value="root" />
<property name="password" value="123" />
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="com/itheima/mapper/UserMapper.xml"></mapper>
</mappers>
</configuration>
3.建立實體類
bean類作為mybatis進行sql對映使用,po類通常與資料庫表對應,
資料庫user表如下圖:
package com.itheima.bean;
import java.io.Serializable;
import java.util.Date;
public class User implements Serializable {
private static final long serialVersionUID = 1L;
private Integer id;
private String username;// 使用者姓名
private String sex;// 性別
private Date birthday;// 生日
private String address;// 地址
public Integer 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 getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "User [id=" + id + ", username=" + username + ", sex=" + sex
+ ", birthday=" + birthday + ", address=" + address + "]";
}
}
4.使用動態代理開發
4.1開發規範:
Mapper介面開發方法只需要程式設計師編寫Mapper介面(相當於Dao介面),由Mybatis框架根據介面定義建立介面的動態代理物件,代理物件的方法體同上邊Dao介面實現類方法。
Mapper介面開發需要遵循以下規範:
1、Mapper.xml檔案中的namespace與mapper介面的類路徑相同。(名稱空間繫結此介面)
2、Mapper介面方法名和Mapper.xml中定義的每個statement的id相同
3、Mapper介面方法的輸入引數型別和mapper.xml中定義的每個sql 的parameterType的型別相同
4、Mapper介面方法的輸出引數型別(返回值)和mapper.xml中定義的每個sql的resultType的型別相同
4.2對映檔案定義mapper對映檔案UserMapper.xml
將UserMapper.xml放在mapper目錄下,效果如下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">
<!-- namespace:名稱空間,用於隔離sql -->
<!-- 還有一個很重要的作用,使用動態代理開發DAO,1. namespace必須和Mapper介面類路徑一致 -->
<mapper namespace="cn.itcast.mybatis.mapper.UserMapper">
<!-- 根據使用者id查詢使用者 -->
<!-- 2. id必須和Mapper介面方法名一致 -->
<!-- 3. parameterType必須和介面方法引數型別一致 -->
<!-- 4. resultType必須和介面方法返回值型別一致 -->
<select id="queryUserById" parameterType="int"
resultType="cn.itcast.mybatis.pojo.User">
select * from user where id = #{id}
</select>
<!-- 根據使用者名稱查詢使用者 -->
<select id="queryUserByUsername" parameterType="string"
resultType="cn.itcast.mybatis.pojo.User">
select * from user where username like '%${value}%'
</select>
<!-- 儲存使用者 -->
<insert id="saveUser" parameterType="cn.itcast.mybatis.pojo.User">
<selectKey keyProperty="id" keyColumn="id" order="AFTER"
resultType="int">
select last_insert_id()
</selectKey>
insert into user(username,birthday,sex,address) values
(#{username},#{birthday},#{sex},#{address});
</insert>
</mapper>
4.2建立介面建立UserMapper介面程式碼如下:
public interface UserMapper {
/**
* 根據id查詢
*
* @param id
* @return
*/
User queryUserById(int id);
/**
* 根據使用者名稱查詢使用者
*
* @param username
* @return
*/
List<User> queryUserByUsername(String username);
/**
* 儲存使用者
*
* @param user
*/
void saveUser(User user);
}
4.3載入UserMapper.xml檔案修改SqlMapConfig.xml檔案,新增以下所示的內容:
<!-- 載入對映檔案 -->
<mappers>
<mapper resource="com/itheima/mapper/UserMapper.xml"></mapper>
</mappers>
4.4編寫測試類以及核心API使用
public class UserMapperTest {
private SqlSessionFactory sqlSessionFactory;
@Before
public void init() throws Exception {
// 建立SqlSessionFactoryBuilder
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
// 載入SqlMapConfig.xml配置檔案
InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
// 建立SqlsessionFactory
this.sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream);
}
@Test
public void testQueryUserById() {
// 獲取sqlSession,和spring整合後由spring管理
SqlSession sqlSession = this.sqlSessionFactory.openSession();
// 從sqlSession中獲取Mapper介面的代理物件
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
// 執行查詢方法
User user = userMapper.queryUserById(1);
System.out.println(user);
// 和spring整合後由spring管理
sqlSession.close();
}
@Test
public void testQueryUserByUsername() {
// 獲取sqlSession,和spring整合後由spring管理
SqlSession sqlSession = this.sqlSessionFactory.openSession();
// 從sqlSession中獲取Mapper介面的代理物件
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
// 執行查詢方法
List<User> list = userMapper.queryUserByUsername("張");
for (User user : list) {
System.out.println(user);
}
// 和spring整合後由spring管理
sqlSession.close();
}
@Test
public void testSaveUser() {
// 獲取sqlSession,和spring整合後由spring管理
SqlSession sqlSession = this.sqlSessionFactory.openSession();
// 從sqlSession中獲取Mapper介面的代理物件
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
// 建立儲存物件
User user = new User();
user.setUsername("劉備");
user.setBirthday(new Date());
user.setSex("1");
user.setAddress("蜀國");
// 執行查詢方法
userMapper.saveUser(user);
System.out.println(user);
// 和spring整合後由spring管理
sqlSession.commit();
sqlSession.close();
}
}
5.小結
- selectOne和selectList
動態代理物件呼叫sqlSession.selectOne()和sqlSession.selectList()是根據mapper介面方法的返回值決定,如果返回list則呼叫selectList方法,如果返回單個物件則呼叫selectOne方法。
namespace
mybatis官方推薦使用mapper代理方法開發mapper介面,程式設計師不用編寫mapper介面實現類,使用mapper代理方法時,輸入引數可以使用pojo包裝物件或map物件,保證dao的通用性。
mappers(對映器)
註冊指定包下的所有mapper介面
如:<package name="cn.itcast.mybatis.mapper"/>
注意:此種方法要求mapper介面名稱和mapper對映檔名稱相同,且放在同一個目錄中
#{}和${}
#{}表示一個佔位符號,#{}可以實現preparedStatement向佔位符中設定值,自動進行java型別和jdbc型別轉換。#{}可以有效防止sql注入。#{}可以接收屬性值。 如果parameterType傳輸單個簡單型別值,#{}括號中可以是value或其它名稱。
${}表示拼接sql串,通過${}可以將parameterType 傳入的內容拼接在sql中且不進行jdbc型別轉換, ${}可以接收簡單型別值或pojo屬性值,如果parameterType傳輸單個簡單型別值,${}括號中只能是value。
6.mybatis與hibernate不同
Mybatis和hibernate不同,它不完全是一個ORM框架,因為MyBatis需要程式設計師自己編寫Sql語句。mybatis可以通過XML或註解方式靈活配置要執行的sql語句,並將java物件和sql語句對映生成最終執行的sql,最後將sql執行的結果再對映生成java物件。
Mybatis學習門檻低,簡單易學,程式設計師直接編寫原生態sql,可嚴格控制sql執行效能,靈活度高,非常適合對關係資料模型要求不高的軟體開發,例如網際網路軟體、企業運營類軟體等,因為這類軟體需求變化頻繁,一但需求變化要求成果輸出迅速。但是靈活的前提是mybatis無法做到資料庫無關性,如果需要實現支援多種資料庫的軟體則需要自定義多套sql對映檔案,工作量大。
Hibernate物件/關係對映能力強,資料庫無關性好,對於關係模型要求高的軟體(例如需求固定的定製化軟體)如果用hibernate開發可以節省很多程式碼,提高效率。但是Hibernate的學習門檻高,要精通門檻更高,而且怎麼設計O/R對映,在效能和物件模型之間如何權衡,以及怎樣用好Hibernate需要具有很強的經驗和能力才行。
總之,按照使用者的需求在有限的資源環境下只要能做出維護性、擴充套件性良好的軟體架構都是好架構,所以框架只有適合才是最好。