欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Mybatis基于注解实现多表查询功能

程序员文章站 2023-11-09 14:32:16
  对应的四种数据库表关系中存在四种关系:一对多,多对应,一对一,多对多。在前文中已经实现了xml配置方式实现表关系的查询,本文记录一下mybatis怎么通过注解实现多表的...

  对应的四种数据库表关系中存在四种关系:一对多,多对应,一对一,多对多。在前文中已经实现了xml配置方式实现表关系的查询,本文记录一下mybatis怎么通过注解实现多表的查询,算是一个知识的补充。

  同样的先介绍一下demo的情况:存在两个实体类用户类和账户类,用户类可能存在多个账户,即一对多的表关系。每个账户只能属于一个用户,即一对一或者多对一关系。我们最后实现两个方法,第一个实现查询所有用户信息并同时查询出每个用户的账户信息,第二个实现查询所有的账户信息并且同时查询出其所属的用户信息。

  1.项目结构

Mybatis基于注解实现多表查询功能

  2.领域类

public class account implements serializable{
  private integer id;
  private integer uid;
  private double money;
  private user user; //加入所属用户的属性
  省略get 和set 方法.............................    
}
public class user implements serializable{
  private integer userid;
  private string username;
  private date userbirthday;
  private string usersex;
  private string useraddress;
  private list<account> accounts;
  省略get 和set 方法.............................    
}

  在user中因为一个用户有多个账户所以添加account的列表,在account中因为一个账户只能属于一个user,所以添加user的对象。 

  3.dao层

public interface accountdao {
  /**
   *查询所有账户并同时查询出所属账户信息
   */
  @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"),
      //配置用户查询的方式 column代表的传入的字段,一对一查询用one select 代表使用的方法的全限定名, fetchtype表示查询的方式为立即加载还是懒加载
      @result(property = "user",column = "uid",one = @one(select = "com.example.dao.userdao.findbyid",fetchtype = fetchtype.eager))
  })
  list<account> findall();
  /**
   * 根据用户id查询所有账户
   * @param id
   * @return
   */
  @select("select * from account where uid = #{id}")
  list<account> findaccountbyuid(integer id);
}
public interface userdao {
  /**
   * 查找所有用户
   * @return
   */
  @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"),
      @result(column = "id",property = "accounts",many = @many(select = "com.example.dao.accountdao.findaccountbyuid",fetchtype = fetchtype.lazy))
  })
  list<user> findall();
  /**
   * 保存用户
   * @param user
   */
  @insert("insert into user(username,birthday,sex,address) values(#{username},#{birthday},#{sex},#{address})")
  void saveuser(user user);
  /**
   * 更新用户
   * @param user
   */
  @update("update user set username=#{username},birthday=#{birthday},sex=#{sex},address=#{address} where id=#{id}")
  void updateuser(user user);
  /**
   * 删除用户
   * @param id
   */
  @delete("delete from user where id=#{id}")
  void deleteuser(integer id);
  /**
   * 查询用户根据id
   * @param id
   * @return
   */
  @select("select * from user where id=#{id}")
  @resultmap(value = {"usermap"})
  user findbyid(integer id);
  /**
   * 根据用户名称查询用户
   * @param name
   * @return
   */
//  @select("select * from user where username like #{name}")
  @select("select * from user where username like '%${value}%'")
  list<user> findbyusername(string name);
  /**
   * 查询用户数量
   * @return
   */
  @select("select count(*) from user")
  int findtotaluser();

  在findall()方法中配置@results的返回值的注解,在@results注解中使用@result配置根据用户和账户的关系而添加的属性,user中的属性list<account>一个用户有多个账户的关系的映射配置:@result(column = "id",property = "accounts",many = @many(select = "com.example.dao.accountdao.findaccountbyuid",fetchtype = fetchtype.lazy)),使用@many来向mybatis表明其一对多的关系,@many中的select属性对应的accountdao中的findaccountbyuid方法的全限定名,fetchtype代表使用立即加载或者延迟加载,因为这里为一对多根据前面的讲解,懒加载的使用方式介绍一对多关系一般使用延迟加载,所以这里配置为lazy方式。在account中存在多对一或者一对一关系,所以配置返回值属性时使用:@result(property = "user",column = "uid",one = @one(select = "com.example.dao.userdao.findbyid",fetchtype = fetchtype.eager)),property代表领域类中声明的属性,column代表传入后面select语句中的参数,因为这里为一对一或者说为多对一,所以使用@one注解来描述其关系,eager表示使用立即加载的方式,select代表查询本条数据时所用的方法的全限定名,fetchtype代表使用立即加载还是延迟加载。

  4.demo中mybatis的配置

