Mybatis学习笔记(三)

1.9 复杂查询环境(一对多,多对一)

1.9.1 多对一

创建学生实体类和老师实体类

//这里使用了lombok注解,减少了代码量
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Student {
    private int id;
    private String name;
    private String classname;
    private Teacher teacher;
}
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Teacher {
    private int id;
    private String name;
}

关于lombok的简单介绍:

Lombok插件

1. 概念

一款java插件,能帮助开发人员省略冗余的实体类中的构造方法,set get方法,重写方法等,但不支持构造方法的重载,可以手动添加,但一般不介意使用此插件

2. 插件使用

先在设置中下载lombok插件,再在pom.xml文件中导入lombok的依赖

3. 相关注解类型

@Data //无参构造方法,get和set方法,equals方法,重写方法,hashCode方法
@AllArgsConstructor //全参构造方法
@NoArgsConstructor  //无参构造方法

回到测试程序:

多对一查询一般有两种方式:

第一种方式:子查询

<!--查询学生信息-->
<select id="findAllStudent" resultMap="stuWithTea">
    select * from student;
</select>
<!--进行结果集映射-->
<resultMap id="stuWithTea" type="student">
    <association property="teacher" column="tid" javaType="Teacher" select="findTeacher"/>
</resultMap>
<!--查询老师信息-->
<select id="findTeacher" resultType="teacher">
    select * from teacher where id=#{tid};
</select>

第二种方式:联表查询

<!--联表查询的sql语句-->
<select id="findAllStudent" resultMap="stuWithTea">
    select s.id sid,s.name sname,s.classname sclsname,t.name tname,t.id tid
    from student s,teacher t where s.tid=t.id;
</select>
<!--进行结果集的一一映射,字段名对应属性名-->
<resultMap id="stuWithTea" type="student">
    <result property="id" column="sid"/>
    <result property="name" column="sname"/>
    <result property="classname" column="sclsname"/>
    <association property="teacher" javaType="Teacher">
        <result property="name" column="tname"/>
        <result property="id" column="tid"/>
    </association>
</resultMap>

1.9.2 一对多,(和多对一类似)

Student和Teacher实体类中添加属性

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Student {
    private int id;
    private String name;
    private String classname;
    private Teacher teacher;
    private int tid;
//重载toString方法
    @Override
    public String toString() {
        return "Student{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", classname='" + classname +
                '}';
    }
}
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Teacher {
    private int id;
    private String name;
    private List<Student> list;
}
<!--方式一:子查询-->
<select id="findTeacherById" resultMap="teaWithStu">
    select * from teacher where id=#{id};
</select>

<resultMap id="teaWithStu" type="teacher">
    <collection property="list" javaType="ArrayList" ofType="Student" column="id" select="findStu"/>
</resultMap>
<select id="findStu" resultType="student">
    select * from student where tid=#{id};
</select>

<!--联表查询-->
<select id="findTeacherById" resultMap="teaWithStu" parameterType="int">
    select t.id tid,t.name tname,s.id sid,s.name sname,s.classname sclsname
    from teacher t,student s where s.tid=t.id and t.id=#{id};
</select>
<resultMap id="teaWithStu" type="teacher">
    <result property="id" column="tid"/>
    <result property="name" column="tname"/>
    <collection property="list" ofType="Student">
        <result property="id" column="sid"/>
        <result property="name" column="sname"/>
        <result property="classname" column="sclsname"/>
    </collection>
</resultMap>

1.9.3 联表查询和子查询的比较

联表查询的sql语句较难写,但结果集的映射较容易,而子查询与联表查询则相反,实际开发中可根据自己的理解选择查询方式

1.9.4 几个特殊词

  • 关联:assocation【多对一】

  • 集合:collection 【一对多】

  • JavaType:用来指定实体类中属性的类型

  • ofType:用来指定映射到集合中的实体类类型(泛型)

2.0 动态SQL

根据不同的查询条件,生成不同的sql语句

通常创建一个新的实体类后在主配置文件中进行类型别名配置,防止报错且难以找出错误

2.0.1 IF语句

<select id="findBlogWith" parameterType="map" resultType="blog">
    select * from blog
    <where>
        <if test="title != null">
            title=#{title}
        </if>
        <if test="author != null">
            and author=#{author}
        </if>
    </where>
</select>
/**
     * 测试不同条件下得到的查询结果
     */
@Test
public void findBlogWith(){
    SqlSession sqlSession = MybatisUtils.getSqlSession();
    BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
    HashMap<String, Object> map = new HashMap<String, Object>();
    map.put("title","java学习");
    map.put("author","战狼");
    List<Blog> blogs = mapper.findBlogWith(map);
    for (Blog blog : blogs) {
        System.out.println(blog);
    }
    sqlSession.close();
}

2.0.2 常用标签

  • where

where 元素只会在子元素返回任何内容的情况下才插入 “WHERE” 子句。而且,若子句的开头为 “AND” 或 “OR”,where 元素也会将它们去除

  • set

set 元素会动态地在行首插入 SET 关键字,并会删掉额外的逗号

<update id="updateBlogById" parameterType="blog">
    update blog
    <set>
        <if test="title != null">
            title=#{title},
        </if>
        <if test="author != null">
            author=#{author},
        </if>
        <if test="views != null">
            views=#{views}
        </if>
    </set>
</update>
  • choose(when,otherwise)

有时不想使用所有的条件,而只是想从多个条件中选择一个使用。针对这种情况,MyBatis 提供了 choose 元素,它有点像 Java 中的 switch 语句

<select id="findBlogWith" parameterType="map" resultType="blog">
    select * from blog
    <!--where标签-->
    <where>
        <choose>
            <when test="title != null">
                title=#{title}
            </when>
            <when test="author != null">
                and author=#{author}
            </when>    
            <otherwise>
                and ....
            </otherwise>
        </choose>
    </where>
