Heim  >  Artikel  >  Java  >  Detaillierte Erläuterung des Beispielcodes der Mybatis-Zuordnungsdatei

Detaillierte Erläuterung des Beispielcodes der Mybatis-Zuordnungsdatei

黄舟
黄舟Original
2017-03-09 10:32:532178Durchsuche

Dieser Artikel stellt hauptsächlich die detaillierte Erklärung von Beispielen für Mybatis-Zuordnungsdateien vor. Freunde, die sie benötigen, können darauf verweisen

1. Eingabezuordnung

parameterType

Geben Sie den Java-Typ des Eingabeparameters an. Sie können einen Alias ​​oder den vollständig qualifizierten Namen der Klasse verwenden. Es kann einfache Typen, POJO, HashMap empfangen.

1. Einfachen Typ übergeben

Benutzerinformationen basierend auf der Benutzer-ID abfragen:

<select id="findUserById" parameterType="int" resultType="com.itheima.mybatis.po.User"> 
  SELECT * FROM USER WHERE id =#{id} 
</select>

2. POJO-Objekt übergeben

Benutzer hinzufügen:

<insert id="insertUser" parameterType="com.itheima.mybatis.po.User"> 
  <selectKey keyProperty="id" resultType="int" order="AFTER"> 
   SELECT LAST_INSERT_ID() 
  </selectKey> 
  INSERT INTO USER(username,birthday,sex,address) VALUES(#{username},#{birthday},#{sex},#{address}) 
</insert>

3 Verpackung Während der Entwicklung des Objekts

werden Abfragebedingungen über pojo übergeben. Die Abfragebedingungen sind umfassende Abfragebedingungen, einschließlich nicht nur Benutzerabfragebedingungen, sondern auch anderer Abfragebedingungen (z. B. Produktinformationen des Benutzers). wird auch als Abfragebedingung verwendet.
Zu diesem Zeitpunkt können Sie das Wrapper-Objekt verwenden, um die Eingabeparameter zu übergeben.

3.1 Anforderungen

Umfassende Abfrage von Benutzerinformationen erfordert komplexe Abfragebedingungen, wie z. B. (Benutzerinformationen, Bestellinformationen, Produktinformationen).

3.2 Definieren Sie Verpackungsobjekte

Im Allgemeinen sollte die User.java-Klasse mit den Datentabellenfeldern übereinstimmen. Es ist am besten, hier keine anderen Felder hinzuzufügen In Mybatis wird die Po-Klasse basierend auf der Tabellenstruktur generiert.

Wenn das Feld in der Po-Klasse erweitert wird, wird es zu diesem Zeitpunkt überschrieben.

Damit die po-Klasse erweitert werden kann, müssen wir eine Erweiterungsklasse erstellen, um sie zu erben.

public class UserExt extends User{ 
 //这里可以定义user的一些扩展信息 
}

POJO-Wrapper-Klasse definieren:

public class UserQueryVO { 
 //用户信息 
 private UserExt userExt; 
 //商品ID集合 
 private List<Integer> idList; 
 //商品信息 
 public List<Integer> getIdList() { 
  return idList; 
 } 
 public void setIdList(List<Integer> idList) { 
  this.idList = idList; 
 } 
 public UserExt getUserExt() { 
  return userExt; 
 } 
 public void setUserExt(UserExt userExt) { 
  this.userExt = userExt; 
 } 
 //订单信息 
}

3.3 Mapper-Schnittstelle schreiben

//Verwenden Sie Paketierungsklassen, um umfassende Abfragen komplexer Benutzerinformationen durchzuführen
public List365ec941ff246bca2de9473cb1305a57

3.4 Mapper-Mapping-Datei schreiben

<!-- 通过包装类来进行复杂的用户信息综合查询 --> 
<select id="findUserList" parameterType="userQueryVO" resultType="userExt"> 
  SELECT * FROM USER WHERE sex=#{userExt.sex} AND username LIKE &#39;%${userExt.username}%&#39; 
</select>

Hinweis: Der Eingabeparametertyp wird zu UserQueryVO, dem Typ des Ergebnissatzes wird zu UserExt, und die Parameter in #{} werden zu den Unterattributen „Geschlecht“ und „Benutzername“ des Attributs „userExt“ im Objekt „UserQueryVO“.

3.5 Testcode schreiben

@Test 
public void findUserListTest() { 
 // 创建SqlSession 
 SqlSession sqlSession = sqlSessionFactory.openSession(); 
 // 通过SqlSession,获取mapper接口的动态代理对象 
 UserMapper userMapper = sqlSession.getMapper(UserMapper.class); 
 //构造userQueryVO对象 
 UserQueryVO userQueryVO = new UserQueryVO(); 
 // 构造UserExt对象 
 UserExt userExt = new UserExt(); 
 userExt.setSex("1"); 
 userExt.setUsername("小明"); 
 userQueryVO.setUserExt(userExt); 
 // 调用mapper对象的方法 
 List<UserExt> list = userMapper.findUserList(userQueryVO); 
 System.out.println(list); 
 // 关闭SqlSession 
 sqlSession.close(); 
}

4 . Das Übergeben von HashMap

ist dasselbe wie das Übergeben von POJO-Objekten. Der Schlüssel von Map entspricht dem Attribut von Pojo.

4.1 Zuordnungsdatei

<!-- 传递hashmap综合查询用户信息 --> 
 <select id="findUserByHashmap" parameterType="hashmap" resultType="user"> 
  select * from user where id=#{<span style="color:#ff0000;">id</span>} and username like &#39;%${<span style="color:#ff0000;">username</span>}%&#39; 
 </select>

Die oben rot markierte ID und der Benutzername sind Hashmap-Schlüssel.

4.2 Testcode

Public void testFindUserByHashmap()throws Exception{ 
  //获取session 
  SqlSession session = sqlSessionFactory.openSession(); 
  //获限mapper接口实例 
  UserMapper userMapper = session.getMapper(UserMapper.class); 
  //构造查询条件Hashmap对象 
  HashMap<String, Object> map = new HashMap<String, Object>(); 
  map.put("id", 1); 
  map.put("username", "管理员"); 
   
  //传递Hashmap对象查询用户列表 
  List<User>list = userMapper.findUserByHashmap(map); 
  //关闭session 
  session.close(); 
 }

Ausnahmetest:

Der Schlüssel in der übergebenen Zuordnung stimmt nicht mit dem in SQL analysierten Schlüssel überein.

Das Testergebnis meldete keinen Fehler, aber der über den Schlüssel erhaltene Wert war leer.

2. Ausgabezuordnung

1. resultType

(1) Verwendungsmethode

Bei Verwendung von resultType für die Ergebniszuordnung muss der Spaltenname genau mit dem zugeordneten Pojo-Attributnamen übereinstimmen, damit die Spalte erfolgreich zugeordnet werden kann.

Wenn der Name der abgefragten Spalte und der Name des zugeordneten Pojo-Attributs alle inkonsistent sind, ist das zugeordnete Objekt leer und es wird kein Pojo-Objekt erstellt.

Wenn der Name der abgefragten Spalte und der Name des zugeordneten Pojo-Attributs nicht übereinstimmen Pojo-Attributnamen haben einen. Wenn sie konsistent sind, ist das zugeordnete Objekt nicht leer und es wird ein Pojo-Objekt erstellt, aber nur das korrekt zugeordnete Attribut hat einen Wert.

(2) Einfacher Typ ausgeben

Beachten Sie, dass es auch Anforderungen für die Ergebniszuordnung einfacher Typen gibt. Die Abfragespalte muss eine Spalte sein, bevor sie einem einfachen Typ zugeordnet werden kann.

Wenn das Ausgabeergebnis nur eine Spalte hat, können Sie ResultType verwenden, um einen einfachen Typ als Ausgabeergebnistyp anzugeben.

2.1 Anforderungen

Eine umfassende Abfrage der Gesamtzahl der Benutzer erfordert die Eingabe komplexer Abfragebedingungen, wie z. B. (Benutzerinformationen, Bestellinformationen). , Produktinformationen).

