05 Mybatis annotation development (the end of Mybatis Series)

Mybatis user manual (5 of 5, continuously updated), collection + attention, don't get lost, hope to be helpful to my friends~

The source code link is at the end of the text ↓↓

Using annotation development can reduce the writing of Mapper mapping files.

1. Mybatis common notes

@Insert:Realize new

@Update:Implementation update

@Delete:Implementation deletion

@Select:Implement query

@Result:Implement result set encapsulation

@Results:Can be with@Result Use together to encapsulate multiple result sets

@ResultMap:Implementation reference@Results Defined encapsulation

@One:Implement one-to-one result set encapsulation

@Many:Implement one to many result set encapsulation

@SelectProvider: Implementation dynamics SQL mapping

@CacheNamespace:Realize the use of annotation L2 cache

2. Implementing basic CRUD with annotations

2.1. Main configuration file

<configuration>
  <!-- Import external profile -->
  <properties resource="jdbc.properties"/>

  <!-- Entity class alias configuration -->
  <typeAliases>
    <package name="com.junlong.domain"/>
  </typeAliases>

  <!-- Environment configuration -->
  <environments default="mysql">
    <environment id="mysql">
      <transactionManager type="JDBC"/>
      <dataSource type="POOLED">
        <property name="driver" value="${jdbc.driver}"/>
        <property name="url" value="${jdbc.url}"/>
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
      </dataSource>
    </environment>
  </environments>

  <!-- Persistence layer interface configuration -->
  <mappers>
    <package name="com.junlong.dao"/>
  </mappers>
</configuration>

2.2. Persistent layer interface (annotation Development)

public interface UserDao {
    /**
     * Query all users
     *
     * @return Return to all users list < user >
     */
    @Select("select * from user")
    @Results(
        id = "userMap",
        value = {
            @Result(id = true, column = "id", property = "userId"),
            @Result(column = "username", property = "userName"),
            @Result(column = "birthday", property = "userBirthday"),
            @Result(column = "sex", property = "userSex"),
            @Result(column = "address", property = "userAddress")
        }
    )
    List<User> findAll();

    /**
     * Query user information according to user id
     *
     * @param id User id
     * @return Return User object User
     */
    @Select("select * from user where id = #{id}")
    @ResultMap("userMap")
    User findById(int id);

    /**
     * New user
     *
     * @param user User object
     */
    @Insert("insert into user (username, birthday, sex, address) VALUES (#{userName}, #{userBirthday}, #{userSex}, #{userAddress})")
    @SelectKey(keyColumn = "id", keyProperty = "userId", resultType = Integer.class, before = false, statement = "select last_insert_id()")
    void saveUser(User user);

    /**
     * Update user information
     *
     * @param user User object
     */
    @Update("update user set username = #{userName}, address = #{userAddress}, birthday = #{userBirthday}, sex = #{userSex} where id = #{userId}")
    void updateUser(User user);

    /**
     * Delete user according to user id (physical deletion)
     *
     * @param id User id
     */
    @Delete("delete from user where id = #{id}")
    void deleteUser(Integer id);

    /**
     * Total records queried by aggregate function
     *
     * @return Returns the total number of records
     */
    @Select("select count(*) from user")
    int findTotal();

    /**
     * Fuzzy query based on user name
     *
     * @param name User name (with%)
     * @return Returns the list of eligible users
     */
    @Select("select * from user where username like #{username}")
    @ResultMap("userMap")
    List<User> findByName(String name);
}

2.3 test

public class UserTest {
    private InputStream inputStream;
    private SqlSession sqlSession;
    private UserDao userDao;

    @Before
    public void init() throws IOException {
        inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        sqlSession = sqlSessionFactory.openSession();
        userDao = sqlSession.getMapper(UserDao.class);
    }

    @After
    public void destroy() throws IOException {
        sqlSession.commit();
        sqlSession.close();
        inputStream.close();
    }

    /**
     * Test query all users
     */
    @Test
    public void testFindAll() {
        List<User> users = userDao.findAll();
        for (User user : users) {
            System.out.println(user);
        }
    }

    /**
     * The test queries the user according to the user id
     */
    @Test
    public void testFindById() {
        User user = userDao.findById(51);
        System.out.println(user);
    }

    /**
     * Test new users
     */
    @Test
    public void testSaveUser() {
        User user = new User();
        user.setUserName("new user");
        user.setUserBirthday(new Date());
        user.setUserSex("female");
        user.setUserAddress("Algeria");
        System.out.println("Before saving:" + user);

        userDao.saveUser(user);

        System.out.println("After saving:" + user);
    }

    /**
     * Test update user information
     */
    @Test
    public void testUpdateUser() {
        User user = userDao.findById(51);
        user.setUserName("updateUser");
        user.setUserAddress("DRC");

        userDao.updateUser(user);
    }

    /**
     * Test delete user
     */
    @Test
    public void testDeleteUser() {
        userDao.deleteUser(50);
    }

    /**
     * Total records of test query (aggregate function query)
     */
    @Test
    public void testFindTotal() {
        int total = userDao.findTotal();
        System.out.println("common " + total + " Records");
    }

    /**
     * Test fuzzy query based on user name
     */
    @Test
    public void testFindByName() {
        List<User> users = userDao.findByName("%king%");
        for (User user : users) {
            System.out.println(user);
        }
    }
}

3. Implementing complex mapping relationships using annotations

3.1 annotation of complex mapping relationship

3.2. One to one complex mapping relationship

3.2.1 accounts and user entities

  • Account entity class
public class Account implements Serializable {
    private int id; // Account id
    private int uid; // User id
    private double money;
    private User user; // User object corresponding to account

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public int getUid() {
        return uid;
    }

    public void setUid(int uid) {
        this.uid = uid;
    }

    public double getMoney() {
        return money;
    }

    public void setMoney(double money) {
        this.money = money;
    }

    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }

    @Override
    public String toString() {
        return "Account{" +
            "id=" + id +
            ", uid=" + uid +
            ", money=" + money +
            ", user=" + user +
            '}';
    }
}
  • User entity class
public class User implements Serializable {
    private int id;
    private String username;
    private Date birthday;
    private String sex;
    private String address;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public Date getBirthday() {
        return birthday;
    }

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    @Override
    public String toString() {
        return "User{" +
            "id=" + id +
            ", username='" + username + '\'' +
            ", birthday=" + birthday +
            ", sex='" + sex + '\'' +
            ", address='" + address + '\'' +
            '}';
    }
}

3.2.2. Account and user persistence layer interface (annotation Development)

  • Account persistence layer interface
public interface AccountDao {
    /**
     * Query all accounts, including the user information corresponding to the account (delayed loading)
     *
     * @return Returns a list of all accounts
     */
    @Select("select * from account")
    @Results(
        id = "accountMap",
        value = {
            @Result(id = true, column = "id", property = "id"),
            @Result(column = "uid", property = "uid"),
            @Result(column = "money", property = "money"),
            @Result(column = "uid",
                    property = "user",
                    one = @One(select = "com.junlong.dao.UserDao.findById", fetchType = FetchType.LAZY)
                   )
        }
    )
    List<Account> findAll();
}
  • User persistence layer interface
public interface UserDao {
    /**
     * Query user by user id
     *
     * @param id User id
     * @return Return user object
     */
    @Select("select * from user where id = #{id}")
    User findById(Integer id);
}

3.2.3 test

public class AccountTest {
    private InputStream inputStream;
    private SqlSession sqlSession;
    private AccountDao accountDao;

    @Before
    public void init() throws IOException {
        inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        sqlSession = sqlSessionFactory.openSession();
        accountDao = sqlSession.getMapper(AccountDao.class);
    }

    @After
    public void destroy() throws IOException {
        sqlSession.commit();
        sqlSession.close();
        inputStream.close();
    }

    /**
     * Test and query all accounts
     */
    @Test
    public void testFindAll() {
        List<Account> accounts = accountDao.findAll();
        for (Account account : accounts) {
            System.out.println(account.getMoney());
        }
    }
}

As shown in the running results, the annotation uses delayed loading without user related information, so the SQL for querying user information is not executed.

3.3. One to many complex mapping relationship

3.3.1 accounts and user entities

  • Account entity class
public class Account implements Serializable {
    private int id; // Account id
    private int uid; // User id
    private double money;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public int getUid() {
        return uid;
    }

    public void setUid(int 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 +
            '}';
    }
}
  • User entity class
public class User implements Serializable {
    private int id; // User id
    private String username;
    private Date birthday;
    private String sex;
    private String address;
    private List<Account> accounts;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public Date getBirthday() {
        return birthday;
    }

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public List<Account> getAccounts() {
        return accounts;
    }

    public void setAccounts(List<Account> accounts) {
        this.accounts = accounts;
    }

    @Override
    public String toString() {
        return "User{" +
            "id=" + id +
            ", username='" + username + '\'' +
            ", birthday=" + birthday +
            ", sex='" + sex + '\'' +
            ", address='" + address + '\'' +
            ", accounts=" + accounts +
            '}';
    }
}

3.3.2 interface of account and user persistence layer

  • Account persistence layer interface
public interface AccountDao {
    /**
     * Query all accounts according to user uid
     *
     * @param uid User id
     * @return Returns a list of all accounts for the user id
     */
    @Select("select * from account where uid = #{uid}")
    List<Account> findByUid(int uid);
}
  • User persistence layer interface
public interface UserDao {
    /**
     * Query all users, including all user account information (delayed loading)
     *
     * @return Returns a list of all users
     */
    @Select("select * from user")
    @Results(
        id = "userMap",
        value = {
            @Result(id = true, column = "id", property = "id"),
            @Result(column = "username", property = "username"),
            @Result(column = "birthday", property = "birthday"),
            @Result(column = "sex", property = "sex"),
            @Result(column = "address", property = "address"),
            @Result(column = "id",
                    property = "accounts",
                    many = @Many(select = "com.junlong.dao.AccountDao.findByUid", fetchType = FetchType.LAZY)
                   )
        }
    )
    List<User> findAll();
}

3.3.3 test

public class UserTest {
    private InputStream inputStream;
    private SqlSession sqlSession;
    private UserDao userDao;

    @Before
    public void init() throws IOException {
        inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        sqlSession = sqlSessionFactory.openSession();
        userDao = sqlSession.getMapper(UserDao.class);
    }

    @After
    public void destroy() throws IOException {
        sqlSession.commit();
        sqlSession.close();
        inputStream.close();
    }

    /**
     * Test and query all users (including all account information of the user)
     */
    @Test
    public void testFindAll() {
        List<User> users = userDao.findAll();
        for (User user : users) {
            System.out.println(user.getUsername());
        }
    }
}

As shown in the running result, the annotation is configured with delayed loading. Since the account related information is not used, the SQL for querying the account information is not executed.

4. Annotation based L2 cache

4.1. Main configuration file

<configuration>
  <!-- External profile -->
  <properties resource="jdbc.properties"/>
  <!-- Enable L2 cache -->
  <settings>
    <!-- cacheEnabled The default value is true๏ผŒMismatch can be omitted -->
    <setting name="cacheEnabled" value="true"/>
  </settings>
  <!-- Entity class alias -->
  <typeAliases>
    <package name="com.junlong.domain"/>
  </typeAliases>
  <!-- Environment configuration -->
  <environments default="mysql">
    <environment id="mysql">
      <transactionManager type="JDBC"/>
      <dataSource type="POOLED">
        <property name="driver" value="${jdbc.driver}"/>
        <property name="url" value="${jdbc.url}"/>
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
      </dataSource>
    </environment>
  </environments>
  <!-- dao route -->
  <mappers>
    <package name="com.junlong.dao"/>
  </mappers>
</configuration>

4.2. Enable L2 cache for user persistence layer interface (annotation Development)

// Configure L2 cache
@CacheNamespace(blocking = true)
public interface UserDao {
    /**
     * Query user by user id
     *
     * @param id User id
     * @return Return user object
     */
    @Select("select * from user where id = #{id}")
    User findById(Integer id);
}

4.3 test

public class UserTest {
    private InputStream inputStream;
    private SqlSessionFactory sqlSessionFactory;

    @Before
    public void init() throws IOException {
        inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
        sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
    }

    @After
    public void destroy() throws IOException {
        inputStream.close();
    }

    /**
     * The test queries the user according to the user id (L2 cache)
     *
     * Note: L2 cache can take effect only after sqlSession is committed or closed
     */
    @Test
    public void testFindById() {
        SqlSession sqlSession1 = sqlSessionFactory.openSession();
        UserDao userDao1 = sqlSession1.getMapper(UserDao.class);
        User user1 = userDao1.findById(51);
        System.out.println(user1);
        sqlSession1.commit();
        sqlSession1.close();

        SqlSession sqlSession2 = sqlSessionFactory.openSession();
        UserDao userDao2 = sqlSession2.getMapper(UserDao.class);
        User user2 = userDao2.findById(51);
        System.out.println(user2);
        sqlSession2.commit();
        sqlSession2.close();

        System.out.println(user1 == user2);
    }
}

As shown in the running results, the two queries only execute SQL once. Since the L2 cache uses serialization storage, the objects obtained from the two queries do not use one.

3. Source download

Source download link ๐Ÿ‘‰ Click direct download address

The Mybatis user's manual contains 5 contents, and this one has been updated. Welcome friends to watch and comment.

Thank you for your attention! Collection + attention don't get lost~

Related content
๐Ÿ‘‰ Mybatis manual
๐Ÿ‘‰ Java se manual

Highlights of previous periods
๐Ÿ‘‰ Java Xiaobai learning manual - SE

Keywords: Java MySQL Mybatis Back-end Annotation

Added by zevious on Thu, 09 Dec 2021 07:10:17 +0200