Mybatis基礎入門(三)——增刪改查
有了上篇文章中的環境基礎,這裡進一步做一些增刪改查的例項。並附帶原始碼下載連結。
一、配置檔案的語法約束:
1、Mybatis的配置檔案和介面的定義要有一定的規範約束,也是約定大於配置的一種表現,那就是配置檔案中,增刪改查的每一個方法的id要和介面中的方法一致,且大小寫敏感。
2、在配置檔案中增刪改查方法有各自對應的標籤:insert、delete、update、select。通常情況下都會有一個parameterType標籤表示傳入的引數型別。傳遞多個引數的時候,可以不在配置檔案中使用該標籤,但需在介面中配合註解。
3、多個引數的傳遞,還有兩種方法:利用hashMap 、實體封裝;mybatis 自身的多個引數傳遞方式。這裡不做重點,後面會有介紹。
4、引數使用ognl的表示式語法,如:#{userName},#{userAge},#{userAddress}。
5、對於結果是集合型別的返回值使用resultMap標籤標示。
6、association標籤相當於一個component,可以打到複用的目的。
二、增刪改查例項:
例項中包含了單表的增刪改查和多表的聯合查詢,針對聯合查詢和hibernate的物件導航語法查詢很類似,這裡不用做過多解釋,重點是具體語法的體會。
在上篇文章的基礎上添加了Article實體,在介面中添加了單表增刪改查的方法以及兩個實體的聯合查詢,以及返回集合型別的方法。
1、介面的定義:
/** * 規則:介面中的方法名和引數和配置檔案中的id和parameterType分別對應,sql寫在配置檔案中,引數和呼叫的類test中的方法一致 * sql語句中的引數和實體中的欄位名一致, * @author limin * */ public interface IUserOperation { /* * 這裡面有一個方法名 selectUserByID 必須與 User.xml 裡面配置的 select 的id 對應(<select * id="selectUserByID") */ public User selectUserByID(int id); //根據使用者名稱查詢使用者列表 public List<User> selectUsers(String userName); public void addUser(User user); public void updateUser(User user); public void deleteUser(int id); public List<Article> getUserArticles(int id); }
2、配置檔案:
<?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="com.tgb.mybatis.inter.IUserOperation">
<!-- com.yihaomen.mybatis.model.UserMapper -->
<!-- resultType的值要和Configuration.xml中的實體User的別名相同 -->
<select id="selectUserByID" parameterType="int" resultType="User">
select * from user where id = #{id}
</select>
<!-- 為了返回list 型別而定義的returnMap -->
<resultMap type="User" id="resultListUser">
<id column="id" property="id" />
<result column="userName" property="userName" />
<result column="userAge" property="userAge" />
<result column="userAddress" property="userAddress" />
</resultMap>
<!-- 返回list 的select 語句,注意 resultMap 的值是指向前面定義好的 -->
<select id="selectUsers" parameterType="string" resultMap="resultListUser">
select * from user where userName like #{userName}
</select>
<!-- 執行增加操作的SQL語句。id和parameterType分別與IUserOperation介面中的addUser方法的名字和 引數型別一致。以#{name}的形式引用Student引數的name屬性,MyBatis將使用反射讀取Student引數
的此屬性。#{name}中name大小寫敏感。引用其他的gender等屬性與此一致。useGeneratedKeys設定 為"true"表明要MyBatis獲取由資料庫自動生成的主
鍵;keyProperty="id"指定把獲取到的主鍵值注入 到Student的id屬性 -->
<insert id="addUser" parameterType="User" useGeneratedKeys="true"
keyProperty="id">
insert into user(userName,userAge,userAddress)
values(#{userName},#{userAge},#{userAddress})
</insert>
<!-- 更新的配置 -->
<update id="updateUser" parameterType="User">
update user set
userName=#{userName},userAge=#{userAge},userAddress=#{userAddress}
where id=#{id}
</update>
<!-- 刪除配置 -->
<delete id="deleteUser" parameterType="int">
delete from user where id=#{id}
</delete>
<!-- 多對一方法二:將 association 中對應的對映獨立抽取出來,可以達到複用的目的。 -->
<!-- User 聯合文章進行查詢 方法之二的配置 (多對一的方式) -->
<resultMap id="resultUserArticleList" type="Article">
<id property="id" column="aid" />
<result property="title" column="title" />
<result property="content" column="content" />
<association property="user" javaType="User" resultMap="resultListUser" />
</resultMap>
<!-- 多對一的配置方法一: 根據使用者id查詢多個Article -->
<!-- <resultMap id="resultUserArticleList" type="Article">
<id property="id" column="aid" />
<result property="title" column="title" />
<result property="content" column="content" />
<association property="user" javaType="User">
<id property="id" column="id" />
<result property="userName" column="userName" />
<result property="userAddress" column="userAddress" />
</association>
</resultMap>
-->
<select id="getUserArticles" parameterType="int"
resultMap="resultUserArticleList">
select user.id,user.username,user.useraddress,article.id aid,article.title,article.content
from user,article
where user.id=article.userid and user.id=#{id}
</select>
</mapper>
同時需要在Configuration.xml中,增加了Article的部分,參照user即可。
對多對一的配置有兩種方法,區別在於是否在association標籤中複用resultMap標籤,resultMap標籤配置了一個list集合。
3、最後再給出測試檔案:
package com.tgb.test;
import java.io.Reader;
import java.util.List;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import com.tgb.mybatis.inter.IUserOperation;
import com.tgb.mybatis.model.Article;
import com.tgb.mybatis.model.User;
/**
* 增加:天機後,必須提交事務,否則不會寫入到資料庫
* 更新:類似hibernate,要先查出後,之後再更新
* 也有類似的session.commit()
* @author limin
*
*/
public class Test {
private static SqlSessionFactory sqlSessionFactory;
private static Reader reader;
static {
try {
// 最終實現了從配置檔案中配置工廠的初始化
reader = Resources.getResourceAsReader("Configuration.xml");
sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
} catch (Exception e) {
e.printStackTrace();
}
}
public static SqlSessionFactory getSession() {
return sqlSessionFactory;
}
public void getUserList(String userName){
SqlSession session = sqlSessionFactory.openSession();
try {
IUserOperation userOperation=session.getMapper(IUserOperation.class);
List<User> users = userOperation.selectUsers(userName);
for(User user:users){
System.out.println(user.getId()+":"+user.getUserName()+":"+user.getUserAddress());
}
} finally {
session.close();
}
}
//增加後,必須提交事務,否則不會寫入到資料庫.
public void addUser(){
User user=new User();
user.setUserAddress("萬達廣場");
user.setUserName("陸遜");
user.setUserAge(80);
SqlSession session = sqlSessionFactory.openSession();
try {
IUserOperation userOperation=session.getMapper(IUserOperation.class);
userOperation.addUser(user);
session.commit();
System.out.println("當前增加的使用者 id為:"+user.getId());
} finally {
session.close();
}
}
//類似hibernate,要先查出後,之後再更新
public void updateUser(){
//先得到使用者,然後修改,提交。
SqlSession session = sqlSessionFactory.openSession();
try {
IUserOperation userOperation=session.getMapper(IUserOperation.class);
User user = userOperation.selectUserByID(2);
user.setUserAddress("上海東方明珠寶塔");
userOperation.updateUser(user);
session.commit();
} finally {
session.close();
}
}
/**
* 刪除資料,刪除一定要 commit.
* @param id
*/
public void deleteUser(int id){
SqlSession session = sqlSessionFactory.openSession();
try {
IUserOperation userOperation=session.getMapper(IUserOperation.class);
userOperation.deleteUser(id);
session.commit();
} finally {
session.close();
}
}
public void getUserArticles(int userid){
SqlSession session = sqlSessionFactory.openSession();
try {
IUserOperation userOperation=session.getMapper(IUserOperation.class);
List<Article> articles = userOperation.getUserArticles(userid);
for(Article article:articles){
System.out.println(article.getTitle()+":"+article.getContent()+
":作者是:"+article.getUser().getUserName()+":地址:"+
article.getUser().getUserAddress());
}
} finally {
session.close();
}
}
public static void main(String[] args) {
//測試介面返回使用者list列表
Test testUser=new Test();
testUser.getUserList("%");
testUser.addUser();
testUser.updateUser();
testUser.deleteUser(2);
testUser.getUserArticles(1);
/*
SqlSession session = sqlSessionFactory.openSession();
try {
// 1、沒有使用介面的測試
// 這裡傳入的引數是從User.xml檔案中配置的
//User user = (User) session.selectOne("com.yihaomen.mybatis.model.UserMapper.selectUserByID", 1);
// 2、基於介面的測試:在介面的定義中,selectUserByID方法和配置檔案中的方法名要一致,這裡傳入的是引數
IUserOperation userOperation = session.getMapper(IUserOperation.class);
User user = userOperation.selectUserByID(1);
System.out.println(user.getUserAddress());
System.out.println(user.getUserName());
} finally {
session.close();
} */
}
}
結果如圖:
三、總結:
這篇文章主要是增刪改查的一個例項,也包含了聯合查詢,重點是幾種xml標籤的使用,在使用的時候,可以從照貓畫虎開始,有hibernate基礎,理解Mybatis是很容易的。