mybatis03

1、mybatis的连接池以及事务控制(原理部分了解,应用部分会用)
mybatis的连接池使用及分析
mybatis事务控制的分析
2、mybatis基于XML配置的动态SQL语句使用(会用即可)
mappers配置文件中的几个标签:
<if>
<where>
<foreach>
<sql>
3、mybatis中的多表操作(掌握应用)
一对多
一对一
多对多
--------------------------------------------------------------------------------------------------
1、连接池:
我们在实际开发中都会使用连接池。
因为它可以减少我们获取连接所消耗的时间。
mybatis中的连接池
mybatis连接池提供了3种方式的配置
配置的位置SqlMapConfig.xml中的dataSource标签。
type属性就是表示采用何种连接方式。
type属性的取值:
POOLED:采用传统的javax.sql.DataSource规范中的连接池,mybatis中有针对规范的实现。
UNPOOLED
JNDI:采用服务器提供的JNDI技术实现,来获取DataSource对象。不同服务器所能拿到的DataSource是不一样的。
注意:如果不是web或者maven的war工程,是不能使用的。我们实际开发中使用的是tomcat服务器。采用连接池是dbcp连接池。
--------------------------------------------------------------------------------------------------


事务:在计算机术语中是指访问并可能更新数据库中各种数据项的一个程序执行单元(unit)。
事务的四大特性ACID:
A:原子性
C:一致性
I:隔离性
D:持久性
mybatis中的事务是通过sqlsession对象的commit方法和rollback方法实现事务的提交和回滚。

在之前讲解的转账操作中,在一个方法里,多次与数据库交互,如果让每个连接处于独立的
事务提交中,事务肯定是控制不住的。在后面spring的课程中还会拿出来和大家详细的分析。


--------------------------------------------------------------------------------------------------
下面说一下在mybatis中resultMap和resultType的区别,
resultType:当使用resultType作SQL语句返回结果类型时,要求对象属性名和数据库表中的列名相同。
resultMap:当使用resultMap做SQL语句返回结果类型处理时,通常需要在mapper.xml中定义resultMap进行pojo和相应表字段的对应。
而resultMap可以通过在SqlMapConfig.xml文件中配置以使对象的属性名
可以与数据库表中的列名不相同。

<?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">

    <resultMap id="userMap" type="user">
        <!--主键字段的对应-->
        <id property="userId" column="id"></id>
        <!--非主键字段的对应-->
        <result property="userName" column="username"></result>
        <result property="userBirthday" column="birthday"></result>
        <result property="userSex" column="sex"></result>
        <result property="userAddress" column="address"></result>
    </resultMap>
    <select id="findAll" resultMap="userMap">
        SELECT * FROM user;
    </select>

    <insert id="saveUser" parameterType="user">
        INSERT INTO user(username,birthday,sex,address) VALUES (#{userName},#{userBirthday},#{userSex},#{userAddress});
    </insert>
</mapper>
--------------------------------------------------------------------------------------------------
mybatis中的动态sql语句
if标签
<select id="findUserByCondition" resultMap="userMap" parameterType="user">
        SELECT * FROM user WHERE 1=1
        <if test="userName != null">
            and username=#{userName}
        </if>
    </select>
MybatisTest.java
@Test
    public void testFindUserByCondition() {
        User user=new User();
        user.setUserName("老王");
        List<User> users = userDao.findUserByCondition(user);
        for (User user1:users) {
            System.out.println(user1);
        }
    }
where标签
<select id="findUserByCondition" resultMap="userMap" parameterType="user">
        SELECT * FROM user
        <where>
            <if test="userName != null">
                and username=#{userName}
            </if>
            <if test="userSex != null">
                and sex= #{userSex}
            </if>
        </where>
    </select>
foreach标签


com.itheima.domain.Query
package com.itheima.domain;

import java.util.List;

public class Queryvo {
    private User user;
    private List<Integer> ids;

    public User getUser() {
        return user;
    }

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

    public List<Integer> getIds() {
        return ids;
    }

    public void setIds(List<Integer> ids) {
        this.ids = ids;
    }
}
IUserDao.java
    /**
     * 根据Queryvo中提供的id***,查询用户信息
     * @param vo
     * @return
     */
    List<User> findUserInIds(Queryvo vo);
IUserDao.xml
<!--根据Queryvo中的Id***实现查询用户列表-->
    <select id="findUserInIds" resultMap="userMap" parameterType="queryvo">
        SELECT * FROM user
        <where>
            <if test="ids!=null and ids.size()>0">
                <foreach collection="ids" open="and id in (" close=")" item="id" separator=",">
                    #{id}
                </foreach>
            </if>
        </where>

    </select>
MybatisTest.java
    @Test
    public void testFindUserInIds() {
        Queryvo vo = new Queryvo();
        List<Integer> list= new ArrayList<Integer>();
        list.add(41);
        list.add(42);
        list.add(43);
        list.add(45);
        list.add(46);
        vo.setIds(list);
        List<User> users = userDao.findUserInIds(vo);
        for (User user1:users) {
            System.out.println(user1);
        }
    }
sql标签
<!--了解的内容:抽取重复的id-->
    <sql id="defaultUser">
        SELECT * FROM user
    </sql>

    <select id="findAll" resultMap="userMap">
        <!--SELECT * FROM user;-->
        <include refid="defaultUser"></include>

    </select>
--------------------------------------------------------------------------------------------------
mybatis中的多表查询
表之间的关系有几种:
一对一
一对多
多对一
多对多
举例:
用户和订单就是一对多
订单和用户就是多对一
人和身份证就是一对一
老师和学生之间是多对多
一个老师可以教多个学生
一个学生可以被多个老师教
mybatis把多对一看成一对一:
一个人可以有很多订单,订单对人就是多对一,
但是拿出每一个订单,他都只能属于一个用户。
所有mybatis就把多对一看成了一对一。

示例:用户和账户
一个用户可以有多个账户
一个账户只能属于一个用户(多个账户也可以属于同一个用户)
步骤:
1、建立两张表:用户表,账户表
让用户表和账户表之间具备一对多的关系:需要使用外键在账户表中添加
2、建立两个实体类:用户实体类和账户实体类
让用户和账户的实体类能体现出来一对多的关系。
3、建立两个配置文件:
用户的配置文件
账户的配置文件
4、实现配置:
当我们查询用户时,可以同时得到用户下所包含的账户信息。
当我们查询账户时,可以同时得到账户的所属用户信息。
--------------------------------------------------------------------------------------------------
实战时候的错误:
建好了account表,把account实体类,接口,IAccountDao.xml以及test测试类
都写好了之后发现出错,于是查了一会,最终发现在文件
SqlMapConfig.xml文件中
只写了
<mapper resource="com/itheima/dao/IUserDao.xml">
没有IAccountDao.xml的,
所以以后为了避免这种错误,还是直接在mappers中写package好啊。
<mappers>
    <package name="com.itheima.dao"></package>
</mappers>

如何做到查询所有账户,同时还要获取当前账户的所属用户信息
现在要求查询账户还要附带账户用户的姓名和地址。
方法一:通过写account的子类方式查询
com.itheima.domain.AccountUser.java
package com.itheima.domain;

public class AccountUser extends Account {

    private String username;
    private String address;

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    @Override
    public String toString() {
        return super.toString()+"   "+"AccountUser{" +
                "username='" + username + '\'' +
                ", address='" + address + '\'' +
                '}';
    }
}
com.itheima.dao.IAccountDao
/**
     * 查询所有账户,并带有用户名称和地址信息
     * @return
     */
    List<AccountUser> findAllAccount();
IAccountDao.xml
<select id="findAllAccount" resultType="accountUser">
        SELECT u.username,u.address,a.* FROM user u,account a WHERE u.id=a.uid;
</select>
test包下的AccountTest
@Test
public void testFindAllAccount() {
    List<AccountUser> accountUsers = accountDao.findAllAccount();
    for (AccountUser account:accountUsers) {
        System.out.println(account);
    }
}
刚才方法一通过写子类的方式不常用。
方法二:建立实体类关系的方式
com.itheima.domain.Account
public class Account implements Serializable {

    private Integer id;
    private Integer uid;
    private Double money;

    //从表实体应该包含一个主表实体的对象引用
    private User user;
IAccountDao.xml
    <!--定义封装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="birthday" column="birthday"></result>
            <result property="sex" column="sex"></result>
            <result property="address" column="address"></result>
        </association>
    </resultMap>
    <!--<select id="findAll" resultType="account">-->
    <select id="findAll" resultMap="accountUserMap">
        <!--SELECT * FROM account;-->
        SELECT u.username,u.address,a.* FROM user u,account a WHERE u.id=a.uid;
    </select>
test包下
AccountTest
    @Test
    public void testFindAll() {
        List<Account> accounts = accountDao.findAll();
        for (Account account:accounts) {
            System.out.println(account);
            System.out.println(account.getUser());
        }
    }
--------------------------------------------------------------------------------------------------
完成user一对多的查询
com.itheima.domain.User
    //一对多关系映射:主表实体应该包含从表实体的***引用
    private List<Account> accounts;

    public List<Account> getAccounts() {
        return accounts;
    }
IUserDao.xml
<?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="birthday" column="birthday"></result>
        <result property="sex" column="sex"></result>
        <result property="address" column="address"></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 * FROM user u LEFT OUTER JOIN account a ON u.id=a.uid;
    </select>

</mapper>
UserTest.java
@Test
public void testFindAll() {
    List<User> users = userDao.findAll();
    for (User user:users) {
        System.out.println(user);
        System.out.println(user.getAccounts());
    }
}
--------------------------------------------------------------------------------------------------
mybaits多对多
示例:用户和角色
一个用户可以有多个角色
一个角色可以有多个用户
步骤:
1、建立两张表:用户表,角色表
让用户表和角色表之间具备多对多的关系:需要使用中间表,
中间表中包含各自的主键,在中间表中是外键。
2、建立两个实体类:用户实体类和角色实体类
让用户和角色的实体类能体现出来多对多的关系。
各自包含对方一个***引用。
3、建立两个配置文件:
用户的配置文件
角色的配置文件
4、实现配置:
当我们查询用户时,可以同时得到用户下所包含的角色信息。
当我们查询角色时,可以同时得到角色所赋予的用户信息。

mybatis多对多操作——查询角色获取角色下所属用户信息。
Role.java
public class Role implements Serializable {

    private Integer roleId;
    private String roleName;
    private String roleDesc;

    private List<User> users;

    public List<User> getUsers() {
        return users;
    }
......




select * from role r
left outer join user_role ur on r.id=ur.rid
left outer join user u on u.id=ur.uid;

有两个id,所以起别名
SELECT u.*,r.id AS rid,r.`ROLE_NAME`,r.`ROLE_DESC` FROM role r
LEFT OUTER JOIN user_role ur ON r.id=ur.rid
LEFT OUTER JOIN USER u ON u.id=ur.uid;
IRoleDao.xml
<?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.IRoleDao">

    <!--定义role表的resultMap-->
    <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="birthday" column="birthday"></result>
            <result property="sex" column="sex"></result>
            <result property="address" column="address"></result>
        </collection>
    </resultMap>

    <!--查询所有-->
    <select id="findAll" resultMap="roleMap">
        SELECT u.*,r.id AS rid,r.`ROLE_NAME`,r.`ROLE_DESC` FROM role r
        LEFT OUTER JOIN user_role ur ON r.id=ur.rid
        LEFT OUTER JOIN USER u ON u.id=ur.uid;
    </select>
</mapper>
test包下RoleTest.java
@Test
public void testFindAll() {
    List<Role> roles = roleDao.findAll();
    for (Role role:roles) {
        System.out.println(role);
        System.out.println(role.getUsers());
    }
}

全部评论

相关推荐

不愿透露姓名的神秘牛友
07-04 14:35
点赞 评论 收藏
分享
避坑恶心到我了大家好,今天我想跟大家聊聊我在成都千子成智能科技有限公司(以下简称千子成)的求职经历,希望能给大家一些参考。千子成的母公司是“同创主悦”,主要经营各种产品,比如菜刀、POS机、电话卡等等。听起来是不是有点像地推销售公司?没错,就是那种类型的公司。我当时刚毕业,急需一份临时工作,所以在BOSS上看到了千子成的招聘信息。他们承诺无责底薪5000元,还包住宿,这吸引了我。面试的时候,HR也说了同样的话,感觉挺靠谱的。于是,我满怀期待地等待结果。结果出来后,我通过了面试,第二天就收到了试岗通知。试岗的内容就是地推销售,公司划定一个区域,然后你就得见人就问,问店铺、问路人,一直问到他们有意向为止。如果他们有兴趣,你就得摇同事帮忙推动,促进成交。说说一天的工作安排吧。工作时间是从早上8:30到晚上18:30。早上7点有人叫你起床,收拾后去公司,然后唱歌跳舞(销售公司都这样),7:55早课(类似宣誓),8:05同事间联系销售话术,8:15分享销售技巧,8:30经理训话。9:20左右从公司下市场,公交、地铁、自行车自费。到了市场大概10点左右,开始地推工作。中午吃饭时间大约是12:00,公司附近的路边盖饭面馆店自费AA,吃饭时间大约40分钟左右。吃完饭后继续地推工作,没有所谓的固定中午午休时间。下午6点下班后返回公司,不能直接下班,需要与同事交流话术,经理讲话洗脑。正常情况下9点下班。整个上班的一天中,早上到公司就是站着的,到晚上下班前都是站着。每天步数2万步以上。公司员工没有自己的工位,百来号人挤在一个20平方米的空间里听经理洗脑。白天就在市场上奔波,公司的投入成本几乎只有租金和工资,没有中央空调。早上2小时,晚上加班2小时,纯蒸桑拿。没有任何福利,节假日也没有3倍工资之类的。偶尔会有冲的酸梅汤和西瓜什么的。公司的晋升路径也很有意思:新人—组长—领队—主管—副经理—经理。要求是业绩和团队人数,类似传销模式,把人留下来。新人不能加微信、不能吐槽公司、不能有负面情绪、不能谈恋爱、不能说累。在公司没有任何坐的地方,不能依墙而坐。早上吃早饭在公司外面的安全通道,未到上班时间还会让你吃快些不能磨蹭。总之就是想榨干你。复试的时候,带你的师傅会给你营造一个钱多事少离家近的工作氛围,吹嘘工资有多高、还能吹自己毕业于好大学。然后让你早点来公司、无偿加班、抓住你可能不会走的心思进一步压榨你。总之,大家在找工作的时候一定要擦亮眼睛,避免踩坑!———来自网友
qq乃乃好喝到咩噗茶:不要做没有专业门槛的工作
点赞 评论 收藏
分享
白火同学:只是实习的话,你这份简历应该也差不多了。真要优化的话,因为面实习的话,没有开发经验,面试更重视技术栈水平。 1、重视JavaSE的基础吧,集合、泛型算是比较基础的基础,多线程、反射、JVM内存模型才是基础; 2、技术栈写到具体的点,比如Elasticsearch的使用写到某个点,限制面试官自由发挥,防止问了相关问题最后又答不上,如果真没把握建议不写,降低面试官的心理预期; 3、技术栈不要重复,比如技术栈第二条和第八条可以合并改为“熟悉Redis中间件,包括基本数据结构、缓存策略、持久化机制,了解缓存三剑客及其解决方案,并有相关项目经验。”; 4、项目指标量化,比如“达到xx秒的响应速度”(不过这个就有点偏校招社招的要求了,实习简历不写也无伤大雅)。
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务