文檔版本 | 開發工具 | 測試平臺 | 工程名字 | 日期 | 作者 | 備注 |
---|---|---|---|---|---|---|
V1.0 | 2016.06.26 | lutianfei | none |
SqlSessionFactoryBuilder
SqlSessionFactory
SqlSession
SqlSession履行進程以下:
if (ExecutorType.BATCH == executorType) {
executor = newBatchExecutor(this, transaction);
} elseif (ExecutorType.REUSE == executorType) {
executor = new ReuseExecutor(this, transaction);
} else {
executor = new SimpleExecutor(this, transaction);
}
if (cacheEnabled) {
executor = new CachingExecutor(executor, autoCommit);
}
* 5、 SqlSession的實現類即DefaultSqlSession,此對象中對操作數據庫實質上用的是Executor
SqlSession session = sqlSessionFactory.openSession();
try {
// do work
} finally {
session.close();
}
思路
dao接口
public class UserDaoImpl implements UserDao {
// 需要向dao實現類中注入SqlSessionFactory
// 這里通過構造方法注入
private SqlSessionFactory sqlSessionFactory;
public UserDaoImpl(SqlSessionFactory sqlSessionFactory) {
this.sqlSessionFactory = sqlSessionFactory;
}
@Override
public User findUserById(int id) throws Exception {
SqlSession sqlSession = sqlSessionFactory.openSession();
User user = sqlSession.selectOne("test.findUserById", id);
// 釋放資源
sqlSession.close();
return user;
}
@Override
public List<User> findUserByName(String name) throws Exception {
SqlSession sqlSession = sqlSessionFactory.openSession();
List<User> list = sqlSession.selectList("test.findUserByName", name);
// 釋放資源
sqlSession.close();
return list;
}
@Override
public void insertUser(User user) throws Exception {
SqlSession sqlSession = sqlSessionFactory.openSession();
//履行插入操作
sqlSession.insert("test.insertUser", user);
// 提交事務
sqlSession.commit();
// 釋放資源
sqlSession.close();
}
@Override
public void deleteUser(int id) throws Exception {
SqlSession sqlSession = sqlSessionFactory.openSession();
//履行插入操作
sqlSession.delete("test.deleteUser", id);
// 提交事務
sqlSession.commit();
// 釋放資源
sqlSession.close();
}
public class UserDaoImplTest {
private SqlSessionFactory sqlSessionFactory;
// 此方法是在履行testFindUserById之前履行
@Before
public void setUp() throws Exception {
// 創建sqlSessionFactory
// mybatis配置文件
String resource = "SqlMapConfig.xml";
// 得到配置文件流
InputStream inputStream = Resources.getResourceAsStream(resource);
// 創建會話工廠,傳入mybatis的配置文件信息
sqlSessionFactory = new SqlSessionFactoryBuilder()
.build(inputStream);
}
@Test
public void testFindUserById() throws Exception {
// 創建UserDao的對象
UserDao userDao = new UserDaoImpl(sqlSessionFactory);
// 調用UserDao的方法
User user = userDao.findUserById(1);
System.out.println(user);
}
}
程序員編寫mapper接口需要遵守1些開發規范,這樣Mybatis可以自動生成mapper接口實現類代理對象。
開發規范:
于mapper接口地址
User user = sqlSession.selectOne("test.findUserById", id);
sqlSession.insert("test.insertUser", user);
public interface UserMapper {
//用戶信息綜合查詢
public List<UserCustom> findUserList(UserQueryVo userQueryVo) throws Exception;
//用戶信息綜合查詢總數
public int findUserCount(UserQueryVo userQueryVo) throws Exception;
//根據id查詢用戶信息
public User findUserById(int id) throws Exception;
//根據id查詢用戶信息,使用resultMap輸出
public User findUserByIdResultMap(int id) throws Exception;
//根據用戶名列查詢用戶列表
public List<User> findUserByName(String name)throws Exception;
//插入用戶
public void insertUser(User user)throws Exception;
//刪除用戶
public void deleteUser(int id)throws Exception;
}
<!-- 加載 映照文件 -->
<mappers>
<mapper class="cn.itcast.mybatis.mapper.UserMapper"/>
<!-- 批量加載mapper
指定mapper接口的包名,mybatis自動掃描包下邊所有mapper接口進行加載,遵守1些規范:需要將mapper接口類名和mapper.xml映照文件名稱保持1致,且在1個目錄中
上邊規范的條件是:使用的是mapper代理方法
-->
<package name="cn.itcast.mybatis.mapper"/>
</mappers>
@Test
public void testFindUserById() throws Exception {
SqlSession sqlSession = sqlSessionFactory.openSession();
//創建UserMapper對象,mybatis自動生成mapper代理對象
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
//調用userMapper的方法
User user = userMapper.findUserById(1);
System.out.println(user);
}
需求:將數據庫連接參數單獨配置在db.properties中,只需要在SqlMapConfig.xml中加載db.properties的屬性值。
在SqlMapConfig.xml中就不需要對數據庫連接參數硬編碼。
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis
jdbc.username=root
jdbc.password=mysql
<!-- 加載屬性文件 -->
<properties resource="db.properties">
<!--properties中還可以配置1些屬性名和屬性值 -->
<!-- <property name="jdbc.driver" value=""/> -->
</properties>
<!-- 和spring整合后 environments配置將廢除-->
<environments default="development">
<environment id="development">
<!-- 使用jdbc事務管理,事務控制由mybatis-->
<transactionManager type="JDBC" />
<!-- 數據庫連接池,由mybatis管理-->
<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>
因此,通過parameterType
傳遞的屬性具有最高優先級,resource
或 url
加載的屬性次之,最低優先級的是 properties
元素體內定義的屬性。
建議:
需求
mybatis默許支持的別名
別名 | 映照的類型 |
---|---|
_byte | byte |
_long | long |
_short | short |
_int | int |
_integer | int |
_double | double |
_float | float |
_boolean | boolean |
string | String |
byte | Byte |
long | Long |
short | Short |
int | Integer |
integer | Integer |
double | Double |
float | Float |
boolean | Boolean |
date | Date |
decimal | BigDecimal |
bigdecimal | BigDecimal |
單個別名定義
援用別名:
批量定義別名(經常使用)
<!-- 別名定義 -->
<typeAliases>
<!-- 針對單個別名定義
type:類型的路徑
alias:別名
-->
<!-- <typeAlias type="cn.itcast.mybatis.po.User" alias="user"/> -->
<!-- 批量別名定義
指定包名,mybatis自動掃描包中的po類,自動定義別名,別名就是類名(首字母大寫或小寫都可以)
-->
<package name="cn.itcast.mybatis.po"/>
</typeAliases>
類型處理器 | Java類型 | JDBC類型 |
---|---|---|
BooleanTypeHandler | Boolean,boolean | 任何兼容的布爾值 |
ByteTypeHandler | Byte,byte | 任何兼容的數字或字節類型 |
ShortTypeHandler | Short,short | 任何兼容的數字或短整型 |
IntegerTypeHandler | Integer,int | 任何兼容的數字和整型 |
LongTypeHandler | Long,long | 任何兼容的數字或長整型 |
FloatTypeHandler | Float,float | 任何兼容的數字或單精度浮點型 |
DoubleTypeHandler | Double,double | 任何兼容的數字或雙精度浮點型 |
BigDecimalTypeHandler | BigDecimal | 任何兼容的數字或10進制小數類型 |
StringTypeHandler | String | CHAR和VARCHAR類型 |
ClobTypeHandler | String | CLOB和LONGVARCHAR類型 |
NStringTypeHandler | String | NVARCHAR和NCHAR類型 |
NClobTypeHandler | String | NCLOB類型 |
ByteArrayTypeHandler | byte[] | 任何兼容的字節流類型 |
BlobTypeHandler | byte[] | BLOB和LONGVARBINARY類型 |
DateTypeHandler | Date(java.util) | TIMESTAMP類型 |
DateOnlyTypeHandler | Date(java.util) | DATE類型 |
TimeOnlyTypeHandler | Date(java.util) | TIME類型 |
SqlTimestampTypeHandler | Timestamp(java.sql) | TIMESTAMP類型 |
SqlDateTypeHandler | Date(java.sql) | DATE類型 |
SqlTimeTypeHandler | Time(java.sql) | TIME類型 |
ObjectTypeHandler | 任意 | 其他或未指定類型 |
EnumTypeHandler | Enumeration類型 | VARCHAR-任何兼容的字符串類型,作為代碼存儲(而不是索引)。 |
<mapper resource=" " />
使用相對類路徑的資源 <mapper resource="sqlmap/User.xml" />
使用完全限定路徑<mapper url=" " />
<mapper url="file:///D:\workspace_spingmvc\mybatis_01\config\sqlmap\User.xml" />
通過mapper接口加載單個mapper
<!-- 通過mapper接口加載單個映照文件需要遵守1些規范:mapper接口類名和mapper.xml映照文件名稱必須保持1致,且在1個package目錄中;并且要使用mapper代理方法-->
<mapper class="cn.itcast.mybatis.mapper.UserMapper"/>
<package name="cn.itcast.mybatis.mapper"/>
需求:
定義包裝類型pojo
mapper.java
測試代碼
#
中 id 和 username是hashmap的key。<!-- 傳遞<u>hashmap</u>綜合查詢用戶信息 -->
<select id="findUserByHashmap" parameterType="hashmap" resultType="user">
select * from user where id=#{id} and username like '%${username}%'
</select>
Public void testFindUserByHashmap()throws Exception{
//獲得session
SqlSession session = sqlSessionFactory.openSession();
//獲限mapper接口實例
UserMapper userMapper = session.getMapper(UserMapper.class);
//構造查詢條件Hashmap對象
HashMap<String, Object> map = new HashMap<String, Object>();
map.put("id", 1);
map.put("username", "管理員");
//傳遞Hashmap對象查詢用戶列表
List<User>list = userMapper.findUserByHashmap(map);
//關閉session
session.close();
}
使用resultType進行輸出映照,只有查詢出來的列名和pojo中的屬性名1致,該列才可以映照成功。
輸出簡單類型
需求
Usermapper.xml
Usermapper.java
測試代碼
小結
輸出pojo對象和pojo列表
在mapper.java指定的方法返回值類型不1樣:
List<Pojo>
生成的動態代理對象中是根據mapper方法的返回值類型肯定是調用selectOne(返回單個對象調用)還是selectList (返回集合對象調用)
mybatis中使用resultMap完成高級輸出結果映照。
resultMap使用方法
案例: 將下邊的sql使用User完成映照
SELECT id id_,username username_ FROM USER WHERE id=#{value}
<!-- 定義resultMap
將SELECT id id_,username username_ FROM USER 和User類中的屬性作1個映照關系
type:resultMap終究映照的java對象類型,可使用別名
id:對resultMap的唯1標識
-->
<resultMap type="user" id="userResultMap">
<!-- id表示查詢結果集中唯1標識
column:查詢出來的列名
property:type指定的pojo類型中的屬性名
終究resultMap對column和property作1個映照關系 (對應關系)
-->
<id column="id_" property="id"/>
<!--
result:對普通名映照定義
column:查詢出來的列名
property:type指定的pojo類型中的屬性名
終究resultMap對column和property作1個映照關系 (對應關系)
-->
<result column="username_" property="username"/>
</resultMap>
<!-- 使用resultMap進行輸出映照
resultMap:指定定義的resultMap的id,如果這個resultMap在其它的mapper文件,前邊需要加namespace
-->
<select id="findUserByIdResultMap" parameterType="int" resultMap="userResultMap">
SELECT id id_,username username_ FROM USER WHERE id=#{value}
</select>
mapper.java
測試
@Test
public void testFindUserByIdResultMap() throws Exception {
SqlSession sqlSession = sqlSessionFactory.openSession();
//創建UserMapper對象,mybatis自動生成mapper代理對象
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
//調用userMapper的方法
User user = userMapper.findUserByIdResultMap(1);
System.out.println(user);
}
甚么是動態sql
需求
mapper.xml
需求
定義sql片斷,在UserMapper.xml頂部
向sql傳遞數組或List,mybatis使用foreach解析
需求
//兩種方法:
SELECT * FROM USER WHERE id=1 OR id=10 OR id=16
SELECT * FROM USER WHERE id IN(1,10,16)
List<Integer>
ids傳入多個id <sql id="query_user_where">
<if test="userCustom!=null">
<if test="userCustom.sex!=null and userCustom.sex!=''">
and user.sex = #{userCustom.sex}
</if>
<if test="userCustom.username!=null and userCustom.username!=''">
and user.username LIKE '%${userCustom.username}%'
</if>
<if test="ids!=null">
<!-- 使用 foreach遍歷傳入ids
collection:指定輸入 對象中集合屬性
item:每一個遍歷生成對象中
open:開始遍用時拼接的串
close:結束遍用時拼接的串
separator:遍歷的兩個對象中需要拼接的串
-->
<!-- 使用實現下邊的sql拼接:
AND (id=1 OR id=10 OR id=16)
-->
<foreach collection="ids" item="user_id" open="AND (" close=")" separator="or">
<!-- 每一個遍歷需要拼接的串 -->
id=#{user_id}
</foreach>
<!-- 實現 “ and id IN(1,10,16)”拼接 -->
<!-- <foreach collection="ids" item="user_id" open="and id IN(" close=")" separator=",">
每一個遍歷需要拼接的串
#{user_id}
</foreach> -->
</if>
</if>
</sql>
測試代碼
在UserQueryVo中:
public class UserQueryVo {
//傳入多個id
private List<Integer> ids;
public List<Integer> getIds() {
return ids;
}
public void setIds(List<Integer> ids) {
this.ids = ids;
}
}
<!-- 實現 “ and id IN(1,10,16)”拼接 -->
<!-- <foreach collection="ids" item="user_id" open="and id IN(" close=")" separator=",">
每一個遍歷需要拼接的串
#{user_id}
</foreach> -->