Mybatis注解開發


Mybatis注解開發

1.Mybaits常用注解說明

  @Insert:實現新增

  @Select:實現查詢

  @Update:實現更新

  @Delete:實現刪除

  @Result:實現結果集的封裝

  @Results:可以與Result一起使用,實現多個結果集的封裝

  @ResultMap:實現引用@Results定義的封裝

  @One:實現一對一結果集的封裝
  @Many:實現一對多結果集的封裝

  @SelectProvider:實現動態SQL映射
  @CacheNamespace:實現注解二級緩存的使用

  1.1 使用Mybatis注解實現基本CRUD

  

package com.llb.domain; import java.io.Serializable; import java.util.Date; /** * Ceate By llb on 2019/8/9 */
public class User implements Serializable{ private Integer userId; private String userName; private String userAddress; private String userSex; private Date userBirthday; }

此處故意與數據庫列名不一致

  1.2 使用注解方式開發持久層接口

package com.llb.dao; import com.llb.domain.User; import org.apache.ibatis.annotations.Delete; import org.apache.ibatis.annotations.Insert; import org.apache.ibatis.annotations.Select; import org.apache.ibatis.annotations.Update; import java.util.List; /** * 針對crud有四個注解 * @Select, @Insert, @Update, @Delete * Ceate By llb on 2019/8/9 */
public interface UserMapper { /** * 查詢所有用戶 * @return
     */ @Select("select * from user") List<User> findAll(); /** * 保存用戶 */ @Insert("insert into user(username, address, sex, birthday) values (#{username}, #{address}, #{sex}, #{birthday})") void saveUser(User user); /** * 更新用戶 */ @Update("update user set username = #{username}, address = #{address}, sex= #{sex}, birthday = #{birthday} where id = #{id}") void updateUser(User user); /** * 刪除用戶 */ @Delete("delete from user where id = #{id}") void deleteUser(Integer id); /** * 根據id查詢用戶 */ @Select("select * from user where id = #{id}") User findUserById(Integer id); /** * 根據姓名模糊查詢 */
// @Select("select * from user where username like #{username}")
    @Select("select * from user where username like '%${value}%'") List<User> findUserByUsername(String username); /** * 查詢總用戶數量 */ @Select("select count(*) from user") Integer findTotal(); }

通過此注解方式,我們就不需要再去編寫UserMapper.xml映射文件了

 

  1.3 編寫SqlMapConfig.xml配置文件

  

<?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>

    <!--配置別名-->
    <typeAliases>
        <package name="com.llb.domain"></package>
    </typeAliases>

    <!--配置環境-->
    <environments default="mysql">
        <!--配置MySQl環境-->
        <environment id="mysql">
            <!--配置事務類型為JDBC-->
            <transactionManager type="JDBC"></transactionManager>
            <!--配置數據源-->
            <!--POOLED創建連接池-->
            <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>
        <!-- 配置 dao 接口的位置,它有兩種方式 第一種:使用 mapper 標簽配置 class 屬性 第二種:使用 package 標簽,直接指定 mapper 接口所在的包 -->
        <!--<mapper class="com.llb.dao.UserMapper"></mapper>-->
        <package name="com.llb.dao"></package>
    </mappers>

</configuration>

  1.4 編寫測試方法

