文檔版本 | 開(kāi)發(fā)工具 | 測(cè)試平臺(tái) | 工程名字 | 日期 | 作者 | 備注 |
---|---|---|---|---|---|---|
V1.0 | 2016.06.26 | lutianfei | none |
SqlSessionFactoryBuilder
SqlSessionFactory
SqlSession
SqlSession履行進(jìn)程以下:
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的實(shí)現(xiàn)類即DefaultSqlSession,此對(duì)象中對(duì)操作數(shù)據(jù)庫(kù)實(shí)質(zhì)上用的是Executor
SqlSession session = sqlSessionFactory.openSession();
try {
// do work
} finally {
session.close();
}
思路
dao接口
public class UserDaoImpl implements UserDao {
// 需要向dao實(shí)現(xiàn)類中注入SqlSessionFactory
// 這里通過(guò)構(gòu)造方法注入
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);
// 提交事務(wù)
sqlSession.commit();
// 釋放資源
sqlSession.close();
}
@Override
public void deleteUser(int id) throws Exception {
SqlSession sqlSession = sqlSessionFactory.openSession();
//履行插入操作
sqlSession.delete("test.deleteUser", id);
// 提交事務(wù)
sqlSession.commit();
// 釋放資源
sqlSession.close();
}
public class UserDaoImplTest {
private SqlSessionFactory sqlSessionFactory;
// 此方法是在履行testFindUserById之前履行
@Before
public void setUp() throws Exception {
// 創(chuàng)建sqlSessionFactory
// mybatis配置文件
String resource = "SqlMapConfig.xml";
// 得到配置文件流
InputStream inputStream = Resources.getResourceAsStream(resource);
// 創(chuàng)建會(huì)話工廠,傳入mybatis的配置文件信息
sqlSessionFactory = new SqlSessionFactoryBuilder()
.build(inputStream);
}
@Test
public void testFindUserById() throws Exception {
// 創(chuàng)建UserDao的對(duì)象
UserDao userDao = new UserDaoImpl(sqlSessionFactory);
// 調(diào)用UserDao的方法
User user = userDao.findUserById(1);
System.out.println(user);
}
}
程序員編寫(xiě)mapper接口需要遵守1些開(kāi)發(fā)規(guī)范,這樣Mybatis可以自動(dòng)生成mapper接口實(shí)現(xiàn)類代理對(duì)象。
開(kāi)發(fā)規(guī)范:
于mapper接口地址
User user = sqlSession.selectOne("test.findUserById", id);
sqlSession.insert("test.insertUser", user);
public interface UserMapper {
//用戶信息綜合查詢
public List<UserCustom> findUserList(UserQueryVo userQueryVo) throws Exception;
//用戶信息綜合查詢總數(shù)
public int findUserCount(UserQueryVo userQueryVo) throws Exception;
//根據(jù)id查詢用戶信息
public User findUserById(int id) throws Exception;
//根據(jù)id查詢用戶信息,使用resultMap輸出
public User findUserByIdResultMap(int id) throws Exception;
//根據(jù)用戶名列查詢用戶列表
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自動(dòng)掃描包下邊所有mapper接口進(jìn)行加載,遵守1些規(guī)范:需要將mapper接口類名和mapper.xml映照文件名稱保持1致,且在1個(gè)目錄中
上邊規(guī)范的條件是:使用的是mapper代理方法
-->
<package name="cn.itcast.mybatis.mapper"/>
</mappers>
@Test
public void testFindUserById() throws Exception {
SqlSession sqlSession = sqlSessionFactory.openSession();
//創(chuàng)建UserMapper對(duì)象,mybatis自動(dòng)生成mapper代理對(duì)象
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
//調(diào)用userMapper的方法
User user = userMapper.findUserById(1);
System.out.println(user);
}
需求:將數(shù)據(jù)庫(kù)連接參數(shù)單獨(dú)配置在db.properties中,只需要在SqlMapConfig.xml中加載db.properties的屬性值。
在SqlMapConfig.xml中就不需要對(duì)數(shù)據(jù)庫(kù)連接參數(shù)硬編碼。
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事務(wù)管理,事務(wù)控制由mybatis-->
<transactionManager type="JDBC" />
<!-- 數(shù)據(jù)庫(kù)連接池,由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>
因此,通過(guò)parameterType
傳遞的屬性具有最高優(yōu)先級(jí),resource
或 url
加載的屬性次之,最低優(yōu)先級(jí)的是 properties
元素體內(nèi)定義的屬性。
建議:
需求
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 |
單個(gè)別名定義
援用別名:
批量定義別名(經(jīng)常使用)
<!-- 別名定義 -->
<typeAliases>
<!-- 針對(duì)單個(gè)別名定義
type:類型的路徑
alias:別名
-->
<!-- <typeAlias type="cn.itcast.mybatis.po.User" alias="user"/> -->
<!-- 批量別名定義
指定包名,mybatis自動(dòng)掃描包中的po類,自動(dòng)定義別名,別名就是類名(首字母大寫(xiě)或小寫(xiě)都可以)
-->
<package name="cn.itcast.mybatis.po"/>
</typeAliases>
類型處理器 | Java類型 | JDBC類型 |
---|---|---|
BooleanTypeHandler | Boolean,boolean | 任何兼容的布爾值 |
ByteTypeHandler | Byte,byte | 任何兼容的數(shù)字或字節(jié)類型 |
ShortTypeHandler | Short,short | 任何兼容的數(shù)字或短整型 |
IntegerTypeHandler | Integer,int | 任何兼容的數(shù)字和整型 |
LongTypeHandler | Long,long | 任何兼容的數(shù)字或長(zhǎng)整型 |
FloatTypeHandler | Float,float | 任何兼容的數(shù)字或單精度浮點(diǎn)型 |
DoubleTypeHandler | Double,double | 任何兼容的數(shù)字或雙精度浮點(diǎn)型 |
BigDecimalTypeHandler | BigDecimal | 任何兼容的數(shù)字或10進(jìn)制小數(shù)類型 |
StringTypeHandler | String | CHAR和VARCHAR類型 |
ClobTypeHandler | String | CLOB和LONGVARCHAR類型 |
NStringTypeHandler | String | NVARCHAR和NCHAR類型 |
NClobTypeHandler | String | NCLOB類型 |
ByteArrayTypeHandler | byte[] | 任何兼容的字節(jié)流類型 |
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-任何兼容的字符串類型,作為代碼存儲(chǔ)(而不是索引)。 |
<mapper resource=" " />
使用相對(duì)類路徑的資源 <mapper resource="sqlmap/User.xml" />
使用完全限定路徑<mapper url=" " />
<mapper url="file:///D:\workspace_spingmvc\mybatis_01\config\sqlmap\User.xml" />
通過(guò)mapper接口加載單個(gè)mapper
<!-- 通過(guò)mapper接口加載單個(gè)映照文件需要遵守1些規(guī)范:mapper接口類名和mapper.xml映照文件名稱必須保持1致,且在1個(gè)package目錄中;并且要使用mapper代理方法-->
<mapper class="cn.itcast.mybatis.mapper.UserMapper"/>
<package name="cn.itcast.mybatis.mapper"/>
需求:
定義包裝類型pojo
mapper.java
測(cè)試代碼
#
中 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接口實(shí)例
UserMapper userMapper = session.getMapper(UserMapper.class);
//構(gòu)造查詢條件Hashmap對(duì)象
HashMap<String, Object> map = new HashMap<String, Object>();
map.put("id", 1);
map.put("username", "管理員");
//傳遞Hashmap對(duì)象查詢用戶列表
List<User>list = userMapper.findUserByHashmap(map);
//關(guān)閉session
session.close();
}
使用resultType進(jìn)行輸出映照,只有查詢出來(lái)的列名和pojo中的屬性名1致,該列才可以映照成功。
輸出簡(jiǎn)單類型
需求
Usermapper.xml
Usermapper.java
測(cè)試代碼
小結(jié)
輸出pojo對(duì)象和pojo列表
在mapper.java指定的方法返回值類型不1樣:
List<Pojo>
生成的動(dòng)態(tài)代理對(duì)象中是根據(jù)mapper方法的返回值類型肯定是調(diào)用selectOne(返回單個(gè)對(duì)象調(diào)用)還是selectList (返回集合對(duì)象調(diào)用)
mybatis中使用resultMap完成高級(jí)輸出結(jié)果映照。
resultMap使用方法
案例: 將下邊的sql使用User完成映照
SELECT id id_,username username_ FROM USER WHERE id=#{value}
<!-- 定義resultMap
將SELECT id id_,username username_ FROM USER 和User類中的屬性作1個(gè)映照關(guān)系
type:resultMap終究映照的java對(duì)象類型,可使用別名
id:對(duì)resultMap的唯1標(biāo)識(shí)
-->
<resultMap type="user" id="userResultMap">
<!-- id表示查詢結(jié)果集中唯1標(biāo)識(shí)
column:查詢出來(lái)的列名
property:type指定的pojo類型中的屬性名
終究resultMap對(duì)column和property作1個(gè)映照關(guān)系 (對(duì)應(yīng)關(guān)系)
-->
<id column="id_" property="id"/>
<!--
result:對(duì)普通名映照定義
column:查詢出來(lái)的列名
property:type指定的pojo類型中的屬性名
終究resultMap對(duì)column和property作1個(gè)映照關(guān)系 (對(duì)應(yīng)關(guān)系)
-->
<result column="username_" property="username"/>
</resultMap>
<!-- 使用resultMap進(jìn)行輸出映照
resultMap:指定定義的resultMap的id,如果這個(gè)resultMap在其它的mapper文件,前邊需要加namespace
-->
<select id="findUserByIdResultMap" parameterType="int" resultMap="userResultMap">
SELECT id id_,username username_ FROM USER WHERE id=#{value}
</select>
mapper.java
測(cè)試
@Test
public void testFindUserByIdResultMap() throws Exception {
SqlSession sqlSession = sqlSessionFactory.openSession();
//創(chuàng)建UserMapper對(duì)象,mybatis自動(dòng)生成mapper代理對(duì)象
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
//調(diào)用userMapper的方法
User user = userMapper.findUserByIdResultMap(1);
System.out.println(user);
}
甚么是動(dòng)態(tài)sql
需求
mapper.xml
需求
定義sql片斷,在UserMapper.xml頂部
向sql傳遞數(shù)組或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傳入多個(gè)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:指定輸入 對(duì)象中集合屬性
item:每一個(gè)遍歷生成對(duì)象中
open:開(kāi)始遍用時(shí)拼接的串
close:結(jié)束遍用時(shí)拼接的串
separator:遍歷的兩個(gè)對(duì)象中需要拼接的串
-->
<!-- 使用實(shí)現(xiàn)下邊的sql拼接:
AND (id=1 OR id=10 OR id=16)
-->
<foreach collection="ids" item="user_id" open="AND (" close=")" separator="or">
<!-- 每一個(gè)遍歷需要拼接的串 -->
id=#{user_id}
</foreach>
<!-- 實(shí)現(xiàn) “ and id IN(1,10,16)”拼接 -->
<!-- <foreach collection="ids" item="user_id" open="and id IN(" close=")" separator=",">
每一個(gè)遍歷需要拼接的串
#{user_id}
</foreach> -->
</if>
</if>
</sql>
測(cè)試代碼
在UserQueryVo中:
public class UserQueryVo {
//傳入多個(gè)id
private List<Integer> ids;
public List<Integer> getIds() {
return ids;
}
public void setIds(List<Integer> ids) {
this.ids = ids;
}
}
<!-- 實(shí)現(xiàn) “ and id IN(1,10,16)”拼接 -->
<!-- <foreach collection="ids" item="user_id" open="and id IN(" close=")" separator=",">
每一個(gè)遍歷需要拼接的串
#{user_id}
</foreach> -->