2.2Mapper-Mapping-Datei

<!-- 综合查询用户信息总数,需要传入查询条件复杂,比如(用户信息、订单信息、商品信息) --> 
<select id="findUsersCount" parameterType="UserQueryVO" 
  resultType="int"> 
  SELECT count(1) FROM USER WHERE sex = #{userExt.sex} AND username LIKE &#39;%${userExt.username}%&#39; 
</select>

2.3 Mapper-Schnittstelle

//综合查询用户信息总数。学习:resultType输出简单类型 
public int findUsersCount(UserQueryVO vo);

2.4 Testcode

@Test 
public void testFindUsersCount() { 
 // 创建SqlSession 
 SqlSession sqlSession = sqlSessionFactory.openSession(); 
 // 通过SqlSession,获取mapper接口的动态代理对象 
 UserMapper userMapper = sqlSession.getMapper(UserMapper.class); 
 //构造userQueryVO对象 
 UserQueryVO userQueryVO = new UserQueryVO(); 
 // 构造UserExt对象 
 UserExt userExt = new UserExt(); 
 userExt.setSex("1"); 
 userExt.setUsername("小明"); 
 userQueryVO.setUserExt(userExt); 
 int count = mapper.findUsersCount(userQueryVO); 
 System.out.println(count); // 关闭SqlSession 
 sqlSession.close(); 
}

