mybatis(二)

整体介绍

  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文件,换行时多打几个空格;
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,036评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,046评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,411评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,622评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,661评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,521评论 1 304
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,288评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,200评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,644评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,837评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,953评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,673评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,281评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,889评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,011评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,119评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,901评论 2 355

推荐阅读更多精彩内容

  • 在上篇Mybatis 入门 中,我们只配置了environment, mappers两个最基本的配置项,但其实这里...
    币来币往阅读 298评论 0 0
  • 第二天内容 二 mybatis配置详解MyBatis最关键的组成部分是SqlSessionFactory,我们可以...
    冰川_阅读 341评论 0 0
  • Mybatis的使用 1.InputStream inputStream = Resources.getReso...
    终城城城阅读 354评论 0 0
  • 1. MyBatis中的连接池与事务控制 连接池 : 在实际开发中都会使用连接池,因为它可以减少获取连接所消耗的时...
    itlu阅读 380评论 0 0
  • 久违的晴天,家长会。 家长大会开好到教室时,离放学已经没多少时间了。班主任说已经安排了三个家长分享经验。 放学铃声...
    飘雪儿5阅读 7,523评论 16 22