mybatis框架的總結(二)
Mapper動態代理方式實現dao:
Mapper介面開發方法只需要程式設計師編寫Mapper介面(相當於Dao介面),由Mybatis框架根據介面定義建立介面的動態代理物件,代理物件的方法體同上邊Dao介面實現類方法。
Mapper介面開發需要遵循以下規範:
- Mapper.xml檔案中的namespace與mapper介面的類路徑相同。
- Mapper介面方法名和Mapper.xml中定義的每個statement的id相同
- Mapper介面方法的輸入引數型別和mapper.xml中定義的每個sql 的parameterType的型別相同
- Mapper介面方法的輸出引數型別和mapper.xml中定義的每個sql的resultType的型別相同
-
Mapper.xml(對映檔案)
定義mapper對映檔案UserMapper.xml,需要修改namespace的值為 UserMapper介面路徑。將UserMapper.xml放在classpath 下和mapper處在同一目錄 下。
<?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="cn.itcast.mybatis.mapper.UserMapper"> <!-- 根據id獲取使用者資訊 --> <select id="findUserById" parameterType="int" resultType="cn.itcast.mybatis.po.User"> select * from user where id = #{id} </select> <!-- 自定義條件查詢使用者列表 --> <select id="findUserByUsername" parameterType="java.lang.String" resultType="cn.itcast.mybatis.po.User"> select * from user where username like '%${value}%' </select> <!-- 新增使用者 --> <insert id="insertUser" parameterType="cn.itcast.mybatis.po.User"> <selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer"> select LAST_INSERT_ID() </selectKey> insert into user(username,birthday,sex,address) values(#{username},#{birthday},#{sex},#{address}) </insert> </mapper>
2、mapper.java介面
介面定義有如下特點:
- Mapper介面方法名和Mapper.xml中定義的statement的id相同
- Mapper介面方法的輸入引數型別和mapper.xml中定義的statement的parameterType的型別相同
- Mapper介面方法的輸出引數型別和mapper.xml中定義的statement的resultType的型別相同
/**
* 使用者管理mapper
*/
Public interface UserMapper {
//根據使用者id查詢使用者資訊
public User findUserById(int id) throws Exception;
//查詢使用者列表
public List<User> findUserByUsername(String username) throws Exception;
//新增使用者資訊
public void insertUser(User user)throws Exception;
}
3、載入UserMapper.xml檔案
修改SqlMapConfig.xml檔案:
<!-- 載入對映檔案 -->
<mappers>
<mapper resource="mapper/UserMapper.xml"/>
</mappers>
3、測試
Public class UserMapperTest extends TestCase {
private SqlSessionFactory sqlSessionFactory;
protected void setUp() throws Exception {
//mybatis配置檔案
String resource = "sqlMapConfig.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
//使用SqlSessionFactoryBuilder建立sessionFactory
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
}
Public void testFindUserById() throws Exception {
//獲取session
SqlSession session = sqlSessionFactory.openSession();
//獲取mapper介面的代理物件
UserMapper userMapper = session.getMapper(UserMapper.class);
//呼叫代理物件方法
User user = userMapper.findUserById(1);
System.out.println(user);
//關閉session
session.close();
}
@Test
public void testFindUserByUsername() throws Exception {
SqlSession sqlSession = sqlSessionFactory.openSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
List<User> list = userMapper.findUserByUsername("張");
System.out.println(list.size());
}
Public void testInsertUser() throws Exception {
//獲取session
SqlSession session = sqlSessionFactory.openSession();
//獲取mapper介面的代理物件
UserMapper userMapper = session.getMapper(UserMapper.class);
//要新增的資料
User user = new User();
user.setUsername("張三");
user.setBirthday(new Date());
user.setSex("1");
user.setAddress("北京市");
//通過mapper介面新增使用者
userMapper.insertUser(user);
//提交
session.commit();
//關閉session
session.close();
}
}
4、自定義別名:
在SqlMapConfig.xml中配置:
<typeAliases>
<!-- 單個別名定義 -->
<typeAlias alias="user" type="cn.itcast.mybatis.po.User"/>
<!-- 批量別名定義,掃描整個包下的類,別名為類名(首字母大寫或小寫都可以) -->
<package name="cn.itcast.mybatis.po"/>
<package name="其它包"/>
</typeAliases>
5、<mapper resource=" " />
使用相對於類路徑的資源
如:<mapper resource="sqlmap/User.xml" />
6、<mapper class=" " />
使用mapper介面類路徑
如:<mapper class="cn.itcast.mybatis.mapper.UserMapper"/>
注意:此種方法要求mapper介面名稱和mapper對映檔名稱相同,且放在同一個目錄中
7、<package name=""/>
註冊指定包下的所有mapper介面
如:<package name="cn.itcast.mybatis.mapper"/>
注意:此種方法要求mapper介面名稱和mapper對映檔名稱相同,且放在同一個目錄中。
8、parameterType(輸入型別)
(1)、 #{}與${}
#{}實現的是向prepareStatement中的預處理語句中設定引數值,sql語句中#{}表示一個佔位符即?。
<!-- 根據id查詢使用者資訊 -->
<select id="findUserById" parameterType="int" resultType="user">
select * from user where id = #{id}
</select>
使用佔位符#{}可以有效防止sql注入,在使用時不需要關心引數值的型別,mybatis會自動進行java型別和jdbc型別的轉換。#{}可以接收簡單型別值或pojo屬性值,如果parameterType傳輸單個簡單型別值,#{}括號中可以是value或其它名稱。
${}和#{}不同,通過${}可以將parameterType 傳入的內容拼接在sql中且不進行jdbc型別轉換, ${}可以接收簡單型別值或pojo屬性值,如果parameterType傳輸單個簡單型別值,${}括號中只能是value。使用${}不能防止sql注入,但是有時用${}會非常方便,如下的例子:
<!-- 根據名稱模糊查詢使用者資訊 -->
<select id="selectUserByName" parameterType="string" resultType="user">
select * from user where username like '%${value}%'
</select>
9、動態sql(重點)
通過mybatis提供的各種標籤方法實現動態拼接sql。
select * from user id=#{id} and username like '%${username}%'
(1)、if
<select id="findUserList" parameterType="user" resultType="user">
select * from user
where 1=1
<if test="id!=null and id!=''">
and id=#{id}
</if>
<if test="username!=null and username!=''">
and username like '%${username}%'
</if>
</select>
(2)、Where
<select id="findUserList" parameterType="user" resultType="user">
select * from user
<where>
<if test="id!=null and id!=''">
and id=#{id}
</if>
<if test="username!=null and username!=''">
and username like '%${username}%'
</if>
</where>
</select>
<where />可以自動處理第一個and。
(3)foreach
向sql傳遞陣列或List,mybatis使用foreach解析
(4)、sql片段
Sql中可將重複的sql提取出來,使用時用include引用即可,最終達到sql重用的目的,如下:
<select id="findUserList" parameterType="user" resultType="user">
select * from user
<where>
<if test="id!=null and id!=''">
and id=#{id}
</if>
<if test="username!=null and username!=''">
and username like '%${username}%'
</if>
</where>
</select>
將where條件抽取出來:
<sql id="query_user_where">
<if test="id!=null and id!=''">
and id=#{id}
</if>
<if test="username!=null and username!=''">
and username like '%${username}%'
</if>
</sql>
使用include引用:
<select id="findUserList" parameterType="user" resultType="user">
select * from user
<where>
<include refid="query_user_where"/>
</where>
</select>
注意:如果引用其它mapper.xml的sql片段,則在引用時需要加上namespace,如下:<include refid="namespace.sql片段”/>