<?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>
  <settings>
    <!--<!–开启全局的懒加载–>-->
    <!--<setting name="lazyloadingenabled" value="true"/>-->
    <!--<!–关闭立即加载,其实不用配置,默认为false–>-->
    <!--<setting name="aggressivelazyloading" value="false"/>-->
    <!--开启mybatis的sql执行相关信息打印-->
    <setting name="logimpl" value="stdout_logging" />
    <!--<setting name="cacheenabled" value="true"/>-->
  </settings>
  <typealiases>
    <typealias type="com.example.domain.user" alias="user"/>
    <package name="com.example.domain"/>
  </typealiases>
  <environments default="test">
    <environment id="test">
      <!--配置事务-->
      <transactionmanager type="jdbc"></transactionmanager>
      <!--配置连接池-->
      <datasource type="pooled">
        <property name="driver" value="com.mysql.jdbc.driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/test1"/>
        <property name="username" value="root"/>
        <property name="password" value="123456"/>
      </datasource>
    </environment>
  </environments>
  <mappers>
    <package name="com.example.dao"/>
  </mappers>
</configuration>

  主要是记得开启mybatis中sql执行情况的打印,方便我们查看执行情况。

  5.测试

  (1)测试查询用户同时查询出其账户的信息

   测试代码:

public class usertest {
  private inputstream in;
  private sqlsessionfactory sqlsessionfactory;
  private sqlsession sqlsession;
  private userdao userdao;
  @before
  public void init()throws exception{
    in = resources.getresourceasstream("sqlmapconfig.xml");
    sqlsessionfactory = new sqlsessionfactorybuilder().build(in);
    sqlsession = sqlsessionfactory.opensession();
    userdao = sqlsession.getmapper(userdao.class);
  }
  @after
  public void destory()throws exception{
    sqlsession.commit();
    sqlsession.close();
    in.close();
  }
  @test
  public void testfindall(){
    list<user> userlist = userdao.findall();
    for (user user: userlist){
      system.out.println("每个用户信息");
      system.out.println(user);
      system.out.println(user.getaccounts());
    }
  }

  测试结果:

Mybatis基于注解实现多表查询功能

(2)查询所有账户信息同时查询出其所属的用户信息

  测试代码:

public class accounttest {
  private inputstream in;
  private sqlsessionfactory sqlsessionfactory;
  private sqlsession sqlsession;
  private accountdao accountdao;
  @before
  public void init()throws exception{
    in = resources.getresourceasstream("sqlmapconfig.xml");
    sqlsessionfactory = new sqlsessionfactorybuilder().build(in);
    sqlsession = sqlsessionfactory.opensession();
    accountdao = sqlsession.getmapper(accountdao.class);
  }
  @after
  public void destory()throws exception{
    sqlsession.commit();
    sqlsession.close();
    in.close();
  }
  @test
  public void testfindall(){
    list<account> accountlist = accountdao.findall();
    for (account account: accountlist){
      system.out.println("查询的每个账户");
      system.out.println(account);
      system.out.println(account.getuser());
    }
  }
}

测试结果:

Mybatis基于注解实现多表查询功能

总结

以上所述是小编给大家介绍的mybatis基于注解实现多表查询功能,希望对大家有所帮助