Mybatis注解开发
(使用了二级缓存, 多表查询, 延迟加载)
项目结构
配置文件
-
pom.xml
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.xiaoge</groupId> <artifactId>annotationOne2Many</artifactId> <version>1.0-SNAPSHOT</version> <packaging>jar</packaging> <dependencies> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.4.5</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.13</version> </dependency> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> </dependency> </dependencies> </project>
-
jdbcConfig.properties
jdbc.driver=com.mysql.cj.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/eesy_mybatis jdbc.username=root jdbc.password=123456
-
SqlMapConfig.xml(重点settings)
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <!-- 引入外部配置文件 --> <properties resource="jdbcConfig.properties"></properties> <!-- 配置开启二级缓存 --> <settings> <setting name="cacheEnabled" value="true"/> </settings> <!-- 配置别名 --> <typeAliases> <package name="com.xiaoge.domain"></package> </typeAliases> <!-- 配置环境 --> <environments default="mysql"> <environment id="mysql"> <transactionManager type="JDBC"></transactionManager> <dataSource type="POOLED"> <property name="driver" value="${jdbc.driver}"></property> <property name="url" value="${jdbc.url}"></property> <property name="username" value="${jdbc.username}"></property> <property name="password" value="${jdbc.password}"></property> </dataSource> </environment> </environments> <!-- 指定带有注解的dao接口所在位置 --> <mappers> <package name="com.xiaoge.dao"></package> </mappers> </configuration>
实体类
-
User(注意: 使用二级缓存是一定要继承Serializable, 要不然就会报一个序列化的错误)
package com.xiaoge.domain; import java.io.Serializable; import java.util.Date; import java.util.List; /** * @Author: 潇哥 * @DateTime: 2020/3/18 下午4:03 * @Description: TODO */ public class User implements Serializable { private Integer userId; private String userName; private Date userBirthday; private String userSex; private String userAddress; // 一对多关系映射: 一个用户对应多个账户 private List<Account> accounts; public List<Account> getAccounts() { return accounts; } public void setAccounts(List<Account> accounts) { this.accounts = accounts; } public Integer getUserId() { return userId; } public void setUserId(Integer userId) { this.userId = userId; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public Date getUserBirthday() { return userBirthday; } public void setUserBirthday(Date userBirthday) { this.userBirthday = userBirthday; } public String getUserSex() { return userSex; } public void setUserSex(String userSex) { this.userSex = userSex; } public String getUserAddress() { return userAddress; } public void setUserAddress(String userAddress) { this.userAddress = userAddress; } @Override public String toString() { return "User{" + "userId=" + userId + ", userName='" + userName + '\'' + ", userBirthday=" + userBirthday + ", userSex='" + userSex + '\'' + ", userAddress='" + userAddress + '\'' + '}'; } }
-
Account
package com.xiaoge.domain; import java.io.Serializable; /** * @Author: 潇哥 * @DateTime: 2020/3/18 下午5:32 * @Description: TODO */ public class Account implements Serializable { private Integer id; private Integer uid; private Double money; // 多对一 (mybatis中称之为一对一) 映射: 一个账户只能属于一个用户 private User user; public User getUser() { return user; } public void setUser(User user) { this.user = user; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public Integer getUid() { return uid; } public void setUid(Integer uid) { this.uid = uid; } public Double getMoney() { return money; } public void setMoney(Double money) { this.money = money; } @Override public String toString() { return "Account{" + "id=" + id + ", uid=" + uid + ", money=" + money + '}'; } }
持久层接口
-
UserDao
package com.xiaoge.dao; import com.xiaoge.domain.User; import org.apache.ibatis.annotations.*; import org.apache.ibatis.mapping.FetchType; import java.util.List; /** * @Author: 潇哥 * @DateTime: 2020/3/18 下午4:05 * @Description: TODO * 在mybatis中针对, CRUD一共有四个注解 * @Select @Insert @Update @Delete */ // 开启二级缓存 就像xml里的<cache /> @CacheNamespace(blocking = true) public interface UserDao { /** * 查询所有 * @return */ @Select("select * from user") // 实现xml里的resultMap的映射关系 @Results( id = "userMap", value = { /* id = true id是主键 column数据库字段 property实体类属性 把 该实体类对应的属性 和 数据库表对应的字段意义匹配 */ @Result(id = true, column = "id", property = "userId"), @Result(column = "username", property = "userName"), @Result(column = "sex", property = "userSex"), @Result(column = "birthday", property = "userBirthday"), @Result(column = "address", property = "userAddress"), /* fetchType = FetchType.LAZY 延迟加载 many = @Many 多个 select = "com.xiaoge.dao.AccountDao.findAccountByUid" 指定方法 column = "id"的值传递给这个方法 property = "accounts" 实体类属性 */ @Result(column = "id", property = "accounts", many = @Many(select = "com.xiaoge.dao.AccountDao.findAccountByUid", fetchType = FetchType.LAZY)) } ) public List<User> findAll(); /** * 根据id查询用户 * @param id */ @Select("select * from user where id = #{id}") @ResultMap(value = {"userMap"}) public User findById(Integer id); /** * 根据用户名模糊查询 * @param username * @return */ @Select("select * from user where username like #{username}") @ResultMap(value = {"userMap"}) public List<User> findUserByName(String username); }
-
AccountDao
package com.xiaoge.dao; import com.xiaoge.domain.Account; import org.apache.ibatis.annotations.*; import org.apache.ibatis.mapping.FetchType; import java.util.List; /** * @Author: 潇哥 * @DateTime: 2020/3/18 下午5:33 * @Description: TODO */ public interface AccountDao { /** * 查询所有账户, 并且获取每个账户所属的用户信息 * @return */ @Select("select * from account") @Results( id = "accountMap", value = { @Result(id = true, property = "id", column = "id"), @Result(property = "uid", column = "uid"), @Result(property = "money", column = "money"), /* 它就是xml里的association fetchType = FetchType.EAGER: 立即加载 fetchType = FetchType.LAZY: 延迟加载 select: 指定方法 全限定类名 column: 传递给这个方法的值 property: select + column 查询出来的值 对应的属性值 */ @Result(property = "user", column = "uid", one = @One(select="com.xiaoge.dao.UserDao.findById", fetchType = FetchType.EAGER)) } ) public List<Account> findAll(); @Select("select * from account where uid = #{uid}") public Account findAccountByUid(Integer uid); }
测试持久层接口方法
-
SecondLevelCacheTest
package com.xiaoge.test; import com.xiaoge.dao.UserDao; import com.xiaoge.domain.User; 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; /** * @Author: 潇哥 * @DateTime: 2020/3/18 下午6:18 * @Description: TODO */ public class SecondLevelCacheTest { private InputStream is; private SqlSessionFactory factory; @Before public void init() throws IOException { is = Resources.getResourceAsStream("SqlMapConfig.xml"); SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder(); factory = builder.build(is); } @After public void destroy() throws IOException { if (is != null) { is.close(); } } /** * 测试二缓 存根据id查询用户信息 */ @Test public void findOneTest() { SqlSession sqlSession1 = factory.openSession(); UserDao userDao1 = sqlSession1.getMapper(UserDao.class); User user1 = userDao1.findById(59); System.out.println(user1); sqlSession1.close(); // 释放一级缓存 SqlSession sqlSession2 = factory.openSession(); // 再次打开SqlSession UserDao userDao2 = sqlSession2.getMapper(UserDao.class); User user2 = userDao2.findById(59); System.out.println(user2); sqlSession2.close(); // 运行结果 2020-03-18 19:47:20,785 1694 [ main] DEBUG om.xiaoge.dao.UserDao.findById - ==> Preparing: select * from user where id = ? // 这里 2020-03-18 19:47:20,836 1745 [ main] DEBUG om.xiaoge.dao.UserDao.findById - ==> Parameters: 59(Integer) 2020-03-18 19:47:20,942 1851 [ main] DEBUG om.xiaoge.dao.UserDao.findById - <== Total: 1 2020-03-18 19:47:20,944 1853 [ main] DEBUG ao.AccountDao.findAccountByUid - ==> Preparing: select * from account where uid = ? // 这里 2020-03-18 19:47:20,945 1854 [ main] DEBUG ao.AccountDao.findAccountByUid - ==> Parameters: 59(Integer) 2020-03-18 19:47:20,946 1855 [ main] DEBUG ao.AccountDao.findAccountByUid - <== Total: 0 User{userId=59, userName='李白 last insertid', userBirthday=Wed Mar 11 18:17:20 CST 2020, userSex='男', userAddress='北京'} // 这里 2020-03-18 19:47:20,959 1868 [ main] DEBUG ansaction.jdbc.JdbcTransaction - Resetting autocommit to true on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@8297b3a] 2020-03-18 19:47:20,960 1869 [ main] DEBUG ansaction.jdbc.JdbcTransaction - Closing JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@8297b3a] 2020-03-18 19:47:20,960 1869 [ main] DEBUG source.pooled.PooledDataSource - Returned connection 136936250 to pool. 2020-03-18 19:47:20,964 1873 [ main] DEBUG com.xiaoge.dao.UserDao - Cache Hit Ratio [com.xiaoge.dao.UserDao]: 0.5 User{userId=59, userName='李白 last insertid', userBirthday=Wed Mar 11 18:17:20 CST 2020, userSex='男', userAddress='北京'} // 这里 // 只去数据库查询了一次, 记住这里水染使用了延迟加载, 但是你是查询的单个用户, 所以会查账户信息 } }
-
AccountTest
package com.xiaoge.test; import com.xiaoge.dao.AccountDao; import com.xiaoge.domain.Account; 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.List; /** * @Author: 潇哥 * @DateTime: 2020/3/18 下午4:41 * @Description: TODO */ public class AccountTest { private InputStream is; private SqlSessionFactory factory; private SqlSession sqlSession; private AccountDao accountDao; @Before public void init() throws IOException { is = Resources.getResourceAsStream("SqlMapConfig.xml"); SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder(); factory = builder.build(is); sqlSession = factory.openSession(); accountDao = sqlSession.getMapper(AccountDao.class); } @After public void destroy() throws IOException { if (sqlSession != null) { sqlSession.commit(); sqlSession.close(); } if (is != null) { is.close(); } } /** * 查询所有 */ @Test public void findAllTest() { List<Account> accounts = accountDao.findAll(); for (Account account : accounts) { System.out.println("--------每个账户信息-------"); System.out.println(account); System.out.println(account.getUser()); } // 运行结果 这里用的立即加载, 因为是多对一, 在mybatis中是一对一, 一对一我设置的是立即加载 --------每个账户信息------- Account{id=1, uid=41, money=1000.0} 2020-03-18 19:52:54,359 1618 [ main] DEBUG ao.AccountDao.findAccountByUid - ==> Preparing: select * from account where uid = ? 2020-03-18 19:52:54,359 1618 [ main] DEBUG ao.AccountDao.findAccountByUid - ==> Parameters: 41(Integer) 2020-03-18 19:52:54,361 1620 [ main] DEBUG ao.AccountDao.findAccountByUid - <== Total: 1 User{userId=41, userName='老王', userBirthday=Wed Feb 28 07:47:08 CST 2018, userSex='男', userAddress='北京'} --------每个账户信息------- Account{id=2, uid=42, money=1000.0} 2020-03-18 19:52:54,367 1626 [ main] DEBUG ao.AccountDao.findAccountByUid - ==> Preparing: select * from account where uid = ? 2020-03-18 19:52:54,368 1627 [ main] DEBUG ao.AccountDao.findAccountByUid - ==> Parameters: 42(Integer) 2020-03-18 19:52:54,369 1628 [ main] DEBUG ao.AccountDao.findAccountByUid - <== Total: 1 User{userId=42, userName='小二王', userBirthday=Sat Mar 03 05:09:37 CST 2018, userSex='女', userAddress='北京金燕龙'} --------每个账户信息------- Account{id=3, uid=43, money=2000.0} 2020-03-18 19:52:54,370 1629 [ main] DEBUG ao.AccountDao.findAccountByUid - ==> Preparing: select * from account where uid = ? 2020-03-18 19:52:54,371 1630 [ main] DEBUG ao.AccountDao.findAccountByUid - ==> Parameters: 43(Integer) 2020-03-18 19:52:54,374 1633 [ main] DEBUG ao.AccountDao.findAccountByUid - <== Total: 2 User{userId=43, userName='小二王', userBirthday=Mon Mar 05 01:34:34 CST 2018, userSex='女', userAddress='北京金燕龙'} --------每个账户信息------- Account{id=4, uid=43, money=3000.0} User{userId=43, userName='小二王', userBirthday=Mon Mar 05 01:34:34 CST 2018, userSex='女', userAddress='北京金燕龙'} } /** * 查询所有 */ @Test public void findByIdTest() { Account account = accountDao.findAccountByUid(41); System.out.println(account); // 运行结果, 这个findAccountByUid方法是辅助UserDao中findAll方法的延迟加载使用的 Account{id=1, uid=41, money=1000.0} } }
-
UserTest
package com.xiaoge.test; import com.xiaoge.dao.UserDao; import com.xiaoge.domain.User; 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.List; /** * @Author: 潇哥 * @DateTime: 2020/3/18 下午4:41 * @Description: TODO */ public class UserTest { private InputStream is; private SqlSessionFactory factory; private SqlSession sqlSession; private UserDao userDao; @Before public void init() throws IOException { is = Resources.getResourceAsStream("SqlMapConfig.xml"); SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder(); factory = builder.build(is); sqlSession = factory.openSession(); userDao = sqlSession.getMapper(UserDao.class); } @After public void destroy() throws IOException { if (sqlSession != null) { sqlSession.commit(); sqlSession.close(); } if (is != null) { is.close(); } } /** * 查询所有 */ @Test public void findAllTest() { List<User> users = userDao.findAll(); for (User user : users) { System.out.println("---------每个用户的信息---------"); System.out.println(user); System.out.println(user.getAccounts()); } // 运行结果 (这里有遍历所以会查询账户, 没有遍历的话是会实现延迟加载, 但是查询单个用户就不会有延迟加载) 2020-03-18 19:55:56,761 1558 [ main] DEBUG com.xiaoge.dao.UserDao.findAll - ==> Preparing: select * from user 2020-03-18 19:55:56,805 1602 [ main] DEBUG com.xiaoge.dao.UserDao.findAll - ==> Parameters: 2020-03-18 19:55:56,873 1670 [ main] DEBUG com.xiaoge.dao.UserDao.findAll - <== Total: 11 ---------每个用户的信息--------- 2020-03-18 19:55:56,875 1672 [ main] DEBUG ao.AccountDao.findAccountByUid - ==> Preparing: select * from account where uid = ? 2020-03-18 19:55:56,876 1673 [ main] DEBUG ao.AccountDao.findAccountByUid - ==> Parameters: 41(Integer) 2020-03-18 19:55:56,878 1675 [ main] DEBUG ao.AccountDao.findAccountByUid - <== Total: 1 User{userId=41, userName='老王', userBirthday=Wed Feb 28 07:47:08 CST 2018, userSex='男', userAddress='北京'} [Account{id=1, uid=41, money=1000.0}] ---------每个用户的信息--------- 2020-03-18 19:55:56,882 1679 [ main] DEBUG ao.AccountDao.findAccountByUid - ==> Preparing: select * from account where uid = ? 2020-03-18 19:55:56,882 1679 [ main] DEBUG ao.AccountDao.findAccountByUid - ==> Parameters: 42(Integer) 2020-03-18 19:55:56,884 1681 [ main] DEBUG ao.AccountDao.findAccountByUid - <== Total: 1 User{userId=42, userName='小二王', userBirthday=Sat Mar 03 05:09:37 CST 2018, userSex='女', userAddress='北京金燕龙'} [Account{id=2, uid=42, money=1000.0}] ---------每个用户的信息--------- 2020-03-18 19:55:56,884 1681 [ main] DEBUG ao.AccountDao.findAccountByUid - ==> Preparing: select * from account where uid = ? 2020-03-18 19:55:56,884 1681 [ main] DEBUG ao.AccountDao.findAccountByUid - ==> Parameters: 43(Integer) 2020-03-18 19:55:56,886 1683 [ main] DEBUG ao.AccountDao.findAccountByUid - <== Total: 2 User{userId=43, userName='小二王', userBirthday=Mon Mar 05 01:34:34 CST 2018, userSex='女', userAddress='北京金燕龙'} [Account{id=3, uid=43, money=2000.0}, Account{id=4, uid=43, money=3000.0}] ---------每个用户的信息--------- 2020-03-18 19:55:56,886 1683 [ main] DEBUG ao.AccountDao.findAccountByUid - ==> Preparing: select * from account where uid = ? 2020-03-18 19:55:56,886 1683 [ main] DEBUG ao.AccountDao.findAccountByUid - ==> Parameters: 46(Integer) 2020-03-18 19:55:56,887 1684 [ main] DEBUG ao.AccountDao.findAccountByUid - <== Total: 0 User{userId=46, userName='老王', userBirthday=Thu Mar 08 07:37:26 CST 2018, userSex='女', userAddress='北京'} [] ---------每个用户的信息--------- 2020-03-18 19:55:56,888 1685 [ main] DEBUG ao.AccountDao.findAccountByUid - ==> Preparing: select * from account where uid = ? 2020-03-18 19:55:56,888 1685 [ main] DEBUG ao.AccountDao.findAccountByUid - ==> Parameters: 48(Integer) 2020-03-18 19:55:56,889 1686 [ main] DEBUG ao.AccountDao.findAccountByUid - <== Total: 0 User{userId=48, userName='小马宝莉', userBirthday=Fri Mar 09 01:44:00 CST 2018, userSex='女', userAddress='北京修正'} [] ---------每个用户的信息--------- 2020-03-18 19:55:56,890 1687 [ main] DEBUG ao.AccountDao.findAccountByUid - ==> Preparing: select * from account where uid = ? 2020-03-18 19:55:56,890 1687 [ main] DEBUG ao.AccountDao.findAccountByUid - ==> Parameters: 53(Integer) 2020-03-18 19:55:56,891 1688 [ main] DEBUG ao.AccountDao.findAccountByUid - <== Total: 0 User{userId=53, userName='啸哥', userBirthday=Fri Mar 06 13:10:42 CST 2020, userSex='男', userAddress='北京四合院'} [] ---------每个用户的信息--------- 2020-03-18 19:55:56,892 1689 [ main] DEBUG ao.AccountDao.findAccountByUid - ==> Preparing: select * from account where uid = ? 2020-03-18 19:55:56,892 1689 [ main] DEBUG ao.AccountDao.findAccountByUid - ==> Parameters: 54(Integer) 2020-03-18 19:55:56,894 1691 [ main] DEBUG ao.AccountDao.findAccountByUid - <== Total: 0 User{userId=54, userName='李四 last insertid', userBirthday=Fri Mar 06 14:26:40 CST 2020, userSex='男', userAddress='北京'} [] ---------每个用户的信息--------- 2020-03-18 19:55:56,895 1692 [ main] DEBUG ao.AccountDao.findAccountByUid - ==> Preparing: select * from account where uid = ? 2020-03-18 19:55:56,895 1692 [ main] DEBUG ao.AccountDao.findAccountByUid - ==> Parameters: 55(Integer) 2020-03-18 19:55:56,896 1693 [ main] DEBUG ao.AccountDao.findAccountByUid - <== Total: 0 User{userId=55, userName='王五 last insertid', userBirthday=Fri Mar 06 15:17:43 CST 2020, userSex='男', userAddress='北京'} [] ---------每个用户的信息--------- 2020-03-18 19:55:56,897 1694 [ main] DEBUG ao.AccountDao.findAccountByUid - ==> Preparing: select * from account where uid = ? 2020-03-18 19:55:56,897 1694 [ main] DEBUG ao.AccountDao.findAccountByUid - ==> Parameters: 56(Integer) 2020-03-18 19:55:56,898 1695 [ main] DEBUG ao.AccountDao.findAccountByUid - <== Total: 0 User{userId=56, userName='李六 last insertid', userBirthday=Fri Mar 06 18:47:48 CST 2020, userSex='男', userAddress='北京'} [] ---------每个用户的信息--------- 2020-03-18 19:55:56,898 1695 [ main] DEBUG ao.AccountDao.findAccountByUid - ==> Preparing: select * from account where uid = ? 2020-03-18 19:55:56,899 1696 [ main] DEBUG ao.AccountDao.findAccountByUid - ==> Parameters: 57(Integer) 2020-03-18 19:55:56,900 1697 [ main] DEBUG ao.AccountDao.findAccountByUid - <== Total: 0 User{userId=57, userName='李六 last insertid', userBirthday=Fri Mar 06 19:11:40 CST 2020, userSex='男', userAddress='北京'} [] ---------每个用户的信息--------- 2020-03-18 19:55:56,900 1697 [ main] DEBUG ao.AccountDao.findAccountByUid - ==> Preparing: select * from account where uid = ? 2020-03-18 19:55:56,901 1698 [ main] DEBUG ao.AccountDao.findAccountByUid - ==> Parameters: 59(Integer) 2020-03-18 19:55:56,902 1699 [ main] DEBUG ao.AccountDao.findAccountByUid - <== Total: 0 User{userId=59, userName='李白 last insertid', userBirthday=Wed Mar 11 18:17:20 CST 2020, userSex='男', userAddress='北京'} [] } /** * 测试根据id查询用户信息 */ @Test public void findOneTest() { User user = userDao.findById(59); System.out.println(user); System.out.println(user.getAccounts()); // 运行结果(因为是查询单个用户, 所以不会实现延迟加载) 2020-03-18 19:58:51,081 1521 [ main] DEBUG om.xiaoge.dao.UserDao.findById - ==> Preparing: select * from user where id = ? 2020-03-18 19:58:51,132 1572 [ main] DEBUG om.xiaoge.dao.UserDao.findById - ==> Parameters: 59(Integer) 2020-03-18 19:58:51,187 1627 [ main] DEBUG om.xiaoge.dao.UserDao.findById - <== Total: 1 2020-03-18 19:58:51,189 1629 [ main] DEBUG ao.AccountDao.findAccountByUid - ==> Preparing: select * from account where uid = ? 2020-03-18 19:58:51,189 1629 [ main] DEBUG ao.AccountDao.findAccountByUid - ==> Parameters: 59(Integer) 2020-03-18 19:58:51,191 1631 [ main] DEBUG ao.AccountDao.findAccountByUid - <== Total: 0 User{userId=59, userName='李白 last insertid', userBirthday=Wed Mar 11 18:17:20 CST 2020, userSex='男', userAddress='北京'} [] } /** * 根据用户名模糊查询 */ @Test public void findUserByNameTest(){ List<User> users = userDao.findUserByName("%王%"); // 运行结果(没有遍历, 实现了延迟加载) 2020-03-18 19:59:49,824 1517 [ main] DEBUG oge.dao.UserDao.findUserByName - ==> Preparing: select * from user where username like ? // 这里 2020-03-18 19:59:49,891 1584 [ main] DEBUG oge.dao.UserDao.findUserByName - ==> Parameters: %王%(String) 2020-03-18 19:59:49,945 1638 [ main] DEBUG oge.dao.UserDao.findUserByName - <== Total: 5 } }