(3) POJO-Einzelobjekt und -Liste ausgeben

Hinweis: Bei der Ausgabe eines einzelnen Pojo-Objekts und einer Pojo-Liste (mit Pojo-Objekten) erfolgt die Mapper-Zuordnung file Die Typen von resultType sind gleich, aber die Methodenrückgabewerte der Mapper-Schnittstelle sind unterschiedlich.

3.1Mapper-Mapping-Datei

<select id="findUsersByName" parameterType="java.lang.String" resultType="cn.itcast.mybatis.po.User"> 
  SELECT * FROM USER WHERE username LIKE &#39;%${value}%&#39; 
</select>

3.2 Mapper-Schnittstelle

1. Ein einzelnes Pojo-Objekt ausgeben

//根据用户名称来模糊查询用户信息 
 public User findUsersByName(String username);

2 >

//根据用户名称来模糊查询用户信息列表 
 public List<User> findUsersByName(String username);

Zusammenfassung: Wenn dieselbe Mapper-Zuordnungsdatei ein einzelnes Objekt und eine Liste von Objekten zurückgibt, wenn die Mapper-Schnittstelle einen dynamischen Proxy generiert,

会根据返回值的类型,决定调用selectOne方法还是selectList方法。

2、resultMap

resultMap可以进行高级结果映射(一对一、一对多映射)。

(1)使用方法

如果查询出来的列名和属性名不一致,通过定义一个resultMap将列名和pojo属性名之间作一个映射关系。

1、  定义resultMap

2、  使用resultMap作为statement的输出映射类型。

(2)需求

把下面SQL的输出结果集进行映射

SELECT id id_,username username_,sex sex_FROM USER WHERE id = 1

(3)Mapper映射文件

定义resultMap:

<!-- 定义resultMap --> 
<!-- 
 [id]:定义resultMap的唯一标识 
 [type]:定义该resultMap最终映射的pojo对象 
 [id标签]:映射结果集的唯一标识列,如果是多个字段联合唯一,则定义多个id标签 
 [result标签]:映射结果集的普通列 
 [column]:SQL查询的列名,如果列有别名,则该处填写别名 
 [property]:pojo对象的属性名 
--> 
<resultMap type="user" id="userResultMap"> 
 <id column="id_" property="id"/> 
 <result column="username_" property="username"/> 
 <result column="sex_" property="sex"/> 
</resultMap>

定义statement:

<!-- 根据ID查询用户信息(学习resultMap) --> 
<select id="findUserByIdResultMap" parameterType="int" resultMap="userResultMap"> 
  SELECT id id_,username username_,sex sex_ FROM USER WHERE id = #{id} 
</select>

(4)Mapper接口定义  

 //根据ID查询用户信息(学习resultMap) 
 public User findUserByIdResultMap(int id);<strong> 
</strong>

定义Statement使用resultMap映射结果集时,Mapper接口定义方法的返回值类型为mapper映射文件中resultMap的type类型。

(5)测试代码

@Test 
public void findUserByIdResultMapTest() { 
 // 创建SqlSession 
 SqlSession sqlSession = sqlSessionFactory.openSession(); 
 // 通过SqlSession,获取mapper接口的动态代理对象 
 UserMapper userMapper = sqlSession.getMapper(UserMapper.class); 
 // 调用mapper对象的方法 
 User user = userMapper.findUserByIdResultMap(1); 
 System.out.println(user); 
 // 关闭SqlSession 
 sqlSession.close(); 
}

三、动态SQL

1、If和where

Ø  If标签:作为判断入参来使用的,如果符合条件,则把if标签体内的SQL拼接上。
注意:用if进行判断是否为空时,不仅要判断null,也要判断空字符串‘';
Ø  Where标签:会去掉条件中的第一个and符号。

(1)需求

用户信息综合查询列表和用户信息综合查询总数这两个statement的定义使用动态SQL。

(2)映射文件

<!-- 综合查询用户信息,需要传入查询条件复杂,比如(用户信息、订单信息、商品信息) --> 
<select id="findUsersByQueryVO" parameterType="cn.itcast.mybatis.po.QueryUserVO" 
  resultType="User"> 
  SELECT * FROM USER 
 <where> 
  <if test="userExt != null"> 
   <if test="userExt.sex != null and userExt.sex != &#39;&#39;"> 
    AND sex = #{userExt.sex} 
   </if> 
   <if test="userExt.username != null and userExt.username != &#39;&#39;"> 
    AND username LIKE &#39;%${userExt.username}%&#39; 
   </if> 
  </if> 
 </where> 
</select> 
<!-- 综合查询用户信息总数,需要传入查询条件复杂,比如(用户信息、订单信息、商品信息) --> 
<select id="findUsersCount" parameterType="QueryUserVO" 
  resultType="int"> 
 SELECT count(1) FROM USER 
 <where> 
  <if test="userExt != null"> 
   <if test="userExt.sex != null and userExt.sex != &#39;&#39;"> 
    AND sex = #{userExt.sex} 
   </if> 
   <if test="userExt.username != null and userExt.username != &#39;&#39;"> 
    AND username LIKE &#39;%${userExt.username}%&#39; 
   </if> 
  </if> 
 </where> 
</select>

(3)Mapper接口

//通过包装类来进行复杂的用户信息综合查询 
public List<UserExt> findUserList(UserQueryVO userQueryVO); 
//综合查询用户总数 
public int findUsersCount(UserQueryVO userQueryVO);

(4)测试代码

不传用户名:

@Test 
 public void testFindUserList() throws Exception{ 
  // 创建UserMapper对象 
  SqlSession sqlSession = sqlSessionFactory.openSession(); 
  // 由mybatis通过sqlsession来创建代理对象 
  UserMapper mapper = sqlSession.getMapper(UserMapper.class); 
  QueryUserVO vo = new QueryUserVO(); 
  User user = new User(); 
  //此处使用动态SQL,不传username参数 
  user.setSex("1"); 
//  user.setUsername("小明"); 
  vo.setUser(user); 
  List<User> list = mapper.findUserList(vo); 
  System.out.println(user); 
  sqlSession.close(); 
 }

输出的SQL如下(也不包含用户名):

通过测试可以得知,打印出的SQL语句确实会随着条件的满足情况而不一样。

2、SQL片段

Mybatis提供了SQL片段的功能,可以提高SQL的可重用性。

2.1定义SQL片段

使用sql标签来定义一个SQL片段:

<!-- 定义SQL片段 --> 
<!-- 
 [sql标签]:定义一个SQL片段 
 [id]:SQL片段的唯一标识 
 建议: 
  1、SQL片段中的内容最好是以单表来定义 
  2、如果是查询字段,则不要写上SELECT 
  3、如果是条件语句,则不要写上WHERE 
 --> 
<sql id="select_user_where"> 
 <if test="userExt != null"> 
  <if test="userExt.sex != null and userExt.sex != &#39;&#39;"> 
   AND sex = #{userExt.sex} 
  </if> 
  <if test="userExt.username != null and userExt.username != &#39;&#39;"> 
   AND username LIKE &#39;%${userExt.username}%&#39; 
  </if> 
 </if> 
</sql>

2.2引用SQL片段

使用4801eb3c8c45c8edef439cb1d2a07f8a 来引用SQL片段:

<!-- 根据用户id来查询用户信息(使用SQL片段) --> 
<!-- 
 [include标签]:引用已经定义好的SQL片段 
 [refid]:引用的SQL片段id 
--> 
<select id="findUserList" parameterType="userQueryVO" resultType="userExt"> 
 SELECT * FROM USER 
<where> 
  <include refid="select_user_where"/> 
 </where> 
</select> 
<!-- 综合查询用户信息总数,需要传入查询条件复杂,比如(用户信息、订单信息、商品信息) --> 
<select id="findUsersCount" parameterType="QueryUserVO" 
  resultType="int"> 
 SELECT count(1) FROM USER 
 <where> 
  <include refid="select_user_where"/> 
 </where> 
</select>

3、foreach

向sql传递数组或List时,mybatis使用foreach解析数组里的参数并拼接到SQL中。

(1)传递pojo对象中的list集合

1.1需求

在用户查询列表和查询总数的statement中增加多个id输入查询。

1.2SQL

SELECT * FROM user WHERE id IN (1,10,16)

1.3定义pojo中的list属性

package com.itheima.mybatis.po; 
import java.util.List; 
/** 
 * <p>Title: UserQueryVO</p> 
 * <p>Description: TODO(这里用一句话描述这个类的作用) <p> 
 */ 