package com.llb.test; /** * Ceate By llb on 2019/8/9 */
public class AnnotationCRUD { InputStream in ; SqlSessionFactory factory; SqlSession sqlSession; UserMapper mapper; @Before public void init() throws IOException { in = Resources.getResourceAsStream("SqlMapConfig.xml"); factory = new SqlSessionFactoryBuilder().build(in); sqlSession = factory.openSession(); mapper = sqlSession.getMapper(UserMapper.class); } @After public void destroy() throws IOException { sqlSession.commit(); sqlSession.close(); in.close(); } /** * 測試注解保存用戶 */ @Test public void testInsert(){ User user = new User(); user.setUsername("王五"); user.setAddress("浙江杭州"); user.setSex("男"); user.setBirthday(new Date()); mapper.saveUser(user); } /** * 測試注解修改用戶 */ @Test public void testUpdate(){ User user = new User(); user.setId(53); user.setUsername("王五"); user.setAddress("浙江杭州"); user.setSex("男"); user.setBirthday(new Date()); mapper.updateUser(user); } /** * 測試注解刪除用戶 */ @Test public void testDelete(){ mapper.deleteUser(53); } /** * 根據id查詢用戶 */ @Test public void testFindUserById(){ User user = mapper.findUserById(41); System.out.println(user); } /** * 根據姓名模糊查詢用戶 */ @Test public void testFindUserByName(){ List<User> users = mapper.findUserByUsername("%張%"); for (User user: users) { System.out.println(user); } } /** * 總條數 */ @Test public void findTotal(){ Integer total = mapper.findTotal(); System.out.println(total); } }

 


 

源碼直達github

 

2 使用注解實現復雜關系映射開發

  實現復雜關系映射開發之前我們可以在映射文件中通過配置<resultMap>來實現,在使用注解開發時,我們需要借助@Result、@Results、@One、@Many

  2.1 復雜關系映射的注解說明

 

@Results 注解 代替的標簽是<resultMap> 該注解中可以使用單個@Result,也可以使用@Results集合 @Results({@Result(),@Result()})或@Results(@Result())

@Result注解
代替了<id>和<result>標簽
@Result中的屬性介紹:
  id 是否是主鍵字段
  column 數據庫的列名
  property 需要裝配的屬性名
  one 需要使用@One注解(@Result(one = @One()))
  
many 需要使用@Many注解(@Result(many = @Many()))


@One注解(一對一)
  代替了<association>標簽,是表查詢的關鍵,在注解中用來指定子查詢返回單一對象。

  屬性介紹:
    select 指定用來多表查詢的SqlMapper
    fetchType 會覆蓋全局的配置參數lazyLoadingEnabled。
  使用格式:
    @Result(column="", prperty="", one=@One(select=""))
@Many注解(一對多)
  代替了<collection>標簽,是多表查詢的關鍵,在注解中用來指定子查詢返回對象集合。

  注意:聚集元素用來處理“一對多”的關系。需要指定映射的 Java 實體類的屬性,屬性的 javaType(一般為 ArrayList)但是注解中可以不定義;
  
  使用格式:
      @Result(property="",column="",many=@Many(select=""))
 

  2.2 使用注解實現一對一復雜關系映射延遲加載

需求:
      加載賬戶信息時並且加載該賬戶的用戶信息,根據情況可實現延遲加載。(注解方式)

    2.2.1 添加User實體類及Account實體類

   用戶實體類:   

package com.llb.domain; import java.io.Serializable; import java.util.Date; import java.util.List; /** * Ceate By llb on 2019/8/9 */
public class User implements Serializable { private Integer userId; private String userName; private String userAddress; private String userSex; private Date userBirthday; }

  賬戶實體類:

package com.llb.domain; import java.io.Serializable; /** * 賬戶的實體類 * Ceate By llb on 2019/8/7 */
public class Account implements Serializable { private Integer id; private Integer uid; private double money; //從表實體應該包含一個主表實體的對象引用
    private User user;  }

    2.2.2 添加賬戶的持久層接口並使用注解配置

    

package com.llb.dao;import java.util.List; /** * Ceate By llb on 2019/8/7 */
public interface AccountMapper { /** * 多對一:立即加載 * 查詢賬戶所對應的的用戶 * FetchType.EAGER:立即加載 * */ @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.llb.dao.UserMapper.findUserById", fetchType = FetchType.EAGER)), }) List<Account> findAllAccount(); }

      2.2.3 測試一對一關聯及延遲加載

  

package com.llb.test; /** * Ceate By llb on 2019/8/9 */
public class AccountCRUD { InputStream in ; SqlSessionFactory factory; SqlSession sqlSession; AccountMapper mapper; @Before public void init() throws IOException { in = Resources.getResourceAsStream("SqlMapConfig.xml"); factory = new SqlSessionFactoryBuilder().build(in); sqlSession = factory.openSession(); mapper = sqlSession.getMapper(AccountMapper.class); } @After public void destroy() throws IOException { sqlSession.commit(); sqlSession.close(); in.close(); } /** * 查詢賬戶所對應的用戶 */ @Test public void findAllAccount(){ List<Account> accounts = mapper.findAllAccount(); for (Account account: accounts) { System.out.println(account); } } }

3. 使用注解實現一對多復雜關系映射

需求:查詢用戶信息時,也要查詢他的賬戶列表。使用注解方式實現。
分析:一個用戶具有多個賬戶信息,所以形成了用戶(User)與賬戶(Account)之間的一對多關系。

  3.1 User實體類加入List<Account>

    

package com.llb.domain; import java.io.Serializable; import java.util.Date; import java.util.List; /** * Ceate By llb on 2019/8/9 */
public class User implements Serializable { private Integer userId; private String userName; private String userAddress; private String userSex; private Date userBirthday;   //一對多關系映射:主表方法應該包含一個從表方的集合引用
private List<Account> accounts; }

  3.2 編寫用戶的持久層接口並使用注解配置

  

package com.llb.dao; import com.llb.domain.User; import org.apache.ibatis.annotations.*; import org.apache.ibatis.mapping.FetchType; import java.util.List; /** * 針對crud有四個注解 * @Select, @Insert, @Update, @Delete * Ceate By llb on 2019/8/9 */

//開啟二級緩存
@CacheNamespace(blocking = true) public interface UserMapper { /** * 查詢所有用戶 * @return
     */ @Select("select * from user") @Results(id = "userMap", value ={ @Result(column = "id", property = "userId"), @Result(column = "username", property = "userName"), @Result(column = "sex", property = "userSex"), @Result(column = "birthday", property = "userBirthday"), @Result(column = "address", property = "userAddress"), @Result(column = "id", property = "accounts", many = @Many(select = "com.llb.dao.AccountMapper.findAccountByUid", fetchType = FetchType.LAZY) ) }) List<User> findAll(); /** * 根據id查詢用戶 */ @Select("select * from user where id = #{id}") @ResultMap(value = {"userMap"}) User findUserById(Integer id); /** * 根據姓名模糊查詢 */
// @Select("select * from user where username like #{username}")
    @Select("select * from user where username like '%${value}%'") List<User> findUserByUsername(String username); }

   3.3 編寫賬戶的持久層接口並使用注解配置

    

package com.llb.dao; import com.llb.domain.Account; import org.apache.ibatis.annotations.One; import org.apache.ibatis.annotations.Result; import org.apache.ibatis.annotations.Results; import org.apache.ibatis.annotations.Select; import org.apache.ibatis.mapping.FetchType; import java.util.List; /** * Ceate By llb on 2019/8/7 */
public interface AccountMapper { /** * 根據用戶id查詢賬戶 * @return
     */ @Select("select * from account where uid = #{uid}") List<Account> findAccountByUid(Integer uid); }

  3.4 添加測試方法

  

package com.llb.test; /** * Ceate By llb on 2019/8/9 */
public class AnnotationCRUD { InputStream in ; SqlSessionFactory factory; SqlSession sqlSession; UserMapper mapper; @Before public void init() throws IOException { in = Resources.getResourceAsStream("SqlMapConfig.xml"); factory = new SqlSessionFactoryBuilder().build(in); sqlSession = factory.openSession(); mapper = sqlSession.getMapper(UserMapper.class); } @After public void destroy() throws IOException { sqlSession.commit(); sqlSession.close(); in.close(); } /** * 查詢所有 */ @Test public void testFindAll(){ List<User> users = mapper.findAll(); for (User user:users) { System.out.println(user); } } }

 


源碼地址github

 

4. 注解實現延遲加載

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM