1. Complex mapping
1.1 result mapping
1.1.1 basic concepts
- resultType: if the attribute name of the entity is consistent with the field name in the table, the query results will be automatically encapsulated into the entity class
- ResutlMap: if the attribute name of the entity is inconsistent with the field name in the table, you can use ResutlMap to manually encapsulate it into the entity class
1.1.2 code cases
-
UserMapper.xml
<?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="cn.knightzz.mapper.UserMapper"> <resultMap id="UserResultMap" type="cn.knightzz.entity.User"> <!-- Encapsulate primary key fields --> <id property="uid" column="id"></id> <!-- Configure common fields --> <result property="usernameABC" column="username"></result> <result property="birthdayABC" column="birthday"></result> <result property="sexABC" column="sex"></result> <result property="addressABC" column="address"></result> </resultMap> <select id="findUserById" parameterType="int" resultMap="UserResultMap"> select * from user where id = #{id}; </select> </mapper>
-
Entity class
package cn.knightzz.entity; import java.util.Date; /** * @author Wang Tianci * @title: User * @projectName spring-aop-01 * @description: * @website http://knightzz.cn/ * @github https://github.com/knightzz1998 * @date 2022/1/15 22:00 */ public class User { /** * User id */ private Integer uid; /** * User name */ private String usernameABC; /** * User birthday */ private Date birthdayABC; /** * Gender */ private String sexABC; /** * address */ private String addressABC; // .... }
-
Test code
package cn.knightzz; import cn.knightzz.entity.User; import cn.knightzz.mapper.UserMapper; 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 org.junit.Test; import java.io.IOException; import java.io.InputStream; import java.util.List; public class MybatisTest { @Test public void findUserById() throws IOException { InputStream stream = Resources.getResourceAsStream("sqlMapConfig.xml"); SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(stream); // Turn on auto submit SqlSession sqlSession = factory.openSession(true); UserMapper mapper = sqlSession.getMapper(UserMapper.class); User user = mapper.findUserById(1); System.out.println(user); sqlSession.close(); } }
1.2 parameter injection
1.2.1 three methods of parameter injection
-
Use #{arg0}-#{argn} or #{param1}-#{paramn} to get parameters
<mapper namespace="com.lagou.mapper.UserMapper"> <select id="findByIdAndUsername1" resultType="user"> <!-- select * from user where id = #{arg0} and username = #{arg1} --> select * from user where id = #{param1} and username = #{param2} </select> </mapper>
-
Use annotation and introduce @ Param() annotation to obtain parameters
public interface UserMapper { public List<User> findByIdAndUsername2(@Param("id") Integer id, @Param("username") String username); }
-
Passing parameter recommendations using pojo objects
-
User entity class
package cn.knightzz.entity; import java.util.Date; public class User { /** * User id */ private Integer id; /** * User name */ private String username; /** * User birthday */ private Date birthday; /** * Gender */ private String sex; /** * address */ private String address; }
-
UserMapper interface
public List<User> findByIdAndUsername(User user);
-
UserMapper.xml
<mapper namespace="com.lagou.mapper.UserMapper"> <select id="findByIdAndUsername" parameterType="cn.knightzz.entity.User" resultType="cn.knightzz.entity.User"> select * from user where id = #{id} and username = #{username} </select> </mapper>
-
1.3 fuzzy query
1.3.1 requirements
- Requirement: query the user table according to username
1.3.2 code cases
-
UserMapper.xml
<?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="cn.knightzz.mapper.UserMapper"> <resultMap id="UserResultMap" type="cn.knightzz.entity.User"> <!-- Encapsulate primary key fields --> <id property="uid" column="id"></id> <!-- Configure common fields --> <result property="usernameABC" column="username"></result> <result property="birthdayABC" column="birthday"></result> <result property="sexABC" column="sex"></result> <result property="addressABC" column="address"></result> </resultMap> <select id="findUserById" parameterType="int" resultMap="UserResultMap"> select * from user where id = #{id}; </select> <select id="findUserByName" parameterType="string" resultMap="UserResultMap"> select * from user where username like #{username}; </select> </mapper>
-
UserMapper
package cn.knightzz.mapper; import cn.knightzz.entity.User; import java.util.List; public interface UserMapper { /** * Query user by id * @param id User id * @return */ public User findUserById(int id); /** * Query user by user name * @param username * @return */ public User findUserByName(String username); }
-
Test code
@Test public void findUserByName() throws IOException { InputStream stream = Resources.getResourceAsStream("sqlMapConfig.xml"); SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(stream); // Turn on auto submit SqlSession sqlSession = factory.openSession(true); UserMapper mapper = sqlSession.getMapper(UserMapper.class); User user = mapper.findUserByName("%answer%"); System.out.println(user); sqlSession.close(); }
1.3.3 difference between ${} and #{} [written test questions]
-
#{}: represents a placeholder
- Through #{} the preparedStatement, you can set the value in the placeholder and automatically convert java type and jdbc type,
- #{} can effectively prevent sql injection.
- #{} can receive simple type values or pojo property values.
- If parameterType transfers a single simple type value, #{} the name in parentheses is written casually.
-
${}: indicates a concatenated sql string
- Through ${}, the contents passed in by parameterType can be spliced into sql without jdbc type conversion, and sql injection will occur
Question. - ${} can receive simple type values or pojo attribute values. If parameterType transfers a single simple type value,
- ${} can only be value in parentheses
- Through ${}, the contents passed in by parameterType can be spliced into sql without jdbc type conversion, and sql injection will occur
2. Mapping file
2.1 return primary key
2.1.1 basic concepts
- In many cases, we need to insert a piece of data into the database and hope to get the data immediately
2.1.2 useGeneratedKeys
-
We can set the value of the primary key returned by the query by setting the value of useGeneratedKeys
-
useGeneratedKeys="true" declare the returned primary key. keyProperty="id" encapsulate the returned primary key value into the id property of the entity. Note that this entity refers to the id value of the parameter object, not the directly returned value
-
Note: it is only applicable to databases with self incremented primary keys. mysql and sqlserver support it, but oracle does not
-
Entity class User
package cn.knightzz.entity; import java.util.Date; /** * @author Wang Tianci * @title: User * @projectName spring-aop-01 * @description: * @website http://knightzz.cn/ * @github https://github.com/knightzz1998 * @date 2022/1/15 22:00 */ public class User { /** * User id */ private Integer id; /** * User name */ private String username; /** * User birthday */ private Date birthday; /** * Gender */ private String sex; /** * address */ private String address; // .... get / set }
-
UserMapper.xml configuration
<?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="cn.knightzz.mapper.UserMapper"> <!-- useGeneratedKeys="true" Declare return primary key keyProperty="id" Encapsulate the returned primary key value into the entity's id Attribute, Note that this entity refers to the object of the parameter --> <insert id="saveUser" parameterType="cn.knightzz.entity.User" useGeneratedKeys="true" keyProperty="id"> insert into user(username, birthday, sex, address) values (#{username}, #{birthday}, #{sex}, #{address}) </insert> </mapper>
-
Test code
package cn.knightzz.test; import cn.knightzz.entity.User; import cn.knightzz.mapper.UserMapper; 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 org.junit.Before; import org.junit.Test; import java.io.IOException; import java.io.InputStream; import java.util.Date; public class MyBatisMapperTest { private SqlSession sqlSession; @Before public void init() throws IOException { InputStream stream = Resources.getResourceAsStream("sqlMapConfig.xml"); SqlSessionFactory build = new SqlSessionFactoryBuilder().build(stream); this.sqlSession = build.openSession(true); } @Test public void saveUser() { UserMapper mapper = sqlSession.getMapper(UserMapper.class); User user = new User(); user.setUsername("KKK"); user.setSex("male"); user.setBirthday(new Date()); user.setAddress("Henan"); mapper.saveUser(user); System.out.println(user); sqlSession.close(); } }
2.1.3 selectKey
-
selectKey has a wide range of applications and supports all types of databases
-
The principle is: use SELECT LAST_INSERT_ID(); SQL built-in function, which can query the primary key id of the last inserted data
-
Common configuration
- keyColumn="id" specifies the primary key column name
- keyProperty="id" specifies that the primary key is encapsulated in the id property of the entity
- resultType="int" specifies the primary key type
- order="AFTER" is set before (after) the sql statement is executed
-
UserMapper.xml
<?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="cn.knightzz.mapper.UserMapper"> <!-- selectKey It has a wide range of applications and supports all types of databases keyColumn="id" Specifies the primary key column name keyProperty="id" Specifies how the primary key is encapsulated into the entity id Attribute resultType="int" Specify primary key type order="AFTER" Set in sql Execute the statement before (after) the statement is executed --> <insert id="saveUserBySelectKey" parameterType="cn.knightzz.entity.User" useGeneratedKeys="true" keyProperty="id"> <selectKey keyProperty="id" keyColumn="id" resultType="int" order="AFTER"> SELECT LAST_INSERT_ID(); </selectKey> insert into user(username, birthday, sex, address) values (#{username}, #{birthday}, #{sex}, #{address}) </insert> </mapper>
-
UserMapper
package cn.knightzz.mapper; import cn.knightzz.entity.User; import java.util.List; public interface UserMapper { /** * Insert user data * @param user * @return Return primary key */ public void saveUser(User user); /** * Return the primary key by selectKey * @param user */ public void saveUserBySelectKey(User user); }
-
Test code
package cn.knightzz.test; import cn.knightzz.entity.User; import cn.knightzz.mapper.UserMapper; 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 org.junit.Before; import org.junit.Test; import java.io.IOException; import java.io.InputStream; import java.util.Date; public class MyBatisMapperTest { private User user = new User(); private SqlSession sqlSession; private UserMapper mapper; @Before public void init() throws IOException { InputStream stream = Resources.getResourceAsStream("sqlMapConfig.xml"); SqlSessionFactory build = new SqlSessionFactoryBuilder().build(stream); sqlSession = build.openSession(true); mapper = sqlSession.getMapper(UserMapper.class); } @Test public void saveUserBySelectKey() { user.setUsername("KKK222"); user.setSex("female"); user.setBirthday(new Date()); user.setAddress("Henan"); mapper.saveUserBySelectKey(user); System.out.println(user); sqlSession.close(); } }
2.2 dynamic SQL
2.2.1 basic concepts
- When we want to execute different sql statements according to different conditions, we need to use dynamic sql
2.2.2 dynamic SQL < if >
-
UserMapper interface
/** * According to id, the latter * @param user * @return */ public User findUserByIdAndUsernameIf(User user);
-
UserMapper.xml
<select id="findUserByIdAndUsernameIf" parameterType="cn.knightzz.entity.User" resultType="cn.knightzz.entity.User"> select * from user <where> <if test="id != null"> AND id = #{id} </if> <if test="username != null"> AND username = #{username} </if> </where> </select>
-
Test code
package cn.knightzz.test; import cn.knightzz.entity.User; import cn.knightzz.mapper.UserMapper; 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 org.junit.Before; import org.junit.Test; import java.io.IOException; import java.io.InputStream; import java.util.Date; /** * @author Wang Tianci * @title: MyBatisMapperTest * @projectName spring-aop-01 * @description: * @website http://knightzz.cn/ * @github https://github.com/knightzz1998 * @date 2022/1/17 18:51 */ public class MyBatisMapperTest { private User user = new User(); private SqlSession sqlSession; private UserMapper mapper; @Before public void init() throws IOException { InputStream stream = Resources.getResourceAsStream("sqlMapConfig.xml"); SqlSessionFactory build = new SqlSessionFactoryBuilder().build(stream); sqlSession = build.openSession(true); mapper = sqlSession.getMapper(UserMapper.class); } @Test public void findUserByIdAndUsernameIf() { user.setUsername("KKK222"); User userByIdAndUsernameIf = mapper.findUserByIdAndUsernameIf(user); System.out.println(userByIdAndUsernameIf); sqlSession.close(); } }
2.2.3 dynamic SQL < set >
-
Dynamically update the user table data. If the attribute has a value, it will be updated. If there is no value, it will not be processed.
-
UserMapper interface
/** * Update user information and use the set tag * @param user */ public void updateUserBySet(User user);
-
UserMapper.xml
<?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="cn.knightzz.mapper.UserMapper"> <update id="updateUserBySet" parameterType="cn.knightzz.entity.User"> update user <set> <if test="username != null"> username = #{username} </if> <if test="birthday != null"> birthday = #{birthday} </if> <if test="sex != null"> sex = #{sex} </if> <if test="address != null"> address = #{address} </if> </set> where id = #{id} </update> </mapper>
-
Test code
package cn.knightzz.test; import cn.knightzz.entity.User; import cn.knightzz.mapper.UserMapper; 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 org.junit.Before; import org.junit.Test; import java.io.IOException; import java.io.InputStream; import java.util.Date; /** * @author Wang Tianci * @title: MyBatisMapperTest * @projectName spring-aop-01 * @description: * @website http://knightzz.cn/ * @github https://github.com/knightzz1998 * @date 2022/1/17 18:51 */ public class MyBatisMapperTest { private User user = new User(); private SqlSession sqlSession; private UserMapper mapper; @Before public void init() throws IOException { InputStream stream = Resources.getResourceAsStream("sqlMapConfig.xml"); SqlSessionFactory build = new SqlSessionFactoryBuilder().build(stream); sqlSession = build.openSession(true); mapper = sqlSession.getMapper(UserMapper.class); } @Test public void updateUserBySet() { user.setId(1); user.setUsername("KKK222"); mapper.updateUserBySet(user); sqlSession.close(); } }
2.2.4 dynamic SQL < foreach >
-
foreach is mainly used for loop traversal of data
For example: select * from user where id in (1,2,3) in such a statement, the passed in parameter part must depend on
foreach traversal can be realized. -
The < foreach > tag is used to traverse the collection. Its properties are:
-
Collection: represents the collection elements to traverse
-
open: represents the beginning of the statement
-
close: represents the end part
-
item: represents the variable name generated by traversing each element of the collection
-
sperator: represents the separator
-
UserMapper interface
/** * Query user list by id * @param ids * @return */ public List<User> findAllUserById(List<Integer> ids);
-
UserMapper.xml configuration
<select id="findAllUserById" parameterType="java.util.List" resultType="cn.knightzz.entity.User"> select * from user <where> /* collection: Represents the collection element to be traversed, usually written as collection or list open: Represents the beginning of a statement close: Representative closing part item: Represents the variable name generated by traversing each element of the collection sperator: Delegate separator */ <foreach collection="collection" open="id in (" close=")" item="id" separator=","> #{id} </foreach> </where> </select>
-
Test code
package cn.knightzz.test; import cn.knightzz.entity.User; import cn.knightzz.mapper.UserMapper; 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 org.junit.Before; import org.junit.Test; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.Date; import java.util.List; /** * @author Wang Tianci * @title: MyBatisMapperTest * @projectName spring-aop-01 * @description: * @website http://knightzz.cn/ * @github https://github.com/knightzz1998 * @date 2022/1/17 18:51 */ public class MyBatisMapperTest { private User user = new User(); private SqlSession sqlSession; private UserMapper mapper; @Before public void init() throws IOException { InputStream stream = Resources.getResourceAsStream("sqlMapConfig.xml"); SqlSessionFactory build = new SqlSessionFactoryBuilder().build(stream); sqlSession = build.openSession(true); mapper = sqlSession.getMapper(UserMapper.class); } @Test public void findAllUserById() { List<Integer> ids = new ArrayList<>(); ids.add(1); ids.add(2); ids.add(2024); List<User> userList = mapper.findAllUserById(ids); for (User user1 : userList) { System.out.println(user1); } sqlSession.close(); } }
2.2.5 dynamic SQL < SQL >
-
Duplicate sql can be extracted from the mapping file and referenced with include when used, so as to achieve the purpose of sql reuse
-
usage method
-
Extract common code
<sql id="selectUser"> select * from user </sql>
-
Introducing SQL code
/* Introducing SQL fragments*/ <include refid="selectUser"></include>
-
-
Code example
<sql id="selectUser"> select * from user </sql> <select id="findAllUserById" parameterType="java.util.List" resultType="cn.knightzz.entity.User"> /* Introducing SQL fragments*/ <include refid="selectUser"></include> <where> /* collection: Represents the collection element to be traversed, usually written as collection or list open: Represents the beginning of a statement close: Representative closing part item: Represents the variable name generated by traversing each element of the collection sperator: Delegate separator */ <foreach collection="collection" open="id in (" close=")" item="id" separator=","> #{id} </foreach> </where> </select>
2.3 paging plug-in
2.3.1 plugins plug-in
- MyBatis can use third-party plug-ins to extend its functions. The paging assistant PageHelper encapsulates the complex operations of paging
Loading, you can obtain paging related data in a simple way - Development steps:
- Import the coordinates of the generic PageHelper
- Configure the PageHelper plug-in in the mybatis core configuration file
- Test paging data acquisition
2.3.2 case realization
-
Introduce Maven dependency
<!-- Paging assistant --> <dependency> <groupId>com.github.pagehelper</groupId> <artifactId>pagehelper</artifactId> <version>3.7.5</version> </dependency> <dependency> <groupId>com.github.jsqlparser</groupId> <artifactId>jsqlparser</artifactId> <version>0.9.1</version> </dependency>
-
In sqlmapconfig Configuring plug-ins in XML
-
Special note: note that < plugins > should be placed in front of < environment > and behind < typealiases >
<!-- Configure plug-ins --> <plugins> <plugin interceptor="com.github.pagehelper.PageHelper"> <!-- 1. Designated dialect, Because different databases have different paging syntax, Database needs to be specified --> <property name="dialect" value="mysql"/> </plugin> </plugins>
-
UserMapper interface
/** * Query all user information * @return */ public List<User> findAll();
-
Test code
package cn.knightzz.test; import cn.knightzz.entity.User; import cn.knightzz.mapper.UserMapper; import com.github.pagehelper.PageHelper; import com.github.pagehelper.PageInfo; 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 org.junit.Before; import org.junit.Test; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.Date; import java.util.List; /** * @author Wang Tianci * @title: MyBatisMapperTest * @projectName spring-aop-01 * @description: * @website http://knightzz.cn/ * @github https://github.com/knightzz1998 * @date 2022/1/17 18:51 */ public class MyBatisMapperTest { private User user = new User(); private SqlSession sqlSession; private UserMapper mapper; @Before public void init() throws IOException { InputStream stream = Resources.getResourceAsStream("sqlMapConfig.xml"); SqlSessionFactory build = new SqlSessionFactoryBuilder().build(stream); sqlSession = build.openSession(true); mapper = sqlSession.getMapper(UserMapper.class); } @Test public void pageHelper() { // Set paging parameters: // pageNum: current page number // pageSize: number of data pieces displayed per page PageHelper.startPage(2, 2); List<User> allUsers = mapper.findAll(); for (User allUser : allUsers) { System.out.println(allUser); } PageInfo<User> pageInfo = new PageInfo<User>(allUsers); System.out.println("Total number of pieces:" + pageInfo.getTotal()); System.out.println("Total pages:" + pageInfo.getPages()); System.out.println("Current page:" + pageInfo.getPageNum()); System.out.println("Display length per page:" + pageInfo.getPageSize()); System.out.println("First page:" + pageInfo.isIsFirstPage()); System.out.println("Last page:" + pageInfo.isIsLastPage()); sqlSession.close(); } }
3. MyBatis multi table query
3.1 database relationship
3.1.1 relationship table type
- Relational database tables are divided into
- one-on-one
- One to many
- Many to many
3.1.2 relationship table cases
-
The ID number is one to one.
- A person can only have one ID number.
- An ID number can only belong to one person.
-
Users and orders are one to many, and orders and users are many to one
- One user can place multiple orders
- Multiple orders belong to the same user
-
Students and courses are many to many
- A student can take multiple courses
- A course can be taken by more than one student
-
In particular, an order is subordinate to only one user, so mybatis regards many to one as one to one
3.2 case environment
3.2.1 database table
DROP TABLE IF EXISTS `orders`; CREATE TABLE `orders` ( `id` INT(11) NOT NULL AUTO_INCREMENT, `ordertime` VARCHAR(255) DEFAULT NULL, `total` DOUBLE DEFAULT NULL, `uid` INT(11) DEFAULT NULL, PRIMARY KEY (`id`), KEY `uid` (`uid`), CONSTRAINT `orders_ibfk_1` FOREIGN KEY (`uid`) REFERENCES `user` (`id`) ) ENGINE = INNODB AUTO_INCREMENT = 4 DEFAULT CHARSET = utf8; -- ---------------------------- -- Records of orders -- ---------------------------- INSERT INTO `orders` VALUES ('1', '2020-12-12', '3000', '1'); INSERT INTO `orders` VALUES ('2', '2020-12-12', '4000', '1'); INSERT INTO `orders` VALUES ('3', '2020-12-12', '5000', '2'); -- ---------------------------- -- Table structure for sys_role -- ---------------------------- DROP TABLE IF EXISTS `sys_role`; CREATE TABLE `sys_role` ( `id` INT(11) NOT NULL AUTO_INCREMENT, `rolename` VARCHAR(255) DEFAULT NULL, `roleDesc` VARCHAR(255) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE = INNODB AUTO_INCREMENT = 3 DEFAULT CHARSET = utf8; -- ---------------------------- -- Records of sys_role -- ---------------------------- INSERT INTO `sys_role` VALUES ('1', 'CTO', 'CTO'); INSERT INTO `sys_role` VALUES ('2', 'CEO', 'CEO'); -- ---------------------------- -- Table structure for sys_user_role -- ---------------------------- DROP TABLE IF EXISTS `sys_user_role`; CREATE TABLE `sys_user_role` ( `userid` INT(11) NOT NULL, `roleid` INT(11) NOT NULL, PRIMARY KEY (`userid`, `roleid`), KEY `roleid` (`roleid`), CONSTRAINT `sys_user_role_ibfk_1` FOREIGN KEY (`userid`) REFERENCES `sys_role` (`id`), CONSTRAINT `sys_user_role_ibfk_2` FOREIGN KEY (`roleid`) REFERENCES `user` (`id`) ) ENGINE = INNODB DEFAULT CHARSET = utf8; -- ---------------------------- -- Records of sys_user_role -- ---------------------------- INSERT INTO `sys_user_role` VALUES ('1', '1'); INSERT INTO `sys_user_role` VALUES ('2', '1'); INSERT INTO `sys_user_role` VALUES ('1', '2'); INSERT INTO `sys_user_role` VALUES ('2', '2');
3.3 one to one
3.3.1 data model
-
The relationship between user table and order table is that a user has multiple orders, and an order belongs to only one user
-
One to one query requirement: query all orders and find out the users of each order at the same time
-
Query sql
select * from orders join user u on u.id = orders.uid
3.3.2 code cases
-
OrderMapper interface
package cn.knightzz.mapper; import cn.knightzz.entity.Order; import java.util.List; /** * @author Wang Tianci * @title: OrderMapper * @projectName spring-aop-01 * @description: * @website http://knightzz.cn/ * @github https://github.com/knightzz1998 * @date 2022/1/19 11:24 */ public interface OrderMapper { /** * Query order information and user information corresponding to the order * @return */ public List<Order> findAllWithUser(); }
-
Order entity class
package cn.knightzz.entity; import java.util.Date; /** * @author Wang Tianci * @title: Oder * @projectName spring-aop-01 * @description: * @website http://knightzz.cn/ * @github https://github.com/knightzz1998 * @date 2022/1/19 11:19 */ public class Order { /** * Order id */ private Integer id; /** * Order time */ private Date orderTime; /** * amount of money */ private double money; /** * User information to which the order belongs */ private User user; // ... get / set }
-
OrderMapper.xml
It should be noted that the User of < association property = "User" refers to the property value of the User object of the entity class Order
Mapping entity class attributes can use < association property = "user" javatype = "CN. Knightzz. Entity. User" >
<?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="cn.knightzz.mapper.OrderMapper"> <!-- One to one (many to one) use association Label Association property="user" Encapsulates the attribute name of the entity javaType="user" Encapsulates the attribute type of the entity --> <resultMap id="orderReturnMap" type="cn.knightzz.entity.Order"> <!-- Primary key --> <id property="id" column="id"></id> <result property="orderTime" column="ordertime"></result> <result property="money" column="total"></result> <!-- property : Order In the table User Property name of the object javaType : User Object's property type full path --> <association property="user" javaType="cn.knightzz.entity.User"> <!-- Encapsulate primary key --> <id property="id" column="id"></id> <result property="username" column="username"></result> <result property="birthday" column="birthday"></result> <result property="sex" column="sex"></result> <result property="address" column="address"></result> </association> </resultMap> <select id="findAllWithUser" resultMap="orderReturnMap"> select * from orders join user u on u.id = orders.uid </select> </mapper>
-
Test code
package cn.knightzz.test; import cn.knightzz.entity.Order; import cn.knightzz.entity.User; import cn.knightzz.mapper.OrderMapper; import cn.knightzz.mapper.UserMapper; import com.github.pagehelper.PageHelper; import com.github.pagehelper.PageInfo; 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 org.junit.After; import org.junit.Before; import org.junit.Test; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.Date; import java.util.List; /** * @author Wang Tianci * @title: MyBatisMapperTest * @projectName spring-aop-01 * @description: * @website http://knightzz.cn/ * @github https://github.com/knightzz1998 * @date 2022/1/17 18:51 */ public class MyBatisMapperTest { private User user = new User(); private SqlSession sqlSession; private UserMapper mapper; private OrderMapper orderMapper; @Before public void init() throws IOException { InputStream stream = Resources.getResourceAsStream("sqlMapConfig.xml"); SqlSessionFactory build = new SqlSessionFactoryBuilder().build(stream); sqlSession = build.openSession(true); mapper = sqlSession.getMapper(UserMapper.class); orderMapper = sqlSession.getMapper(OrderMapper.class); } @Test public void findAllWithUser(){ List<Order> allWithUsers = orderMapper.findAllWithUser(); for (Order allWithUser : allWithUsers) { System.out.println(allWithUser); } } @After public void destroy(){ sqlSession.close(); } }
3.4 one to many
3.4.1 data model
-
The relationship between user table and order table is that a user has multiple orders, and an order belongs to only one user
-
One to many query requirements: query all users and find the orders that the user has at the same time
-
Query sql
select *, o.id as oid from user left join orders o on user.id = o.uid
3.4.2 code cases
-
UserMapper interface
/** * Query all user information and their order information * @return */ public List<User> findAllWithOrder();
-
User entity class
package cn.knightzz.entity; import java.util.Date; import java.util.List; /** * @author Wang Tianci * @title: User * @projectName spring-aop-01 * @description: * @website http://knightzz.cn/ * @github https://github.com/knightzz1998 * @date 2022/1/15 22:00 */ public class User { /** * User id */ private Integer id; /** * User name */ private String username; /** * User birthday */ private Date birthday; /** * Gender */ private String sex; /** * address */ private String address; /** * Order list */ private List<Order> orderList; }
-
UserMapper.xml configuration
<resultMap id="userReturnMap" type="cn.knightzz.entity.User"> <!-- Set user table primary key and attribute mapping--> <id property="id" column="id"></id> <result property="username" column="username"></result> <result property="birthday" column="birthday"></result> <result property="sex" column="sex"></result> <result property="address" column="address"></result> <collection property="orderList" ofType="cn.knightzz.entity.Order"> <!-- Primary key --> <id property="id" column="oid"></id> <result property="orderTime" column="ordertime"></result> <result property="money" column="total"></result> </collection> </resultMap> <select id="findAllWithOrder" resultMap="userReturnMap"> select *, o.id as oid from user left join orders o on user.id = o.uid </select>
-
Test code
package cn.knightzz.test; import cn.knightzz.entity.Order; import cn.knightzz.entity.User; import cn.knightzz.mapper.OrderMapper; import cn.knightzz.mapper.UserMapper; import com.github.pagehelper.PageHelper; import com.github.pagehelper.PageInfo; 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 org.junit.After; import org.junit.Before; import org.junit.Test; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.Date; import java.util.List; /** * @author Wang Tianci * @title: MyBatisMapperTest * @projectName spring-aop-01 * @description: * @website http://knightzz.cn/ * @github https://github.com/knightzz1998 * @date 2022/1/17 18:51 */ public class MyBatisMapperTest { private User user = new User(); private SqlSession sqlSession; private UserMapper mapper; private OrderMapper orderMapper; @Before public void init() throws IOException { InputStream stream = Resources.getResourceAsStream("sqlMapConfig.xml"); SqlSessionFactory build = new SqlSessionFactoryBuilder().build(stream); sqlSession = build.openSession(true); mapper = sqlSession.getMapper(UserMapper.class); orderMapper = sqlSession.getMapper(OrderMapper.class); } @Test public void findAllWithOrder(){ List<User> allWithOrders = mapper.findAllWithOrder(); for (User allWithOrder : allWithOrders) { System.out.println(allWithOrder); } } @After public void destroy(){ sqlSession.close(); } }
3.5 many to many
3.5.1 data model
-
The relationship between user table and role table is that a user has multiple roles and a role is used by multiple users
-
Many to many query requirements: query all users and find all roles of the user at the same time
-
Query SQL
select * from user left join sys_user_role sur on user.id = sur.userid inner join sys_role sr on sur.roleid = sr.id
3.5.2 code cases
- User and SysRole entity classes
package cn.knightzz.entity; import java.util.Date; import java.util.List; public class User { private Integer id; private String username; private Date birthday; private String sex; private String address; /** * Represents the list of roles associated with the current user */ private List<SysRole> roleList; }
package cn.knightzz.entity; public class SysRole { private Integer id; private String roleName; private String roleDesc; // get /set ... }
-
UserMapper interface
/** * Find users and their permission list * @return */ public List<User> findAllWithRole();
-
UserMapper.xml configuration`
<resultMap id="userRoleListMap" type="cn.knightzz.entity.User"> <!-- Set user table primary key and attribute mapping--> <id property="id" column="id"></id> <result property="username" column="username"></result> <result property="birthday" column="birthday"></result> <result property="sex" column="sex"></result> <result property="address" column="address"></result> <collection property="roleList" ofType="cn.knightzz.entity.SysRole"> <!-- Primary key --> <id property="id" column="roleid"></id> <result property="roleName" column="rolename"></result> <result property="roleDesc" column="roleDesc"></result> </collection> </resultMap> <select id="findAllWithRole" resultMap="userRoleListMap"> select * from user left join sys_user_role sur on user.id = sur.userid inner join sys_role sr on sur.roleid = sr.id </select>
-
Test code
package cn.knightzz.test; import cn.knightzz.entity.Order; import cn.knightzz.entity.User; import cn.knightzz.mapper.OrderMapper; import cn.knightzz.mapper.UserMapper; import com.github.pagehelper.PageHelper; import com.github.pagehelper.PageInfo; 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 org.junit.After; import org.junit.Before; import org.junit.Test; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.Date; import java.util.List; /** * @author Wang Tianci * @title: MyBatisMapperTest * @projectName spring-aop-01 * @description: * @website http://knightzz.cn/ * @github https://github.com/knightzz1998 * @date 2022/1/17 18:51 */ public class MyBatisMapperTest { private User user = new User(); private SqlSession sqlSession; private UserMapper mapper; private OrderMapper orderMapper; @Before public void init() throws IOException { InputStream stream = Resources.getResourceAsStream("sqlMapConfig.xml"); SqlSessionFactory build = new SqlSessionFactoryBuilder().build(stream); sqlSession = build.openSession(true); mapper = sqlSession.getMapper(UserMapper.class); orderMapper = sqlSession.getMapper(OrderMapper.class); } @Test public void findAllWithRole(){ List<User> allWithRoles = mapper.findAllWithRole(); for (User allWithRole : allWithRoles) { System.out.println(allWithRole); } } @After public void destroy(){ sqlSession.close(); } }
4. MyBatis nested query
4.1 basic concepts
-
Nested query is to split the joint query statements in the original multi table query into a single table query, and then nest them in one table using the syntax of mybatis
Get up.
4.2 advantages and disadvantages
- Advantages: simplify multi table query operations
- Disadvantages: execute multiple sql statements, wasting database performance