public class UserQueryVO { 
 //用户信息 
 private UserExt userExt; 
 //商品ID集合 
 private List<Integer> idList; 
 //商品信息 
 public List<Integer> getIdList() { 
  return idList; 
 } 
 public void setIdList(List<Integer> idList) { 
  this.idList = idList; 
 } 
 public UserExt getUserExt() { 
  return UserExt; 
 } 
 public void setUserExt(UserExt userExt) { 
  this.UserExt = UserExt; 
 } 
 //订单信息 
}

1.4映射文件

<!-- [foreach标签]:表示一个foreach循环 --> 
<!-- [collection]:集合参数的名称,如果是直接传入集合参数,则该处的参数名称只能填写[list]。 --> 
<!-- [item]:每次遍历出来的对象 --> 
<!-- [open]:开始遍历时拼接的串 --> 
<!-- [close]:结束遍历时拼接的串 --> 
<!-- [separator]:遍历出的每个对象之间需要拼接的字符 --> 
<if test="idList != null and idList.size > 0"> 
<foreach collection="idList" item="id" open="AND id IN (" close=")" separator=","> 
  #{id} 
</foreach> 
</if>

1.5Mapper接口

//根据用户ID的集合查询用户列表(学习foreach标签之通过POJO对象传ID集合) 
public List<UserExt> findUserList(UserQueryVO vo);

1.6测试代码

@Test 
public void testFindUserList() { 
  // 创建SqlSession 
  SqlSession sqlSession = sqlSessionFactory.openSession(); 
  // 通过SqlSession,获取mapper接口的动态代理对象 
  UserMapper mapper = sqlSession.getMapper(UserMapper.class); 
  // 构造QueryUserVO对象 
  QueryUserVO vo = new QueryUserVO(); 
  // UserExt ext = new UserExt(); 
  // ext.setUsername("小明"); 
  // ext.setSex("1"); 
  // vo.setUserExt(ext); 
  // 创建用户ID集合,然后设置到QueryUserVO对象中 
  List<Integer> idList = new ArrayList<Integer>(); 
  idList.add(1); 
  idList.add(10); 
  idList.add(16); 
  vo.setIdList(idList); 
  // 调用mapper代理对象的方法 
  List<UserExt> list = mapper.findUserList(vo); 
  System.out.println(list); 
  // 关闭SqlSession 
  sqlSession.close(); 
}

(2)直接传递List集合

2.1需求

根据用户ID的集合查询用户列表

2.2SQL

SELECT * FROM user WHERE id IN (1,10,16)

2.3映射文件

<!-- 根据用户ID的集合查询用户列表(学习foreach标签之直接传ID集合) --> 
<!--  
  [foreach标签]:表示一个foreach循环 
  [collection]:集合参数的名称,如果是直接传入集合参数,则该处的参数名称只能填写[list]。 
  [item]:定义遍历集合之后的参数名称 
  [open]:开始遍历之前需要拼接的SQL串 
  [close]:结束遍历之后需要拼接的SQL串 
  [separator]:遍历出的每个对象之间需要拼接的字符 
 --> 
<select id="findUsersByIdList" parameterType="java.util.List" resultType="user"> 
  SELECT * FROM USER 
  <where> 
    <if test="list != null and list.size > 0"> 
      <foreach collection="list" item="id" open="AND id IN (" close=")" separator=","> 
        #{id} 
      </foreach> 
    </if> 
  </where> 
</select>

2.4Mapper接口

//根据用户ID的集合查询用户列表(学习foreach标签之直接传ID集合) 
public List<User> findUsersByIdList (List<Integer> idList);

2.5测试代码

@Test 
public void findUsersByIdListTest() { 
  // 创建SqlSession 
  SqlSession sqlSession = sqlSessionFactory.openSession(); 
  // 通过SqlSession,获取mapper接口的动态代理对象 
  UserMapper userMapper = sqlSession.getMapper(UserMapper.class); 
  // 构造List<Integer>集合 
  List<Integer> idList = new ArrayList<Integer>(); 
  idList.add(1); 
  idList.add(10); 
    idList.add(16); 
  // 调用mapper对象的方法 
  List<User> list = userMapper.findUsersByIdList (idList); 
  System.out.println(list); 
  // 关闭SqlSession 
  sqlSession.close(); 
}


Das obige ist der detaillierte Inhalt vonDetaillierte Erläuterung des Beispielcodes der Mybatis-Zuordnungsdatei. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn