美文网首页
mybatis(二)

mybatis(二)

作者: Raral | 来源:发表于2021-01-11 16:47 被阅读0次

整体介绍

  1. mybatis中的连接池以及事务控制

    1. mybatis中连接池使用及分析
    2. mybatis事务控制分析
  2. mybatis基于xml配置动态SQL语句使用

    mappers 配置文件中的几个标签

     <if> <where> <foreach> <sql>
    
  3. mybatis中的多表操作

    一对多

    一对一

    多对多


连接池

  1. 概念
    我们实际开发中都会使用连接池,因为它可以减少我们获取连接所消耗的时间

  2. mybatis中的连接池
    mybatis连接池提供了3种方式配置:
    配置的位置:
    主配置文件SqlMapConfig.xml中的dataSource标签,type属性就是采用哪种方式的连接
    type属性:

         POOLED
              采用传统的javax.sql.DataSource规范中的连接池,mybatis中有针对规范的实现
    
         UNPOOLED
              采用传统的获取连接的方式,虽然也实现Javax.sql.DataSource接口,但是并没有使用池的思想。
         JNDI
              采用服务器提供的JNDI技术实现,来获取DataSource对象,不同的服务器所能拿到DataSource是不一样。
              注意:如果不是web或者maven的war工程,是不能使用的。
              我们课程中使用的是tomcat服务器,采用连接池就是dbcp连接池。
    
  3. mybatis中的事务

    1. 什么是事务
    2. 事务4大特性
    3. 不考虑隔离性会产生的3个问题
    4. 解决办法:四种隔离级别

    它是通过sqlsession对象的commit方法和rollback方法实现事务的提交和回滚

mybatis动态sql

  1. where if (普通的输入框)
<!-- 根据不确定参数条件查询 -->
<select id="findUserByCondition" parameterType="user" resultMap="userMap">
        select * from user
        <where>
            <if test="username != null">
                and  username = #{username}
            </if>

            <if test="sex != null">
                and sex = #{sex}
            </if>
        </where>
    </select>
<!-- 测试方法 -->

测试方法

//测试 多条件查询 where if
    @Test
    public void testFindByCondition() {
        User u = new User();
        u.setUsername("老王");
        u.setSex("女");
        List<User> users = userDao.findUserByCondition(u);
        for (User user : users) {
            System.out.println(user);
        }
    }
  1. foreach (复选框)
 <!--根据queryvo中的I的集合实现查询用户列表-->
    <select id="findUserInIds" parameterType="queryvo" resultMap="userMap">
        select * from user
        <where>
            <if test="ids != null and ids.size() > 0">
              <foreach collection="ids" open="and id in (" close=")" item="uid" separator=",">
                #{uid}
              </foreach>
            </if>
        </where>
    </select>
<!-- 测试方法 -->

测试方法

//测试子查询 方法 foreach
    @Test
    public void testfindUserInIds() {
        QueryVo queryVo = new QueryVo();
        List<Integer> list = new ArrayList<Integer>();
        list.add(41);
        list.add(42);
        list.add(43);
        queryVo.setIds(list);
        List<User> users = userDao.findUserInIds(queryVo);
        for (User user : users) {
            System.out.println(user);
        }
    }

注意

1.抽离公共sql代码,主要针对查询的对应的实体类对应的列名,单独抽离出来,方便下面使用。

 <!--抽离公共sql 主要针对 查询表的时候不要用*-->
    <sql id="defaultUser">
        select id, username, sex, birthday, sex, address from user
    </sql>

<!-- 使用 -->
 <!--根据queryvo中的I的集合实现查询用户列表-->
    <select id="findUserInIds" parameterType="queryvo" resultMap="userMap">
        <include refid="defaultUser"></include>
        <where>
            <if test="ids != null and ids.size() > 0">
              <foreach collection="ids" open="and id in (" close=")" item="uid" separator=",">
                #{uid}
              </foreach>
            </if>
        </where>
    </select>

mybatis多表查询

一对多

一对一

多对多
举例:
    用户和订单就是一对多
    订单和用户就是多对一
        一个用户可以下多个订单
        多个订单属于同一个用户

    人和身份证号就是一对一
        一个人只能有一个身份证号
        一个身份证号只能属于一个人

    老师和学生之间就是多对多
        一个学生可以被多个老师教过
        一个老师可以交多个学生
特例:
    如果拿出每一个订单,他都只能属于一个用户。
    所以Mybatis就把多对一看成了一对一。
  1. mybatis 一对多的查询 关联对象
    一个用户有多个账户
    实体类
public class Account implements Serializable {
    private Integer id;
    private Integer uid;
    private Double money;

    // 体现 一对多的关系
    //从表的实体类包含一个主表的实体的对象引用
    private  User user;

    public User getUser() {
        return user;
    }

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

    public Integer getId() {
        return id;
    }

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

    public Integer getUid() {
        return uid;
    }

    public void setUid(Integer 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 +
                '}';
    }
}

dao映射文件

<!--定义封装account和user的resultMap-->
    <resultMap id="accountUserMap" type="account">
        <id property="id" column="aid"></id>
        <result property="uid" column="UID"></result>
        <result property="money" column="MONEY"></result>
        <!--一对一的关系映射 配置封装user内容-->
        <association property="user" column="UID" javaType="user">
            <id property="id" column="id"></id>
            <result property="username" column="username"></result>
            <result property="address" column="address"></result>
        </association>
    </resultMap>
    <!--配置查询所有-->
    <select id="findAll" resultMap="accountUserMap">
        select u.*,a.ID as aid,a.UID, a.MONEY from user u,account a where u.id = a.UID
    </select>
    <select id="findAllAccount" resultMap="accountUserMap">
        select a.*,u.username,u.address from user u,account a where u.id = a.UID
    </select>
  1. 一对多 关联集合
    实体类
package com.itheima.domain;

import java.io.Serializable;
import java.util.Date;
import java.util.List;

public class User implements Serializable {
    //实体类属性和表中的列名保持一致
    private Integer id;
    private String username;
    private Date birthday;
    private String sex;
    private String address;

    // 一对多
    //主表实体类包含从表实体类的“集合”引用
    private List<Account> accounts;

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

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

    public Integer getId() {
        return id;
    }

    public void setId(Integer 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 + '\'' +
                '}';
    }
}

dao的映射文件

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

<mapper namespace="com.itheima.dao.IUserDao">
    <!--定义封装User的resultMap-->
    <resultMap id="userAccountMap" type="user">
        <id property="id" column="id"></id>
        <result property="username" column="username"></result>
        <result property="address" column="address"></result>
        <result property="sex" column="sex"></result>
        <result property="birthday" column="birthday"></result>
        <!--配置user对象 accounts集合映射-->
        <collection property="accounts"   ofType="account" >
            <id property="id" column="aid"></id>
            <result property="uid" column="UID"></result>
            <result property="money" column="MONEY"></result>
        </collection>
    </resultMap>
    <!--配置查询所有-->
    <select id="findAll" resultMap="userAccountMap">
        select u.*,a.ID as aid, a.UID, a.MONEY from user u left join account a on u.id = a.UID;
    </select>

</mapper>
  1. 多表查询 多 对 多

    1. 以用户为主
      用户实体类,体现 一对多
        package com.itheima.domain;
    
        import java.io.Serializable;
        import java.util.Date;
        import java.util.List;
    
        public class User implements Serializable {
            //实体类属性和表中的列名保持一致
            private Integer id;
            private String username;
            private Date birthday;
            private String sex;
            private String address;
    
            // 一对多
            //主表实体类包含从表实体类的“集合”引用
            private List<Account> accounts;
    
            //多对多
            //一个用户对应多个角色
            private List<Role> roles;
    
            public List<Role> getRoles() {
                return roles;
            }
    
            public void setRoles(List<Role> roles) {
                this.roles = roles;
            }
    
            public List<Account> getAccounts() {
                return accounts;
            }
    
            public void setAccounts(List<Account> accounts) {
                this.accounts = accounts;
            }
    
            public Integer getId() {
                return id;
            }
    
            public void setId(Integer 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 + '\'' +
                        '}';
            }
        }
    
    

    用户的映射文件

        <resultMap id="userMap" type="user">
        <id property="id" column="id"></id>
        <result property="username" column="username"></result>
        <result property="address" column="address"></result>
        <result property="sex" column="sex"></result>
        <result property="birthday" column="birthday"></result>
    
        <collection property="roles" ofType="role">
            <id property="roleId" column="rid"></id>
            <result property="roleName" column="role_name"></result>
            <result property="roleDesc" column="role_desc"></result>
        </collection>
    </resultMap>
    <!--查询所有用户,同时获取用户的所赋予的角色-->
    <select id="findAll2" resultMap="userMap">
        select u.*, r.id as rid,r.role_name, r.role_desc from user u
        left join user_role ur on u.id = ur.uid
        left join role r on r.id = ur.rid
    </select>
    
    1. 以角色为主
      角色实体类
            package com.itheima.domain;
    
            import java.io.Serializable;
            import java.util.List;
    
            public class Role implements Serializable {
                private  Integer roleId;
                private String roleName;
                private String roleDesc;
    
                //多对多关系映射
                //一个角色对应多个用户
                private List<User> users;
    
                public List<User> getUsers() {
                    return users;
                }
    
                public void setUsers(List<User> users) {
                    this.users = users;
                }
    
                public Integer getRoleId() {
                    return roleId;
                }
    
                public void setRoleId(Integer roleId) {
                    this.roleId = roleId;
                }
    
                public String getRoleName() {
                    return roleName;
                }
    
                public void setRoleName(String roleName) {
                    this.roleName = roleName;
                }
    
                public String getRoleDesc() {
                    return roleDesc;
                }
    
                public void setRoleDesc(String roleDesc) {
                    this.roleDesc = roleDesc;
                }
    
                @Override
                public String toString() {
                    return "Role{" +
                            "roleId=" + roleId +
                            ", roleName='" + roleName + '\'' +
                            ", roleDesc='" + roleDesc + '\'' +
                            '}';
                }
            }
    
    

    角色的映射文件

    <resultMap id="roleMap" type="role">
        <id property="roleId" column="rid"></id>
        <result property="roleName" column="role_name"></result>
        <result property="roleDesc" column="role_desc"></result>
        <collection property="users" ofType="user">
            <id property="id" column="id"></id>
            <result property="username" column="username"></result>
            <result property="address" column="address"></result>
            <result property="sex" column="sex"></result>
            <result property="birthday" column="birthday"></result>
        </collection>
    </resultMap>
     <!--查询所有-->
    <!--查询所有角色,同时获取角色的所赋予的用户-->
    <select id="findAll" resultMap="roleMap">
          select u.*, r.id as rid,r.role_name, r.role_desc from role r
          left join user_role ur on r.id = ur.rid
          left join user u on u.id = ur.uid
    </select>
    

    注意

    1. mysql在window系统不区分大小写,在linux系统区分;
    2. 实体类的属性尽量使用驼峰,数据库的列名使用下划线;
    3. 当使用多表查询时,在navicat写好,复制到mapper文件,换行时多打几个空格;

相关文章

网友评论

      本文标题:mybatis(二)

      本文链接:https://www.haomeiwen.com/subject/grvdaktx.html