MyBatis learning summary (4) - resolve the conflict between field names and entity class attribute names
In normal development, the field names in our table and the attribute names of the entity class corresponding to the table are not necessarily exactly the same. Let's demonstrate how to resolve the conflict between the field name and the entity class attribute name in this case.
1. Prepare the tables and data needed for the presentation
CREATE TABLE orders( order_id INT PRIMARY KEY AUTO_INCREMENT, order_no VARCHAR(20), order_price FLOAT ); INSERT INTO orders(order_no, order_price) VALUES('aaaa', 23); INSERT INTO orders(order_no, order_price) VALUES('bbbb', 33); INSERT INTO orders(order_no, order_price) VALUES('cccc', 22);
Second, define the entity class
1 package me.gacl.domain; 2 3 /** 4 * @author gacl 5 * Define the entity class corresponding to the orders table 6 */ 7 public class Order { 8 /** 9 * 10 CREATE TABLE orders( 11 order_id INT PRIMARY KEY AUTO_INCREMENT, 12 order_no VARCHAR(20), 13 order_price FLOAT 14 ); 15 */ 16 17 //The attribute name in the Order entity class is different from the field name in the orders table 18 private int id; //id===>order_id 19 private String orderNo; //orderNo===>order_no 20 private float price; //price===>order_price 21 22 public int getId() { 23 return id; 24 } 25 26 public void setId(int id) { 27 this.id = id; 28 } 29 30 public String getOrderNo() { 31 return orderNo; 32 } 33 34 public void setOrderNo(String orderNo) { 35 this.orderNo = orderNo; 36 } 37 38 public float getPrice() { 39 return price; 40 } 41 42 public void setPrice(float price) { 43 this.price = price; 44 } 45 46 @Override 47 public String toString() { 48 return "Order [id=" + id + ", orderNo=" + orderNo + ", price=" + price+ "]"; 49 } 50 }
3. Write test code
3.1, write SQL xml mapping file
1. Create an orderMapper.xml file. The content of orderMapper.xml is as follows:
1 <?xml version="1.0" encoding="UTF-8" ?> 2 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> 3 <!-- Specify a unique namespace for this mapper, the value of the namespace is customarily set to the package name + sql mapping file name, so that the value of the namespace can be guaranteed to be unique 4 For example, namespace="me.gacl.mapping.orderMapper" is me.gacl.mapping (package name) + orderMapper (orderMapper.xml file removes the suffix) 5 --> 6 <mapper namespace="me.gacl.mapping.orderMapper"> 7 8 <!-- 9 Obtain an order object based on the id query. Using this query can not query the results we want. 10 This is mainly because the attribute name of the entity class does not correspond to the field name of the database, so the corresponding record cannot be queried. 11 --> 12 <select id="getOrderById" parameterType="int" 13 resultType="me.gacl.domain.Order"> 14 select * from orders where order_id=#{id} 15 </select> 16 17 <!-- 18 Obtain an order object according to the id query. Using this query, we can query the results we want normally. 19 This is because we assign the field names of the query to an alias that is the same as the attribute name of the entity class, so that the attribute name of the entity class and the field name in the query result can be in one-to-one correspondence. 20 --> 21 <select id="selectOrder" parameterType="int" 22 resultType="me.gacl.domain.Order"> 23 select order_id id, order_no orderNo,order_price price from orders where order_id=#{id} 24 </select> 25 26 <!-- 27 Obtain an order object according to the id query. Using this query, we can query the results we want normally. 28 This is because we map the entity class attribute name and table field name one-to-one correspondence through <resultMap> --> 29 <select id="selectOrderResultMap" parameterType="int" resultMap="orderResultMap"> 30 select * from orders where order_id=#{id} 31 </select> 32 <!--Map the corresponding relationship between the attribute name of the entity class and the field name of the table through <resultMap>--> 33 <resultMap type="me.gacl.domain.Order" id="orderResultMap"> 34 <!-- Use the id attribute to map the primary key field --> 35 <id property="id" column="order_id"/> 36 <!-- Use the result attribute to map non-primary key fields --> 37 <result property="orderNo" column="order_no"/> 38 <result property="price" column="order_price"/> 39 </resultMap> 40 41 </mapper>
2. Register the orderMapper.xml mapping file in the conf.xml file
<mappers> <!-- Register the orderMapper.xml file, orderMapper.xml is located under the package me.gacl.mapping, so the resource is written as me/gacl/mapping/orderMapper.xml--> <mapper resource="me/gacl/mapping/orderMapper.xml"/> </mappers>
3.2, write unit test code
1 package me.gacl.test; 2 3 import me.gacl.domain.Order; 4 import me.gacl.util.MyBatisUtil; 5 import org.apache.ibatis.session.SqlSession; 6 import org.junit.Test; 7 8 public class Test2 { 9 10 @Test 11 public void testGetOrderById(){ 12 SqlSession sqlSession = MyBatisUtil.getSqlSession(); 13 /** 14 * The identification string of the mapping sql, 15 * me.gacl.mapping.orderMapper is the value of the namespace attribute of the mapper tag in the orderMapper.xml file, 16 * getOrderById is the id attribute value of the select tag, you can find the SQL to be executed through the id attribute value of the select tag 17 */ 18 String statement = "me.gacl.mapping.orderMapper.getOrderById";//Map sql identification string 19 //Execute the query operation, and automatically encapsulate the query result into an Order object and return it 20 Order order = sqlSession.selectOne(statement,1);//Query the record with id 1 in the orders table 21 //After executing SQL using SqlSession, you need to close the SqlSession 22 sqlSession.close(); 23 System.out.println(order);//Print result: null, that is, no corresponding record is queried 24 } 25 26 @Test 27 public void testGetOrderById2(){ 28 SqlSession sqlSession = MyBatisUtil.getSqlSession(); 29 /** 30 * The identification string of the mapped sql, 31 * me.gacl.mapping.orderMapper is the value of the namespace attribute of the mapper tag in the orderMapper.xml file, 32 * selectOrder is the id attribute value of the select tag, and the SQL to be executed can be found through the id attribute value of the select tag 33 */ 34 String statement = "me.gacl.mapping.orderMapper.selectOrder";//Map sql identification string 35 //Execute the query operation, and automatically encapsulate the query result into an Order object and return it 36 Order order = sqlSession.selectOne(statement,1);//Query the record with id 1 in the orders table 37 //After executing SQL using SqlSession, you need to close the SqlSession 38 sqlSession.close(); 39 System.out.println(order);//Print result: Order [id=1, orderNo=aaaa, price=23.0] 40 } 41 42 @Test 43 public void testGetOrderById3(){ 44 SqlSession sqlSession = MyBatisUtil.getSqlSession(); 45 /** 46 * The identification string of the mapping sql, 47 * me.gacl.mapping.orderMapper is the value of the namespace attribute of the mapper tag in the orderMapper.xml file, 48 * selectOrderResultMap is the id attribute value of the select tag, and the SQL to be executed can be found through the id attribute value of the select tag 49 */ 50 String statement = "me.gacl.mapping.orderMapper.selectOrderResultMap";//Map sql identification string 51 //Execute the query operation, and automatically encapsulate the query result into an Order object and return it 52 Order order = sqlSession.selectOne(statement,1);//Query the record with id 1 in the orders table 53 //After executing SQL using SqlSession, you need to close the SqlSession 54 sqlSession.close(); 55 System.out.println(order);//Print result: Order [id=1, orderNo=aaaa, price=23.0] 56 } 57 }
Result of executing unit test:
1. The testGetOrderById method returns a null after executing the query.
2. After the testGetOrderById2 method and the testGetOrderById3 method execute the query, the desired result can be obtained normally.
4. Summary
The above test code demonstrates the problem that when the attribute name in the entity class is inconsistent with the field name in the table, the corresponding result cannot be queried when using MyBatis for query operation, and two methods are adopted for the problem:
Solution 1 : Define the alias of the field name in the sql statement of the query , so that the alias of the field name is consistent with the attribute name of the entity class, so that the field name of the table and the attribute name of the entity class can be in one-to-one correspondence. The way is to solve the mapping relationship between field names and attribute names by defining aliases in SQL statements.
Solution 2 : Use <resultMap> to map the one-to-one correspondence between field names and entity class attribute names. This method uses the solution provided by MyBatis to solve the mapping relationship between field names and attribute names.
In normal development, the field names in our table and the attribute names of the entity class corresponding to the table are not necessarily exactly the same. Let's demonstrate how to resolve the conflict between the field name and the entity class attribute name in this case.
1. Prepare the tables and data needed for the presentation
CREATE TABLE orders( order_id INT PRIMARY KEY AUTO_INCREMENT, order_no VARCHAR(20), order_price FLOAT ); INSERT INTO orders(order_no, order_price) VALUES('aaaa', 23); INSERT INTO orders(order_no, order_price) VALUES('bbbb', 33); INSERT INTO orders(order_no, order_price) VALUES('cccc', 22);
Second, define the entity class
1 package me.gacl.domain; 2 3 /** 4 * @author gacl 5 * Define the entity class corresponding to the orders table 6 */ 7 public class Order { 8 /** 9 * 10 CREATE TABLE orders( 11 order_id INT PRIMARY KEY AUTO_INCREMENT, 12 order_no VARCHAR(20), 13 order_price FLOAT 14 ); 15 */ 16 17 //The attribute name in the Order entity class is different from the field name in the orders table 18 private int id; //id===>order_id 19 private String orderNo; //orderNo===>order_no 20 private float price; //price===>order_price 21 22 public int getId() { 23 return id; 24 } 25 26 public void setId(int id) { 27 this.id = id; 28 } 29 30 public String getOrderNo() { 31 return orderNo; 32 } 33 34 public void setOrderNo(String orderNo) { 35 this.orderNo = orderNo; 36 } 37 38 public float getPrice() { 39 return price; 40 } 41 42 public void setPrice(float price) { 43 this.price = price; 44 } 45 46 @Override 47 public String toString() { 48 return "Order [id=" + id + ", orderNo=" + orderNo + ", price=" + price+ "]"; 49 } 50 }
3. Write test code
3.1, write SQL xml mapping file
1. Create an orderMapper.xml file. The content of orderMapper.xml is as follows:
1 <?xml version="1.0" encoding="UTF-8" ?> 2 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> 3 <!-- Specify a unique namespace for this mapper, the value of the namespace is customarily set to the package name + sql mapping file name, so that the value of the namespace can be guaranteed to be unique 4 For example, namespace="me.gacl.mapping.orderMapper" is me.gacl.mapping (package name) + orderMapper (orderMapper.xml file removes the suffix) 5 --> 6 <mapper namespace="me.gacl.mapping.orderMapper"> 7 8 <!-- 9 Obtain an order object based on the id query. Using this query can not query the results we want. 10 This is mainly because the attribute name of the entity class does not correspond to the field name of the database, so the corresponding record cannot be queried. 11 --> 12 <select id="getOrderById" parameterType="int" 13 resultType="me.gacl.domain.Order"> 14 select * from orders where order_id=#{id} 15 </select> 16 17 <!-- 18 Obtain an order object according to the id query. Using this query, we can query the results we want normally. 19 This is because we assign the field names of the query to an alias that is the same as the attribute name of the entity class, so that the attribute name of the entity class and the field name in the query result can be in one-to-one correspondence. 20 --> 21 <select id="selectOrder" parameterType="int" 22 resultType="me.gacl.domain.Order"> 23 select order_id id, order_no orderNo,order_price price from orders where order_id=#{id} 24 </select> 25 26 <!-- 27 Obtain an order object according to the id query. Using this query, we can query the results we want normally. 28 This is because we map the entity class attribute name and table field name one-to-one correspondence through <resultMap> --> 29 <select id="selectOrderResultMap" parameterType="int" resultMap="orderResultMap"> 30 select * from orders where order_id=#{id} 31 </select> 32 <!--Map the corresponding relationship between the attribute name of the entity class and the field name of the table through <resultMap>--> 33 <resultMap type="me.gacl.domain.Order" id="orderResultMap"> 34 <!-- Use the id attribute to map the primary key field --> 35 <id property="id" column="order_id"/> 36 <!-- Use the result attribute to map non-primary key fields --> 37 <result property="orderNo" column="order_no"/> 38 <result property="price" column="order_price"/> 39 </resultMap> 40 41 </mapper>
2. Register the orderMapper.xml mapping file in the conf.xml file
<mappers> <!-- Register the orderMapper.xml file, orderMapper.xml is located under the package me.gacl.mapping, so the resource is written as me/gacl/mapping/orderMapper.xml--> <mapper resource="me/gacl/mapping/orderMapper.xml"/> </mappers>
3.2, write unit test code
1 package me.gacl.test; 2 3 import me.gacl.domain.Order; 4 import me.gacl.util.MyBatisUtil; 5 import org.apache.ibatis.session.SqlSession; 6 import org.junit.Test; 7 8 public class Test2 { 9 10 @Test 11 public void testGetOrderById(){ 12 SqlSession sqlSession = MyBatisUtil.getSqlSession(); 13 /** 14 * The identification string of the mapping sql, 15 * me.gacl.mapping.orderMapper is the value of the namespace attribute of the mapper tag in the orderMapper.xml file, 16 * getOrderById is the id attribute value of the select tag, you can find the SQL to be executed through the id attribute value of the select tag 17 */ 18 String statement = "me.gacl.mapping.orderMapper.getOrderById";//Map sql identification string 19 //Execute the query operation, and automatically encapsulate the query result into an Order object and return it 20 Order order = sqlSession.selectOne(statement,1);//Query the record with id 1 in the orders table 21 //After executing SQL using SqlSession, you need to close the SqlSession 22 sqlSession.close(); 23 System.out.println(order);//Print result: null, that is, no corresponding record is queried 24 } 25 26 @Test 27 public void testGetOrderById2(){ 28 SqlSession sqlSession = MyBatisUtil.getSqlSession(); 29 /** 30 * The identification string of the mapped sql, 31 * me.gacl.mapping.orderMapper is the value of the namespace attribute of the mapper tag in the orderMapper.xml file, 32 * selectOrder is the id attribute value of the select tag, and the SQL to be executed can be found through the id attribute value of the select tag 33 */ 34 String statement = "me.gacl.mapping.orderMapper.selectOrder";//Map sql identification string 35 //Execute the query operation, and automatically encapsulate the query result into an Order object and return it 36 Order order = sqlSession.selectOne(statement,1);//Query the record with id 1 in the orders table 37 //After executing SQL using SqlSession, you need to close the SqlSession 38 sqlSession.close(); 39 System.out.println(order);//Print result: Order [id=1, orderNo=aaaa, price=23.0] 40 } 41 42 @Test 43 public void testGetOrderById3(){ 44 SqlSession sqlSession = MyBatisUtil.getSqlSession(); 45 /** 46 * The identification string of the mapping sql, 47 * me.gacl.mapping.orderMapper is the value of the namespace attribute of the mapper tag in the orderMapper.xml file, 48 * selectOrderResultMap is the id attribute value of the select tag, and the SQL to be executed can be found through the id attribute value of the select tag 49 */ 50 String statement = "me.gacl.mapping.orderMapper.selectOrderResultMap";//Map sql identification string 51 //Execute the query operation, and automatically encapsulate the query result into an Order object and return it 52 Order order = sqlSession.selectOne(statement,1);//Query the record with id 1 in the orders table 53 //After executing SQL using SqlSession, you need to close the SqlSession 54 sqlSession.close(); 55 System.out.println(order);//Print result: Order [id=1, orderNo=aaaa, price=23.0] 56 } 57 }
Result of executing unit test:
1. The testGetOrderById method returns a null after executing the query.
2. After the testGetOrderById2 method and the testGetOrderById3 method execute the query, the desired result can be obtained normally.
4. Summary
The above test code demonstrates the problem that when the attribute name in the entity class is inconsistent with the field name in the table, the corresponding result cannot be queried when using MyBatis for query operation, and two methods are adopted for the problem:
Solution 1 : Define the alias of the field name in the sql statement of the query , so that the alias of the field name is consistent with the attribute name of the entity class, so that the field name of the table and the attribute name of the entity class can be in one-to-one correspondence. The way is to solve the mapping relationship between field names and attribute names by defining aliases in SQL statements.
Solution 2 : Use <resultMap> to map the one-to-one correspondence between field names and entity class attribute names. This method uses the solution provided by MyBatis to solve the mapping relationship between field names and attribute names.