</select>

2.0.3 SQL片段

增加sql代码的复用性,简化代码量,可将重复用到的sql语句抽取出来成为一个sql片段,使用直接调用

例如如下sql语句是经常用到的,可以进行一个抽取,只需要添加一个sql标签即可,id属性值可任选,方便调用

<sql id="title-author">
    <if test="title != null">
        and title=#{title}
    </if>
    <if test="author != null">
        and author=#{author}
    </if>
</sql>

然后在需要调用的地方添加include标签即可,refid属性值为sql片段的id值

<select id="findBlogWith" parameterType="map" resultType="blog">
    select * from blog
    <where>
        <include refid="title-author"></include>
    </where>
</select>

sql片段适用于简单且单表的语句,若语句过于复杂将难以实现复用,且最好不包含where标签

2.0.4 foreach标签

动态 SQL 的另一个常见使用场景是对集合进行遍历(尤其是在构建 IN 条件语句的时候)

例如如下需求:查询id为1,2,3的博客信息

select * from blog where (id=1 or id=2 or id=3);

在接口中定义方法

/**
     *查询指定范围中的博客信息
     * @param map
     * @return
     */
List<Blog> findBlogForeach(Map map);

在对应的mapper.xml文件中写sql语句,其中open标签是开始遍历时拼接的字符串,而close标签为结束遍历时拼接的字符串,separator标签为遍历对象之间所需要拼接的字符串,collection标签为传入的集合属性名,item标签为每一次遍历生成的对象

<select id="findBlogForeach" parameterType="map" resultType="blog">
    select * from blog
    <where>
        <foreach collection="ids" item="id" open="(" close=")" separator="or">
            id=#{id}<!--对应item属性的值-->
        </foreach>
    </where>;
</select>

进行测试

/**
     * 测试查询指定范围的博客信息方法
     */
    @Test
    public void findBlogForeachTest(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
        Map map = new HashMap();
        List<Integer> ids = new ArrayList<Integer>();
        ids.add(1);
        map.put("ids",ids);
        List<Blog> blogs = mapper.findBlogForeach(map);

        for (Blog blog : blogs) {
            System.out.println(blog);
        }
        sqlSession.close();
    }

下一篇介绍mybatis的缓存!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
MyBatis是一个开源的持久化框架,可以帮助我们将数据从数据库中读取出来,然后转换为Java对象,并将Java对象写入数据库中。 在C#中使用MyBatis,需要先安装MyBatis.Net库,然后在项目中引用该库。接着,我们需要创建一个配置文件,用于配置MyBatis的数据库连接信息、SQL语句等。在配置文件中,我们需要指定一个别名,用于在程序中引用这个配置文件。 接下来,我们需要创建一个映射文件,用于将数据库中的数据映射为Java对象。在映射文件中,我们需要定义一个 resultMap,用于定义Java对象与数据库表之间的关系。我们还需要定义一个 SQL 语句,用于从数据库中读取数据,并将其转换为Java对象。 在程序中,我们需要创建一个 SqlSession 对象,用于执行SQL语句。我们可以通过SqlSession对象调用selectOne、selectList、update、delete等方法,来执行SQL语句,并将结果转换为Java对象或者操作数据库。 下面是一个简单的示例,展示了如何在C#中使用MyBatis: 1. 安装MyBatis.Net库 在Visual Studio中,选择“工具”-“NuGet包管理器”-“程序包管理器控制台”,然后输入以下命令: ``` Install-Package MyBatisNet ``` 2. 创建配置文件 在项目中创建一个名为“SqlMapConfig.xml”的文件,用于配置数据库连接信息、SQL语句等。以下是一个示例配置文件: ``` xml <?xml version="1.0" encoding="utf-8" ?> <sqlMapConfig> <database> <provider name="SqlServer" connectionString="Data Source=localhost;Initial Catalog=mydatabase;User ID=myuser;Password=mypassword;" /> </database> <sqlMap> <map resource="MyMapper.xml"/> </sqlMap> </sqlMapConfig> ``` 其中,provider元素用于指定数据库类型和连接字符串,map元素用于指定映射文件路径。 3. 创建映射文件 在项目中创建一个名为“MyMapper.xml”的文件,用于将数据库中的数据映射为Java对象。以下是一个示例映射文件: ``` xml <?xml version="1.0" encoding="utf-8" ?> <sqlMap namespace="MyMapper"> <resultMap id="MyResultMap" class="MyClass"> <result property="id" column="id"/> <result property="name" column="name"/> </resultMap> <select id="selectById" resultMap="MyResultMap"> SELECT * FROM mytable WHERE id=#id# </select> </sqlMap> ``` 其中,resultMap元素用于定义Java对象与数据库表之间的关系,select元素用于定义SQL语句。 4. 在程序中使用MyBatis 在程序中,我们需要创建一个 SqlSession 对象,用于执行SQL语句。以下是一个示例代码: ``` csharp using IBatisNet.DataMapper; using IBatisNet.DataMapper.Configuration; using IBatisNet.DataMapper.Configuration.Files; // 创建配置文件 DomSqlMapBuilder builder = new DomSqlMapBuilder(); ISqlMapper sqlMapper = builder.Configure(@"SqlMapConfig.xml"); // 执行SQL语句 MyClass obj = sqlMapper.QueryForObject<MyClass>("MyMapper.selectById", new { id = 1 }); ``` 以上是一个简单的示例,展示了如何在C#中使用MyBatis。实际上,MyBatis还有很多其他的用法和功能,需要我们在实际开发中去探索和使用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值