mybatis框架讓我們能在編程中只需要編寫一個接口,然后再編寫mapper映射文件,無需編寫接口的實現類就可以實現從數據庫檢索數據。這是mybatis通過動態代理,把mapper映射文件的內容轉化為真正的執行部分。因此我們在編程中,需要特別關注接口和映射文件的編寫。本節主要講解接口方法的返回值類型在mapper文件中的編寫方式。
我們思考下,返回值類型一般分為
- 數字類型,比如查詢記錄的個數
- 單個對象
- 多個對象,使用List封裝
- 單個對象,使用map封裝
- 多個對象,使用map封裝
由於每次建立工程比較復雜,可以參考第一節:mybatis入門來搭建一個簡單的工程,然后來測試本節內容。
注意本節內容關注點是mapper接口方法的返回值類型和mapper文件的resultType的編寫。
1、返回值類型為數字類型
1、mapper接口,我們簡單查詢所有記錄,返回Long類型的值。
public interface PersonMapper { Long getTotalNumberOfPerson(); }
2、mapper映射文件
<select id="getTotalNumberOfPerson" resultType="long"> select count(*) from person </select>
注意在mapper文件中,只需要 resultType 為 long 類型即可。
3、測試
public class Main { public static void main(String[] args) throws IOException { InputStream resourceAsStream = Resources.getResourceAsStream("mybatis-config.xml"); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream); SqlSession sqlSession = sqlSessionFactory.openSession(); PersonMapper mapper = sqlSession.getMapper(PersonMapper.class); Long totalNumberOfPerson= mapper.getTotalNumberOfPerson(); System.out.println(totalNumberOfPerson); //10 sqlSession.close(); } }
2、查詢單個對象
這種查詢直接返回和數據庫表對應的相關實體,並且只有一條記錄,一般都是按照id去查詢,也就是第一節:mybatis入門中演示的樣例,我們再次說明下。
1、mapper接口
public interface PersonMapper { Person getPerson(Integer id); }
2、mapper映射文件
<select id="getPerson" resultType="com.yefengyu.mybatis.entity.Person"> select id, first_name firstName, last_name lastName, age, email, address from person where id = #{id} </select>
3、測試
public class Main { public static void main(String[] args) throws IOException { InputStream resourceAsStream = Resources.getResourceAsStream("mybatis-config.xml"); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream); SqlSession sqlSession = sqlSessionFactory.openSession(); PersonMapper mapper = sqlSession.getMapper(PersonMapper.class); Person person = mapper.getPerson(1); System.out.println(person); sqlSession.close(); } }
總結:在查詢單個對象,返回的是實體類型的時候,只需要將resultType設置為全類名即可。
3、查詢多個對象,使用list封裝
這種查詢一般是根據某種條件,查詢出很多個結果,然后使用List封裝起來。
1、mapper接口,根據address查詢多個Person對象
public interface PersonMapper { List<Person> getPersons(String address); }
2、mapper映射文件,注意對於mapper接口中返回List類型的,mapper映射文件的resultType只需要設置List所包含的對象的類型即可。
<select id="getPersons" resultType="com.yefengyu.mybatis.entity.Person"> select id, first_name firstName, last_name lastName, age, email, address from person where address = #{address} </select>
3、測試
public class Main { public static void main(String[] args) throws IOException { InputStream resourceAsStream = Resources.getResourceAsStream("mybatis-config.xml"); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream); SqlSession sqlSession = sqlSessionFactory.openSession(); PersonMapper mapper = sqlSession.getMapper(PersonMapper.class); List<Person> persons = mapper.getPersons("beijing"); for (int i = 0; i < persons.size(); i++) { System.out.println(persons.get(i)); } sqlSession.close(); } }
4、結果:
Person{id=1, firstName='Schmitt', lastName='Carine', age=25, email='null', address='beijing'} Person{id=2, firstName='King', lastName='Jean', age=36, email='Jean@163.com', address='beijing'} Person{id=8, firstName='Gao', lastName='Diego', age=45, email='66666@qq.com', address='beijing'} Person{id=9, firstName='Piestrzeniewicz', lastName='Schmitt', age=36, email='44444@qq.com', address='beijing'} Person{id=10, firstName='Frdrique', lastName='Juri', age=25, email='99999@qq.com', address='beijing'}
4、查詢單個對象,使用map封裝
這種情況,類似第二小節,也是單個對象,只不過我們需要返回的是一個map,將單個對象封裝成map,數據庫的列名對應的屬性名稱作為key,返回的結果作為value.
1、mapper接口
public interface PersonMapper { Map<String, Object> getPersonMap(Integer id); }
2、mapper映射文件,此時需要把resultType設置為map
<select id="getPersonMap" resultType="map"> select id, first_name firstName, last_name lastName, age, email, address from person where id = #{id} </select>
3、測試
public class Main { public static void main(String[] args) throws IOException { InputStream resourceAsStream = Resources.getResourceAsStream("mybatis-config.xml"); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream); SqlSession sqlSession = sqlSessionFactory.openSession(); PersonMapper mapper = sqlSession.getMapper(PersonMapper.class); Map<String, Object> personMap = mapper.getPersonMap(1); System.out.println(personMap); sqlSession.close(); } }
4、結果如下,注意在使用map接收返回值的時候,如果某個字段為null,那么就不會封裝到map中,比如下面的結果中就沒有Email字段的結果。
{firstName=Schmitt, lastName=Carine, address=beijing, id=1, age=25}
5、查詢多個對象,使用map封裝
這個情況,一般是查詢多條記錄,使用主鍵作為key,使用對象作為value,見下面mapper接口。
1、mapper接口
public interface PersonMapper { @MapKey("id") Map<Integer, Person> getPersonsMap(String address); }
2、mapper映射文件
<select id="getPersonsMap" resultType="map"> select id, first_name firstName, last_name lastName, age, email, address from person where address = #{address} </select>
3、測試
public class Main { public static void main(String[] args) throws IOException { InputStream resourceAsStream = Resources.getResourceAsStream("mybatis-config.xml"); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream); SqlSession sqlSession = sqlSessionFactory.openSession(); PersonMapper mapper = sqlSession.getMapper(PersonMapper.class); Map<Integer, Person> personMap = mapper.getPersonsMap("beijing"); for (Map.Entry<Integer, Person> personEntry : personMap.entrySet()) { System.out.println(personEntry.getKey() + " : " + personEntry.getValue()); } sqlSession.close(); } }
4、結果
1 : {firstName=Schmitt, lastName=Carine, address=beijing, id=1, age=25} 2 : {firstName=King, lastName=Jean, address=beijing, id=2, age=36, email=Jean@163.com} 8 : {firstName=Gao, lastName=Diego, address=beijing, id=8, age=45, email=66666@qq.com} 9 : {firstName=Piestrzeniewicz, lastName=Schmitt, address=beijing, id=9, age=36, email=44444@qq.com} 10 : {firstName=Frdrique, lastName=Juri, address=beijing, id=10, age=25, email=99999@qq.com}
注意:mapper接口需要使用MapKey注解指定將某個屬性的值作為map的key。本例中使用person表的主鍵id對應的實體的屬性id作為key。除此之外,mapper映射文件中resultType設置為map。此外如果某個字段為null,那么就不插入到map中。
6、總結
- 數字類型,比如查詢記錄的個數。resultType為 int 或者 long等。
- 單個對象。resultType為對象全類名
- 多個對象,使用List封裝。resultType為對象全類名。
- 單個對象,使用map封裝。resultType為map。
- 多個對象,使用map封裝。resultType為map。注意mapper接口的方法需要使用MapKey注解指定key為哪個屬性。