Mybatis--進階
MyBatis--2.進階
MyBatis的Dao層實現
傳統開發方式
Dao中的接口類:
public interface UserMapper {
public List<User> findAll() throws IOException;
}
Dao中接口的實現類:
public class UserMapperImpl implements UserMapper {
@Override
public List<User> findAll() throws IOException {
InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
SqlSessionFactory sqlSessionFactory= new SqlSessionFactoryBuilder().build(resourceAsStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
List<User> userList = sqlSession.selectList("userMapper.findAll");
return userList;
}
}
再在其他類需要進行數據庫操作時調用UserMapperImpl的findAll方法
代理開發方式

編寫接口:

測試代理:

parameterType類型就按照正常類型,不按照泛型
至于不同的返回類型resulttype如何寫需要按照泛型,參考:
mybatis的resultType_mybatis resulttype_beidaol的博客-CSDN博客
MyBatis映射文件深入
動態sql語句
動態sql字面意思就是傳遞參數不同sql語句動態變化
動態sql語句的重要表情發標簽
-
if
下面#{}用到的是傳入參數的屬性
<select id="findAll" resultType="com.xxx.User" parameterType="com.xxx.User"> select * from user where username=#{username} and password=#{password} -- 判斷如果id!=0執行后面的 <if test="id!=0"> and id=#{id} </if> </select> -
choose(when,otherwise)
-
trim(where,set)
<select id="findAll" resultType="com.xxx.User" parameterType="com.xxx.User"> select * from user -- 和之前的where相同 <where> -- 判斷如果id!=0執行后面的 <if test="id!=0"> and id=#{id} </if> <if test="password!=null"> and password=#{password} </if> </where> </select> -
foreach
<select id="findAll" resultType="com.xxx.User" parameterType="list">
select * from user
<where>
-- 本處傳遞的是一個list,如果是數組參數collection為array,open表示以什么開始,
-- close表示以什么結束,item是變量負責接收集合的每一個
-- separator是封裝符,通過它拼接使用的item;另外sql語句in和or類似
<foreach collection="list" open="id in(" close=")" item="id" separator=","></foreach>
-- 這就是item
#{id}
</where>
</select>
sql片段的抽取
<!-- 抽取-->
<sql id="selectUser">select * from user </sql>
<!-- 引入-->
<select id="das">
<include refid="selectUser"></include>
</select>
MyBatis核心配置文件深入
typeHandlers標簽
默認的類型轉換器

當默認的轉換器不符合需求時,我們使用該標簽自定義轉換器

開發步驟:
-
定義轉換繼承類BaseTypeHandler
-
覆蓋四個未實現的方法,其中setNonNullParameter為java程序設置數據到數據庫的回調方法,getNullableResult為查詢時mysql的字符串類型轉換為java的Type類型方法
public class DateHandler extends BaseTypeHandler<Date> { // 將java類型轉換成數據庫需要的類型 @Override public void setNonNullParameter(PreparedStatement preparedStatement, int i, Date date, JdbcType jdbcType) throws SQLException { long time = date.getTime(); preparedStatement.setLong(i,time); } // 數據庫類型轉java類型 //String參數是要轉換的字段名稱 //resultset是查詢的結果集 @Override public Date getNullableResult(ResultSet resultSet, String s) throws SQLException { // 獲得結果集需要的數據(long)轉換為date類型返回 long aLong = resultSet.getLong(s); Date date = new Date(aLong); return date; } // 數據庫類型轉java類型 @Override public Date getNullableResult(ResultSet resultSet, int i) throws SQLException { long aLong = resultSet.getLong(i); Date date = new Date(aLong); return date; } // 數據庫類型轉java類型 @Override public Date getNullableResult(CallableStatement callableStatement, int i) throws SQLException { long aLong = callableStatement.getLong(i);; Date date = new Date(aLong); return date; } } -
在MyBatis核心配置文件中進行注冊
<!-- 自定義類型處理器--> <typeHandlers> <typeHandler handler="com.xxx.handler.DateHandler"></typeHandler> </typeHandlers> -
測試轉換是否正確
plugins標簽

開發步驟:
-
導入PageHelper的坐標
<!-- 導入通用PageHlper坐標--> <dependency> <groupId>com.github.pagehelper</groupId> <artifactId>pagehelper</artifactId> <version>3.7.5</version> </dependency> <dependency> <groupId>com.github.jsqlparser</groupId> <artifactId>jsqlparser</artifactId> <version>0.9.1</version> </dependency> -
再mybatis核心配置文件中配置PageHelper插件
<!-- 配置分頁助手插件--> <plugins> <plugin interceptor="com.github.pagehelper.PageHelper"> <!-- 指定參數,指定數據庫方言--> <property name="dialect" value="mysql"/> </plugin> </plugins> -
測試分頁數據獲取
public void test1() throws IOException { // 獲取配置文件Resources是ibatis包下的 InputStream resourceAsFile = Resources.getResourceAsStream("sqlMapConfig.xml"); // 獲得session工廠對象 SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsFile); // 獲得session會話對象 SqlSession sqlSession = sqlSessionFactory.openSession(); UserMapper mapper = sqlSession.getMapper(UserMapper.class); // 設置分頁相關參數 PageHelper.startPage(1,2); List<User> userList = mapper.findAll(); for (User user : userList) { System.out.println(user); } // 獲得與分頁相關的參數 PageInfo<User> pageInfo = new PageInfo<User>(userList); System.out.println("當前頁:"+pageInfo.getPageNum()); System.out.println("每頁條數:"+pageInfo.getPageSize()); System.out.println("總條數:"+pageInfo.getTotal()); System.out.println("總頁數:"+pageInfo.getPages()); System.out.println("上一頁:"+pageInfo.getPrePage()); System.out.println("下一頁:"+pageInfo.getNextPage()); System.out.println("是否是第一個:"+pageInfo.isIsFirstPage()); System.out.println("是否是最后一個:"+pageInfo.isIsLastPage()); // 釋放資源 sqlSession.close(); }
結果:

MyBatis的多表操作
一對一查詢

第一種配置方式:
orders類:
public class Order {
private int id;
private Date ordertime;
private double total;
//當前訂單屬于那個用戶
private User user;
其他get和set方法。。。
}
映射文件中:
<?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命名空間-->
<mapper namespace="com.xxx.Mapper.OrderMapper">
<resultMap id="orderMap" type="com.xxx.Order">
<!-- 手動指定字段與實體屬性的映射關系
column:數據庫字段名稱
property:實體屬性名
id:是主鍵-->
<id column="oid" property="id"></id>
<result column="ordertime" property="ordertime"></result>
<result column="total" property="total"></result>
<result column="uid" property="user.id"></result>
<result column="username" property="user.username"></result>
<result column="password" property="user.password"></result>
<result column="birthday" property="user.birthday"></result>
</resultMap>
<select id="findAll" resultMap="orderMap">
select *,o.id oid from orders o,user u where o.uid=u.id
</select>
</mapper>
另外一種映射文件寫法:
<resultMap id="orderMap" type="com.xxx.Order">
<!-- 手動指定字段與實體屬性的映射關系
column:數據庫字段名稱
property:實體屬性名
id:是主鍵-->
<id column="oid" property="id"></id>
<result column="ordertime" property="ordertime"></result>
<result column="total" property="total"></result>
<!-- 兩個參數:前者是order中的user屬性,后者是屬性類型-->
<association property="user" javaType="com.xxx.User">
<id column="uid" property="id"></id>
<result column="username" property="username"></result>
<result column="password" property="password"></result>
<result column="birthday" property="birthday"></result>
</association>
一對多

<resultMap id="userMap" type="user">
<id column="uid" property="id"></id>
<result column="username" property="username"></result>
<result column="password" property="password"></result>
<!-- 配置集合信息
property類集合屬性名稱
ofType當前集合的數據類型-->
<collection property="orderList" ofType="order">
<id column="oid" property="id"></id>
<result column="ordertime" property="ordertime"></result>
</collection>
</resultMap>
其他和一對一查詢類似
多對多

<resultMap id="userRoleMap" type="user">
<id column="userId" property="id"></id>
<result column="username" property="username"></result>
<!-- user內部的roleList信息-->
<collection property="roleList" ofType="role">
<id column="role" property="id"></id>
<result column="roleName" property="roleName"></result>
</collection>
</resultMap>
<select id="findUserAndRoleAll" resultMap="userRoleMap">
select * from user u, sys_user_role ur,sys_role r where u.id=ur.userId and ur.roleId = r.id
</select>
自定義別名
核心配置文件

浙公網安備 33010602011771號