使用要求:
1、持久層接口和持久層接口的映射配置必須在相同的包下
2、持久層映射配置中mapper标簽的namespace屬性取值必須是持久層接口的全限定類名
3、sql語句的配置标簽,,,的id屬性必須和持久層接口的方法名相同
根據ID查詢
1、 在持久層接口中添加findById方法
/**
* 根據id查詢使用者資訊
* @param userId
* @return
*/
User findById(Integer userId);
2、在使用者的映射配置檔案中配置
<!-- 根據id查詢使用者 -->
<select id="findById" parameterType="INT" resultType="com.itheima.domain.User">
select * from user where id = #{uid}
</select>
resultType屬性:用于指定結果集的類型
parameterType屬性:用于指定傳入參數的類型
sql語句中使用#{}:代表占位符,相當于jdbc中的?,用于執行語句時替換實際的資料,具體的資料由#{}裡面的内容決定,由于資料類型是基本類型,#{}内可以随意寫。
3、在測試類添加測試
public class MybatisTest {
private InputStream in;
private SqlSessionFactory factory;
private SqlSession session;
private IUserDao userDao;
@Before//用于在測試方法執行之前執行
public void init()throws Exception{
//1.讀取配置檔案,生成位元組輸入流
in = Resources.getResourceAsStream("SqlMapConfig.xml");
//2. 建立建構者對象
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
//3.建立SqlSessionFactory對象
factory = builder.build(in);
//4.建立SqlSession對象
session = factory.openSession();
//5.建立Dao的代理對象
userDao = session.getMapper(IUserDao.class);
}
@After//用于在測試方法執行之後執行
public void destroy()throws Exception{
session.commit();
//7.釋放資源
session.close();
in.close();
}'
@Test
public void testFindOne(){
//5.執行查詢一個方法
User user = userDao.findById(41);
System.out.println(user);
}
儲存操作
1、在持久層接口中添加新增方法
/**
* 儲存使用者
* @param user
*/
void saveUser(User user);
2、在使用者的映射配置檔案中配置
<!-- 儲存使用者 -->
<insert id="saveUser" parameterType="com.itheima.domain.User">
insert into user(username,address,sex,birthday) values(#{username},#{address},#{sex},#{birthday});
</insert>
parameterType屬性:代表參數的類型,因為我們要傳入一個類的對象,是以類型就寫類的全名稱、
#{}内容:由于儲存方法的參數是一個User對象,此處要寫User對象中的屬性名稱,使用ognl表達式
ognl(object graphic navigation language)表達式:對象圖導航語言。按照一定的文法格式來擷取資料,#{對象.對象}
#{user.username}先找到user對象,然後在user對象中找到username屬性,并調用getUsername()方法把值取出來。但是我們在parameterType屬性上制定了實體類名稱,是以可以省略user直接寫username.
3、添加測試類中的測試方法
/**
* 測試儲存操作
*/
@Test
public void testSave(){
User user = new User();
user.setUserName("modify User property");
user.setUserAddress("北京市順義區");
user.setUserSex("男");
user.setUserBirthday(new Date());
System.out.println("儲存操作之前:"+user);
//5.執行儲存方法
userDao.saveUser(user);
System.out.println("儲存操作之後:"+user);
}
此時mysql資料庫中沒有任何添加紀錄,因為在實作增删改時一定要去控制事務的送出,在myBatis中使用sqlSession.commit()
@After//用于在測試方法執行之後執行
public void destroy()throws Exception{
//送出事務
sqlSession.commit();
//6.釋放資源
sqlSession.close();
in.close();
}
4、新增使用者Id的傳回值
新增使用者後,同時還要傳回目前新增使用者的id值,因為id是由資料庫的自動增長來實作的,是以就相當于我們要在新增後将自動增長的auto_increment的值傳回。
<!-- 儲存使用者 -->
<insert id="saveUser" parameterType="com.itheima.domain.User">
<!-- 配置插入操作後,擷取插入資料的id -->
<selectKey keyProperty="id" keyColumn="id" resultType="int" order="AFTER">
select last_insert_id();
</selectKey>
insert into user(username,address,sex,birthday)values(#{username},#{address},#{sex},#{birthday});
</insert>
使用者更新
1、在持久層接口中添加更新方法
/**
* 更新使用者
* @param user
*/
void updateUser(User user);
2、在使用者的映射配置檔案中配置
<!-- 更新使用者 -->
<update id="updateUser" parameterType="com.itheima.domain.User">
update user set username=#{username},address=#{address},sex=#{sex},birthday=#{birthday} where id=#{id}
</update>
3、加入更新的測試方法
/**
* 測試更新操作
*/
@Test
public void testUpdate(){
User user = new User();
user.setId(50);
user.setUsername("userdaoimpl update user");
user.setAddress("北京市順義區");
user.setSex("女");
user.setBirthday(new Date());
//執行更新方法
userDao.updateUser(user);
}
使用者删除
1、在持久層接口中添加删除方法
/**
* 根據Id删除使用者
* @param userId
*/
void deleteUser(Integer userId);
2、在使用者的映射配置檔案中配置
<!-- 删除使用者-->
<delete id="deleteUser" parameterType="java.lang.Integer">
delete from user where id = #{uid}
</delete>
3、加入删除的測試方法
/**
* 測試删除操作
*/
@Test
public void testDelete(){
//5.執行删除方法
userDao.deleteUser(54);
}
使用者模糊查詢
在持久層接口中添加模糊查詢方法
/**
* 根據名稱模糊查詢使用者資訊
* @param username
* @return
*/
List<User> findByName(String username);
在使用者的映射配置檔案中配置
<!-- 根據名稱模糊查詢 -->
<select id="findByName" parameterType="string" resultType="com.itheima.domain.User">
select * from user where username like #{name}
</select>
加入模糊查詢的測試方法
/**
* 測試模糊查詢操作
*/
@Test
public void testFindByName(){
//5.執行查詢一個方法
List<User> users = userDao.findByName("%王%");
for(User user : users){
System.out.println(user);
}
}
配置檔案中沒有加入%來作為模糊查詢的條件,是以在傳入字元串實參時,就需要給定模糊查詢的表示%,配置檔案中的#{username}也隻是一個占位符,是以sql語句顯示為?
模糊查詢的另一種配置方式
1、修改sql語句的配置
<!-- 根據名稱模糊查詢 -->
<select id="findByName" parameterType="string" resultType="com.itheima.domain.User">
select * from user where username like **'%${value}%'**
</select>
将原來的#{}占位符,改為。如果使用模糊查詢的寫法,
${value}
的寫法時固定的
${value}
2、測試
/**
* 測試模糊查詢操作
*/
@Test
public void testFindByName(){
//5.執行查詢一個方法
List<User> users = userDao.findByName("王");
for(User user : users){
System.out.println(user);
}
}
這種查詢方式不需要加入模糊查詢的比對符$
#{}與${}的差別
#{}表示一個占位符号
- 通過#{}可以實作 preparedStatement 向占位符中設定值,自動進行 java 類型和 jdbc 類型轉換, #{}可以有效防止 sql 注入。 #{}可以接收簡單類型值或 pojo 屬性值。 如果 parameterType 傳輸單個簡單類 型值,#{}括号中可以是 value 或其它名稱。
${}表示拼接sql串
- 通過${}可以将 parameterType 傳入的内容拼接在 sql中且不進行 jdbc 類型轉換, 可 以 接 收 簡 單 類 型 值 或 p o j o 屬 性 值 , 如 果 p a r a m e t e r T y p e 傳 輸 單 個 簡 單 類 型 值 , {}可以接收簡 單類型值或 pojo 屬性值,如果 parameterType 傳輸單個簡單類型值, 可以接收簡單類型值或pojo屬性值,如果parameterType傳輸單個簡單類型值,{}括号中隻能是 value。
MyBatis和JDBC的差別
- 1.資料庫連結建立、釋放頻繁造成系統資源浪費進而影響系統性能,如果使用資料庫連結池可解決此問題。 解決: 在 SqlMapConfig.xml 中配置資料連結池,使用連接配接池管理資料庫連結。
- 2.Sql 語句寫在代碼中造成代碼不易維護,實際應用 sql 變化的可能較大,sql 變動需要改變 java 代碼。 解決: 将 Sql 語句配置在 XXXXmapper.xml 檔案中與 java 代碼分離。
- 3.向sql語句傳參數麻煩,因為sql語句的where 條件不一定,可能多也可能少,占位符需要和參數對應。 解決: Mybatis自動将 java 對象映射至 sql 語句,通過 statement 中的 parameterType 定義輸入參數的 類型。
- 4.對結果集解析麻煩,sql 變化導緻解析代碼變化,且解析前需要周遊,如果能将資料庫記錄封裝成 pojo 對 象解析比較友善。 解決: Mybatis自動将 sql執行結果映射至 java 對象,通過statement中的resultType 定義輸出結果的 類型。