MyBatisのCURD操作(Mapperダイナミックエージェント)
前の例(Daoインタフェース実装クラス)でDaoインタフェース実装クラスをカスタマイズした場合、Daoの実装クラスは実質的な作業をしていないことがわかりました.それはSqlSessionの関連APIを通じてマッピングファイルmapperの対応するidのSQL文にナビゲートするだけです.実際にDBを操作する作業は、フレームワークがmapperのSQLを通じて行われます.
そのため、MyBatisフレームワークはDaoの実装クラスを捨てて、マッピングファイルmapperの対応するSQL文に直接位置決めし、DBを操作します.このようなDaoの実装方式をMapperの動的エージェント方式と呼ぶ.Mapperダイナミックエージェント方式では,プログラマがDaoインタフェースを実現する必要はない.インタフェースは,MyBatisとマッピングファイルを組み合わせて自動的に生成される動的エージェントによって実現される.
マッピングファイルのnamespaceプロパティ値
一般的に、Daoインタフェースの実装クラスメソッドは、同じSQLマッピングファイル内のSQLマッピングidを使用します.したがって、MyBatisフレームワークでは、マッピングファイルのラベルのnamespaceプロパティをDaoインタフェースの全クラス名に設定すると、メソッドが属するDaoインタフェースに基づいて、対応するnamespaceのマッピングファイルに自動的に関連するSQLマッピングが検索されます.
簡単に言えば、インタフェース名を使用してマッピングファイルmapperにナビゲートできます.
ログ出力制御ファイルの変更
mapperのnamespaceが変更された場合、ログ出力制御ファイルのloggerの出力オブジェクトを変更する必要があります.
Daoインタフェースメソッド名
MyBatisフレームワークでは、インタフェースのメソッド名が、マッピングファイルの対応するSQLラベルのid値と同じであることが要求されます.メソッド名に基づいて、対応するマッピングファイルに同じ名前のSQLマッピングidが自動的に検索されます.簡単に言えば、マッピングファイルmapperの対応するSQL文にメソッド名でナビゲートできます.
Dao実装クラスの削除
Daoインタフェースを呼び出す方法によって、SQLマッピングファイルから実行するSQL文を見つけることができるだけでなく、メソッドパラメータと戻り値を通じてSQL文の動的パラメータを入力し、クエリー結果を返すこともできます.したがって、Daoの実装作業は、MyBatisシステムがマッピングファイルに基づいて自動的に完了することができます.
テストクラスの変更
マルチクエリー条件では問題の解決を全体的に受信できません
実際の作業では、フォームに与えられたクエリー条件が1つのオブジェクトにカプセル化できない場合があります.つまり、クエリー・メソッドは複数のパラメータしか持ち込めません.この複数のパラメータをカプセル化した1つのオブジェクトは持ち込めません.この問題には2つの解決策がある.
1.複数のパラメータを1つのMapにカプセル化
(1)Daoインタフェースの修正
(2)マッピングファイルの修正
(3)試験クラスの修正
2.複数のパラメータを個々に受信
mapperのSQL文では、パラメータインデックス#{index}で各パラメータを1つずつ受信できます.
(1)Daoインタフェースの修正
(2)マッピングファイルの修正
(3)試験クラスの修正
質問:#{}にはどんな内容が入れられますか?1)パラメータオブジェクトの属性;2)任意の内容で,このときの#{}はプレースホルダである.3)パラメータがmapの場合のkey;4)パラメータがmapの場合、keyに対応するvalueがオブジェクトであれば、そのオブジェクトの属性を入れることができる.5)パラメータのインデックス番号.
そのため、MyBatisフレームワークはDaoの実装クラスを捨てて、マッピングファイルmapperの対応するSQL文に直接位置決めし、DBを操作します.このようなDaoの実装方式をMapperの動的エージェント方式と呼ぶ.Mapperダイナミックエージェント方式では,プログラマがDaoインタフェースを実現する必要はない.インタフェースは,MyBatisとマッピングファイルを組み合わせて自動的に生成される動的エージェントによって実現される.
マッピングファイルのnamespaceプロパティ値
一般的に、Daoインタフェースの実装クラスメソッドは、同じSQLマッピングファイル内のSQLマッピングidを使用します.したがって、MyBatisフレームワークでは、マッピングファイルのラベルのnamespaceプロパティをDaoインタフェースの全クラス名に設定すると、メソッドが属するDaoインタフェースに基づいて、対応するnamespaceのマッピングファイルに自動的に関連するSQLマッピングが検索されます.
簡単に言えば、インタフェース名を使用してマッピングファイルmapperにナビゲートできます.
<mapper namespace="com.huang.dao.IStudentDao">
ログ出力制御ファイルの変更
mapperのnamespaceが変更された場合、ログ出力制御ファイルのloggerの出力オブジェクトを変更する必要があります.
##define a logger
log4j.logger.com.huang.dao.IStudentDao=trace,console
Daoインタフェースメソッド名
MyBatisフレームワークでは、インタフェースのメソッド名が、マッピングファイルの対応するSQLラベルのid値と同じであることが要求されます.メソッド名に基づいて、対応するマッピングファイルに同じ名前のSQLマッピングidが自動的に検索されます.簡単に言えば、マッピングファイルmapperの対応するSQL文にメソッド名でナビゲートできます.
public interface IStudentDao {
void insertStudent(Student student);
void deleteStudentById(int id);
void updateStudent(Student student);
List<Student> selectAllStudents();
Student selectStudentById(int id);
List<Student> selectStudentsByName(String name);
}
Dao実装クラスの削除
Daoインタフェースを呼び出す方法によって、SQLマッピングファイルから実行するSQL文を見つけることができるだけでなく、メソッドパラメータと戻り値を通じてSQL文の動的パラメータを入力し、クエリー結果を返すこともできます.したがって、Daoの実装作業は、MyBatisシステムがマッピングファイルに基づいて自動的に完了することができます.
テストクラスの変更
public class MyTest {
private IStudentDao dao;
private SqlSession session;
@Before
public void setUp() {
session = MyBatisUtils.getSqlSession();
dao = session.getMapper(IStudentDao.class);
}
@After
public void tearDown() {
if (session != null) {
session.close();
}
}
@Test
public void test01() {
Student student = new Student(" ", 23, 93.5);
System.out.println(" :student = " + student);
dao.insertStudent(student);
System.out.println(" :student = " + student);
// SqlSession
session.commit();
}
/*@Test
public void test02() {
Student student = new Student(" ", 23, 93.5);
System.out.println(" :student = " + student);
dao.insertStudentCacheId(student);
System.out.println(" :student = " + student);
}*/
@Test
public void test03() {
dao.deleteStudentById(22);
// SqlSession
session.commit();
}
@Test
public void test04() {
Student student = new Student(" ", 23, 93.5);
student.setId(8);
dao.updateStudent(student);
// SqlSession
session.commit();
}
マルチクエリー条件では問題の解決を全体的に受信できません
実際の作業では、フォームに与えられたクエリー条件が1つのオブジェクトにカプセル化できない場合があります.つまり、クエリー・メソッドは複数のパラメータしか持ち込めません.この複数のパラメータをカプセル化した1つのオブジェクトは持ち込めません.この問題には2つの解決策がある.
1.複数のパラメータを1つのMapにカプセル化
(1)Daoインタフェースの修正
public interface IStudentDao {
List<Student> selectStudentsByCondition(Map<String, Object> map);
}
(2)マッピングファイルの修正
<select id="selectStudentsByCondition" resultType="Student">
select id,name,age,score
from student
where name like '%' #{nameCon} '%'
and age > #{ageCon}
and score > #{scoreCon}
select>
(3)試験クラスの修正
// map
@Test
public void test01() {
Student stu = new Student(" ", 20, 96.5);
Map<String, Object> map = new HashMap<String, Object>();
map.put("nameCon", " ");
map.put("ageCon", 23);
map.put("stu", stu);
List<Student> students = dao.selectStudentsByCondition(map);
for (Student student : students) {
System.out.println(student);
}
}
2.複数のパラメータを個々に受信
mapperのSQL文では、パラメータインデックス#{index}で各パラメータを1つずつ受信できます.
(1)Daoインタフェースの修正
public interface IStudentDao {
List<Student> selectStudentsByCondition(String name, int age);
}
(2)マッピングファイルの修正
<select id="selectStudentsByCondition" resultType="Student">
select id,name,age,score
from student
where name like '%' #{0} '%'
and age > #{1}
select>
(3)試験クラスの修正
@Test
public void test01() {
List<Student> students = dao.selectStudentsByCondition(" ", 23);
for (Student student : students) {
System.out.println(student);
}
}
質問:#{}にはどんな内容が入れられますか?1)パラメータオブジェクトの属性;2)任意の内容で,このときの#{}はプレースホルダである.3)パラメータがmapの場合のkey;4)パラメータがmapの場合、keyに対応するvalueがオブジェクトであれば、そのオブジェクトの属性を入れることができる.5)パラメータのインデックス番号.