Mybatis分页,注解,多对一,一对多

1.分页


我们为什么要分页呢?

  • 减少数据的处理量

使用Limit分页

select * from mybatis.user limit  startIndex,pageSize;
select * from mybatis.user limit 0,5;

使用mybatis实现分页,核心SQL
1.接口,这里我们使用万能的Map进行传参数(可以去找我前面写的文章关于CRUD的)

    //分页
    List<User> getUserByLimit(Map<String,Integer> map);

2.Mapper.xml

  <select id="getUserByLimit" resultType="com.lwq.pojo.User" parameterType="map">
      select  * from mybatis.user limit #{startIndex},#{pageSize}
    </select>

3.测试

  public void getUserByLimit() {
        HashMap<String, Integer> HashMap = new HashMap<String, Integer>();
        HashMap.put("startIndex",0);
        HashMap.put("pageSize",5);
        SqlSession sqlSession = MbatisUtlis.getSqlSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        List<User> userByLimit = mapper.getUserByLimit(HashMap);
        for (User user : userByLimit) {
            System.out.println(user);
        }
        sqlSession.close();
    }

2.分页插件

在这里插入图片描述

3.注解开发


3.1 面向接口编程

大家之前都学过面向对象编程,也学习过接口,但在真正的开发中,很多时候我们会选择面向接口编程

  • 根本原因 : 解耦 , 可拓展 , 提高复用 , 分层开发中 , 上层不用管具体的实现 , 大家都遵守共同的标准 , 使得开发变得容易 , 规范性更好
  • 在一个面向对象的系统中,系统的各种功能是由许许多多的不同对象协作完成的。在这种情况下,各个对象内部是如何实现自己的,对系统设计人员来讲就不那么重要了;
  • 而各个对象之间的协作关系则成为系统设计的关键。小到不同类之间的通信,大到各模块之间的交互,在系统设计之初都是要着重考虑的,这也是系统设计的主要工作内容。面向接口编程就是指按照这种思想来编程。

关于接口的理解

  • 接口从更深层次的理解,应是定义(规范,约束)与实现(名实分离的原则)的分离。
  • 接口的本身反映了系统设计人员对系统的抽象理解。
  • 接口应有两类:
    • 第一类是对一个个体的抽象,它可对应为一个抽象体(abstract class);
    • 第二类是对一个个体某一方面的抽象,即形成一个抽象面(interface);
    • 一个体有可能有多个抽象面。抽象体与抽象面是有区别的。

3.2使用注解开发

1.注解在接口上面实现


    @Select("select * from user")
    List<User> getUserList();

2.需要在核心配置文件中绑定接口

 <mappers>
        <mapper class="com.lwq.dao.UserMapper"></mapper>
    </mappers>

在这里插入图片描述
3.测试


    @Test
    public void Test1() {
        SqlSession sqlSession = null;
        try {
            sqlSession = MbatisUtlis.getSqlSession();
         //底层主要应用放射
            UserMapper mapper = sqlSession.getMapper(UserMapper.class);
            List<User> list = mapper.getUserList();
            for (User user : list) {
                System.out.println(user);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //不要忘记关闭sqlSession哟
            sqlSession.close();
        }
    }

4.测试结果成功
在这里插入图片描述
mybatis详细流程图
在这里插入图片描述

4.注解实现CRUD

我们可以在工具类中创建的时候实现自动提交事务(设置为true)
在这里插入图片描述

4.1查询操作

接口

 @Select("select * from user")
    List<User> getUserList();

    //方法存在多个参数,所有的参数必须加上@Param
    @Select("select * from user where id=#{id}")
    User getUserById(@Param("id") int id);

测试类

 @Test
    public void Test1() {
        SqlSession sqlSession = null;
        try {
            sqlSession = MbatisUtlis.getSqlSession();
         //底层主要应用放射
            UserMapper mapper = sqlSession.getMapper(UserMapper.class);
            List<User> list = mapper.getUserList();
            for (User user : list) {
                System.out.println(user);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //不要忘记关闭sqlSession哟
            sqlSession.close();
        }
    }

    @Test
    public void getByIdTest() {
        SqlSession sqlSession = MbatisUtlis.getSqlSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        User userById = mapper.getUserById(5);
        System.out.println(userById);
        sqlSession.close();
    }

运行结果
在这里插入图片描述
在这里插入图片描述

4.2增加操作

接口

  @Insert("insert into user(id,name,pwd) values(#{id},#{name},#{pwd})")
    int addUser(User user);

测试类

    @Test
    public void addUser() {
        SqlSession sqlSession = MbatisUtlis.getSqlSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        int i = mapper.addUser(new User(18, "开学啦", "123456"));
        if (i>0){
            System.out.println("插入成功");
        }else {
            System.out.println("插入失败");
        }
        sqlSession.close();
    }

测试结果
在这里插入图片描述

4.3更新操作

接口

 @Update("update user set name=#{name},pwd=#{pwd} where id=#{id}")
     int updateUser(User user);

测试类

 @Test
    public void updateUser() {
        SqlSession sqlSession = MbatisUtlis.getSqlSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        int i = mapper.updateUser(new User(18, "开学啦哟", "1234567"));
        if (i>0){
            System.out.println("修改成功");
        }else {
            System.out.println("修改失败");
        }
        sqlSession.close();
    }

测试结果
在这里插入图片描述

4.4删除操作

接口

   @Delete("delete from user where id=#{id}")
    int deleteUser(int id);

测试类

  @Test
    public void deleteUser() {
        SqlSession sqlSession = MbatisUtlis.getSqlSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        int i = mapper.deleteUser(16);
        if (i>0){
            System.out.println("删除成功");
        }else {
            System.out.println("删除失败");
        }
        sqlSession.close();
    }

测试结果
在这里插入图片描述

5.多对一处理

在这里插入图片描述

  • 多个学生,对应一个老师
  • 对于学生来说,关联…多个学生,关联一个老师【多对一】
  • 对于老师来说,集合,一个老师有很多学生【一对多】
    在这里插入图片描述
    SQL语句
CREATE TABLE `teacher` (
`id` INT(10) NOT NULL,
`name` VARCHAR(30) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=INNODB DEFAULT CHARSET=utf8

INSERT INTO teacher(`id`, `name`) VALUES (1, '秦老师'); 

CREATE TABLE `student` (
`id` INT(10) NOT NULL,
`name` VARCHAR(30) DEFAULT NULL,
`tid` INT(10) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `fktid` (`tid`),
CONSTRAINT `fktid` FOREIGN KEY (`tid`) REFERENCES `teacher` (`id`)
) ENGINE=INNODB DEFAULT CHARSET=utf8INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('1', '小明', '1'); 
INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('2', '小红', '1'); 
INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('3', '小张', '1'); 
INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('4', '小李', '1'); 
INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('5', '小王', '1');

测试环境搭建
1.新建实体类Teacher,Student
2.建立Mapper接口
3.建立Mapper.xml文件
4.在核心配置文件在绑定注册我们的Mapper接口或者文件
4.测试查询是否能成功

按照查询嵌套处理

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.lwq.dao.StudentMapper">

    <!--    思路:
               1.查询所有的学生信息
               2.根据学生的tid,寻找对应的老师
    -->
    <select id="getStudent" resultMap="StudentTeacher">
    select * from student
    </select>
    <resultMap id="StudentTeacher" type="Student">
        <result property="id" column="id"></result>
        <result property="name" column="name"></result>
        <!--            复杂的属性需要单独处理- -->
        <!--               对象:association-->
        <!--               集合:collection-->
        <association property="teacher" column="tid" javaType="Teacher" select="getTeacher"></association>
    </resultMap>
    <select id="getTeacher" resultType="Teacher">
       select  * from teacher where id=#{id};
    </select>
</mapper>

按照结果嵌套处理

  <!--按照结果嵌套处理-->
    <select id="getStudent2" resultMap="StudentTeacher2">
   select  s.id sid,s.name sname,t.name tname, t.id tid
    from student s,teacher t
     where s.tid=t.id;
    </select>
    <resultMap id="StudentTeacher2" type="Student">
        <result property="id" column="sid"></result>
        <result property="name" column="sname"></result>
        <association property="teacher" javaType="Teacher">
            <result property="name" column="tname"></result>
            <result property="id" column="tid"></result>
        </association>
    </resultMap>

回顾一下MySQL多对一查询方式:

  • 子查询
  • 联表查询

6.一对多处理


比如:一个老师拥有好多好多个学生
对于老师而言,就是一对多的关系
1.环境搭建,和刚才一样的
按照结果嵌套处理

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.lwq.dao.TeacherMapper">
    <!--    按照结果嵌套查询-->
    <select id="getTeacher" resultMap="TeacherStudent">
   select s.id sid,s.name sname,t.name tname,t.id tid
   from student s,teacher t
   where s.tid=t.id and t.id=#{tid};
    </select>
    <resultMap id="TeacherStudent" type="Teacher">
        <result property="id" column="tid"></result>
        <result property="name" column="tname"></result>
        <!--        复杂的属性,我们需要单独处理  对象association  集合collection-->
        <!--        javaType="" 指定属性的类型-->
        <!--        集合中的泛型信息,我们使用ofType获取-->
        <collection property="students" ofType="Student">
            <result property="id" column="sid"></result>
            <result property="name" column="sname"></result>
            <result property="tid" column="tid"></result>
        </collection>
    </resultMap>
</mapper>

按照查询嵌套处理

   <select id="getTeacher2" resultMap="TeacherStudent2">
        select  * from teacher where id=#{tid};
    </select>
    <resultMap id="TeacherStudent2" type="Teacher">
       <collection property="students"  javaType="ArrayList" ofType="Student" select="getStudentByTeacherId" column="id">

       </collection>
    </resultMap>
    <select id="getStudentByTeacherId" resultType="Student">
        select * from student where tid=#{tid}
    </select>

注意的点


  • 关联- association [多对一]
  • 集合- collection[一对多]
  • javaType & ofType
    1.javaType 用来指定实体类中的属性的类型
    2.ofType 用来指定映射到List或者集合中pojo类型,泛型中的约束类型
  • 保证SQL的可读性 ,尽量保证读的懂
  • 注意一对多喝多对一中,属性和字段的问题

7.动态SQL


什么是动态SQL:动态SQL就是根据不同的条件生成不同的SQL语句

要进行练习首先需搭建环境

CREATE TABLE `blog`(
                       `id` VARCHAR(50) NOT NULL COMMENT '博客id',
                       `title` VARCHAR(100) NOT NULL COMMENT '博客标题',
                       `author` VARCHAR(30) NOT NULL COMMENT '博客作者',
                       `create_time` DATETIME NOT NULL COMMENT '创建时间',
                       `views` INT(30) NOT NULL COMMENT '浏览量'
)ENGINE=INNODB DEFAULT CHARSET=utf8

创建一个基础工程
1.编写配置文件

<?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核心配置文件-->
<configuration>
    <!--    引入外部配置文件-->
    <properties resource="db.properties"></properties>

<!--    配置日志-->
    <settings>
        <setting name="logImpl" value="LOG4J"/>
    </settings>

<!--        可以给实体类写别名-->
    <typeAliases>
<!--        <typeAlias type="com.lwq.pojo.User" alias="User"></typeAlias>-->
        <package name="com.lwq.pojo"/>
    </typeAliases>

    <environments default="development">
        <environment id="development">
            <!--            事务管理,jdbc-->
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="${driver}"/>
                <property name="url" value="${url}"/>
                <property name="username" value="${username}"/>
                <property name="password" value="${password}"/>
            </dataSource>
        </environment>
    </environments>
<mappers>
    <mapper class="com.lwq.dao.BlogMapper"></mapper>
</mappers>

</configuration>

db.properties配置文件
driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/mybatis?serverTimezone=GMT
username=root
password=147258

2.编写实体类

package com.lwq.pojo;

import java.util.Date;

/**
 * 2 * @Author: lwq
 * 3 * @Date: 2020/6/3 20:54
 * 4
 */
public class Blog {
    private String id;
    private String title;

    public Blog(String id, String title, String author, Date create_time, int views) {
        this.id = id;
        this.title = title;
        this.author = author;
        this.create_time = create_time;
        this.views = views;
    }

    public Blog() {
    }

    private String author;
    private Date create_time;
    private int views;

    public String getId() {
        return id;
    }

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

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getAuthor() {
        return author;
    }

    public void setAuthor(String author) {
        this.author = author;
    }

    public Date getCreate_time() {
        return create_time;
    }

    public void setCreate_time(Date create_time) {
        this.create_time = create_time;
    }

    public int getViews() {
        return views;
    }

    public void setViews(int views) {
        this.views = views;
    }

    @Override
    public String toString() {
        return "Blog{" +
                "id='" + id + '\'' +
                ", title='" + title + '\'' +
                ", author='" + author + '\'' +
                ", create_time=" + create_time +
                ", views=" + views +
                '}';
    }
}

3.编写实体类对应Mapper接口 和Mapper.XML文件

package com.lwq.dao;

import com.lwq.pojo.Blog;
import org.apache.ibatis.annotations.Insert;

/**
 * 2 * @Author: lwq
 * 3 * @Date: 2020/6/3 20:13
 * 4
 */

//插入数据
public interface BlogMapper {

  int addBook(Blog blog);
}


<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.lwq.dao.BlogMapper">

    <insert id="addBook" parameterType="blog">
  insert  into blog(id,title,author,create_time,views)
  values(#{id},#{title},#{author},#{create_time},#{views})

</insert>

</mapper>

4.在核心配置文件在绑定注册我们的Mapper接口或者文件

1.动态SQL之 if

接口

 List<Blog> queryBlogIf(Map map);

xml配置文件(关于where标签的作用 :where 元素只会在子元素返回任何内容的情况下才插入 “WHERE” 子句。而且,若子句的开头为 “AND” 或 “OR”,where 元素也会将它们去除。)

  <select id="queryBlogIf" parameterType="map" resultType="blog">
        select * from blog
          <where>
            <if test="title !=null">
                and title=#{title}
            </if>
            <if test="author !=null">
                and author=#{author}
            </if>
          </where>
    </select>

测试类


    @Test
    public void queryBlogIf() {
        SqlSession sqlSession = MbatisUtlis.getSqlSession();
        BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
        HashMap hashMap = new HashMap();
//        hashMap.put("title", "java如此简单");
        hashMap.put("author","小罗老师");
        List<Blog> list = mapper.queryBlogIf(hashMap);
        for (Blog blog : list) {
            System.out.println(blog);
        }
        sqlSession.close();
    }

2.choose、when、otherwise


    <select id="queryBlogChoose" parameterType="map" resultType="blog">
        select * from mybatis.blog
        <where>
            <choose>
                <when test="title!=null">
                   and title=#{title}
                </when>
                <otherwise>
                    and views=#{views}
                </otherwise>
            </choose>
        </where>
    </select>

3.trim、where、set

 select * from blog
          <where>
            <if test="title !=null">
                and title=#{title}
            </if>
            <if test="author !=null">
                and author=#{author}
            </if>
          </where>
 <update id="updateBlog" parameterType="map">
        update mybatis.blog
        <set>
            <if test="title!=null">
                title=#{title},
            </if>
            <if test="author!=null">
                author=#{author},
            </if>
            <if test="views!=null">
                views=#{views}
            </if>
        </set>
        where id=#{id}
    </update>

其实动态SQL,本质上还是SQL语句,只是可以在SQL语句的基础上加一些逻辑代码。
if
where,set,choose,when

8.SQL片段

有的时候,我们可能会将一些功能的部分抽取出来,方便复用
SQL标签抽取的公共的部分

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

在需要的地方使用include标签引入

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

解释:
在这里插入图片描述
注意事项:

  • 最好基于单表来定义SQL片段(简单来说就是写的东西简单一点,这样重复利用的机会更多)
  • 不要存在where标签

动态SQL就是在拼接SQL语句,我们只要保证SQL的正确性,安装SQL的格式,去排列组合就可以了
建议:

  • 先在mysql中写出完整的SQL,在对应的去修改成为我们的动态SQL实现通用即可。
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值