Mybatis学习第三天:Mybatis 连接池 多表操作

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
云数据库 RDS PostgreSQL,集群系列 2核4GB
简介: Mybatis学习第三天:Mybatis 连接池 多表操作

文章目录

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连接池。)

autocommit 自动提交

可以在生产session时调用SqlSession openSession(boolean var1) 方法来实现自动提交

即将session=sqlSessionFactory.openSession(); 改为session=sqlSessionFactory.openSession(true);

这时完成后就无需进行手动提交了

事务

https://www.cnblogs.com/dongguangming/p/12846052.html

resultmap

https://blog.csdn.net/weixin_44306005/article/details/88100858

mybatis标签

if和where

如果我们想实现根据已有的条件来查询用户的功能,就可以使用if和where标签

例:List finddataUser(User user);

    <select id="finddataUser" resultType="com.gegege.domain.User" parameterType="com.gegege.domain.User">
        select * from user
        <where>
            <if test="username != null ">
               and username = #{username}
            </if>
            <if test="sex != null">
                and sex = #{sex}
            </if>
        </where>
    </select>

foreach

有时我们会想要实现下面这样的语句

select * from user where id in (41,42,43,44,45,46);

我们可以定义一个实体类叫queryvo里面存放list< integer>类型的list

dao接口中添加

List<User> getListFindUser(User user);

更改IUserDao.xml

    <resultMap id="usermap" type="com.gegege.domain.User">
        <id column="id" property="id"/>
        <result column="username" property="username"/>
        <result column="birthday" property="birthday"/>
        <result column="sex" property="sex"/>
        <result column="address" property="address"/>
    </resultMap>
<select id="getListFindUser" resultMap="usermap" parameterType="com.gegege.domain.QuertyVo">
        select * from user
        <where>
            <if test="idList != null and idList.size() != null">
                <foreach collection="idList" item="id" open="and id in ( " close=")" separator=",">
                    #{id}
                </foreach>
            </if>
        </where>
    </select>

编写test函数:

   /**
     * 测试foreach
     */
    @Test
    public void testforeach() {
        List<Integer> list=new ArrayList<Integer>();
        QuertyVo vo = new QuertyVo();
        list.add(41);
        list.add(42);
        list.add(43);
        list.add(44);
        list.add(45);
        list.add(46);
        vo.setIdList(list);
         List<User> list2=dao.getListFindUser(vo);
        list2.forEach(System.out::println);
    }
}

SQL标签

对于重复的SQL语句我们可以采用

<sql id="select*"> select * from user</sql>

此标签来进行定义

在需要调用时使用

<include refid="select*"></include>

此语句进行调用

多表查询

先了解一下表之间的关系

image.png

先了解一下测试用的数据库

数据库分为用户数据库User:

image.png

账户数据库account:

image.png

其中account.uid的外键设置为User.id

那么我们先做好准备工作:

1.创建javabean

2.创建IAccountDao接口

一对一操作

如果我们在查找Account时,也需要一并找到对应用户的姓名地址

这时我们可以写出下面这样的sql语句

SELECT a.* , u.username,u.address FROM account a, user u where u.id = a.uid

便可以查询到需要的数据

但这时没有用来存储返回数据的对象

所以我们要创建一个新的javabean

image.png

此时便可以配置xml来进行接口的实现

    <select id="FindAllAccountUser" resultType="com.gegege.domain.AccountUser">
        SELECT a.* , u.username,u.address FROM account a, user u where u.id = a.uid
    </select>

这时就可以尝试调用

    private InputStream in;
    private SqlSession session;
    private IAccountDao dao;
    @Before
    public void before() throws IOException {
        in = Resources.getResourceAsStream("SqlMapConfig.xml");
        SqlSessionFactoryBuilder builder=new SqlSessionFactoryBuilder();
        session= builder.build(in).openSession(true);
        dao=session.getMapper(IAccountDao.class);
    }
    @After
    public void after() throws IOException {
        in.close();
        session.close();
    }
    /**
     * 查找所有账户及对应用户的姓名地址
     */
    @Test
    public void FindAllAccountUser() {
        List<AccountUser> list=dao.FindAllAccountUser();
        list.forEach(System.out::println);
    }

此时便可以获得结果:

image.png

一对多操作

由上面两表可知 一个用户可以拥有多个账户,这便是一对多的关系

我们怎么实现一对多的查询呢

同样我们先写出sql语句

SELECT u.*,a.ID as aid,a.UID , a.MONEY FROM user u LEFT JOIN account a on u.id = a.UID

同样我们也需要存储的容器,

在user的javabean中添加一个list即可

private List<Account> list;

更改xml文件

    <resultMap id="selectUserAccount" type="com.gegege.domain.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 property="list" ofType="com.gegege.domain.Account">
            <id column="aid" property="id"></id>
            <result column="uid" property="uid"></result>
            <result column="money" property="money"></result>
        </collection>
    </resultMap>
    <select id="findAll" resultMap="selectUserAccount">
        SELECT u.*,a.ID as aid,a.UID , a.MONEY FROM user u LEFT JOIN account a on u.id = a.UID
    </select>

测试一下

 private InputStream in;
    private SqlSessionFactoryBuilder sessionFactoryBuilder;
    private SqlSessionFactory sqlSessionFactory;
    private SqlSession session;
    private IUserDao dao;
    @Before
    public void before() throws IOException {
        in = Resources.getResourceAsStream("SqlMapConfig.xml");
        //创建工具
        sessionFactoryBuilder=new SqlSessionFactoryBuilder();
        //创建工厂
        sqlSessionFactory=sessionFactoryBuilder.build(in);
        //生产session
        session=sqlSessionFactory.openSession();
        //使用sqlsession 创建代理对象
        dao=session.getMapper(IUserDao.class);
    }
    @After
    public void after() throws IOException {
        //提交操作
        session.commit();
        //释放资源
        session.close();
        in.close();
    }
    /**
     * 测试查找
     * @throws IOException
     */
    @Test
    public void testFindAll() {
        //调用findall
        List<User> users=dao.findAll();
        for (User user:users
        ) {
            System.out.println(user+""+user.getList());
        }
    }

输出结果为:

image.png

多对多操作

image.png

按照步骤来建立数据库

建立完成后有这样三个表

1.角色表(role):

image.png

2.用户表(user):

image.png

3.中间表(user_role):

UID的外键是user表中的id

RID的外键是角色表中的ID

image.png

和一对多操作相同,我们想要查询用户表时可以查询到对应角色相关信息

查询角色表时可以查询到对应用户相关信息

可以写出sql语句:

    SELECT r.ID AS rid,r.ROLE_NAME,ROLE_DESC,u.* FROM role r
        right JOIN user_role ur ON rid = r.id
        right JOIN user u ON uid = u.id
        SELECT r.ID AS rid,r.ROLE_NAME,ROLE_DESC,u.* FROM role r
        LEFT JOIN user_role ur ON rid = r.id
        LEFT JOIN user u ON uid = u.id

有了sql语句则需要存储查询结果

则在user的javabean中和role的javabean中添加彼此的list用来存储

之后声明resultMap

    <resultMap id="Rolemap" type="com.gegege.domain.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="com.gegege.domain.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>
    <resultMap id="usermap" type="com.gegege.domain.User">
        <id column="id" property="id"/>
        <result column="username" property="username"/>
        <result column="birthday" property="birthday"/>
        <result column="sex" property="sex"/>
        <result column="address" property="address"/>
        <collection property="roles" ofType="com.gegege.domain.Role">
            <id property="roleid" column="rid"></id>
            <result property="rolename" column="ROLE_NAME"></result>
            <result property="roledesc" column="ROLE_DESC"></result>
        </collection>
    </resultMap>

声明sql查询

    <select id="findAll" resultMap="Rolemap" >
        SELECT r.ID AS rid,r.ROLE_NAME,ROLE_DESC,u.* FROM role r
        LEFT JOIN user_role ur ON rid = r.id
        LEFT JOIN user u ON uid = u.id
    </select>
    <select id="findAll"  resultMap="usermap" >
        SELECT r.ID AS rid,r.ROLE_NAME,ROLE_DESC,u.* FROM role r
        right JOIN user_role ur ON rid = r.id
        right JOIN user u ON uid = u.id
    </select>

扩展:JNDI

jndi类似于windows中的注册表,存储了键值对

需要注意项目需要时war工程 且经过tomcat服务器才可以运行

首先,将之前mybatis的工程复制过来

配置javaweb环境:

添加下面两个jar包即可

    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>servlet-api</artifactId>
      <version>2.5</version>
    </dependency>
    <dependency>
      <groupId>javax.servlet.jsp</groupId>
      <artifactId>jsp-api</artifactId>
      <version>2.1</version>
    </dependency>

配置JNDI环境:

– 1.在webapp文件夹下创建META-INF文件夹

– 2.在文件夹下创建context.xml文件

– 3.将以下配置内容添加到context.xml

<?xml version="1.0" encoding="UTF-8"?>
<Context>
<!-- 
<Resource 
name="jdbc/eesy_mybatis"            数据源的名称
type="javax.sql.DataSource"           数据源类型
auth="Container"                数据源提供者
maxActive="20"                  最大活动数
maxWait="10000"                 最大等待时间
maxIdle="5"                   最大空闲数
username="root"                 用户名
password="1234"                 密码
driverClassName="com.mysql.jdbc.Driver"     驱动类
url="jdbc:mysql://localhost:3306/eesy_mybatis"  连接url字符串
/>
 -->
<Resource 
name="jdbc/mybatis"
type="javax.sql.DataSource"
auth="Container"
maxActive="20"
maxWait="10000"
maxIdle="5"
username="root"
password="adminadmin"
driverClassName="com.mysql.cj.jdbc.Driver"
url="jdbc:mysql://localhost:3306/mybatis"
/>
</Context>

– 4.更改SqlMapConfig.xml

将原来存放数据库url密码等信息的位置更改为

这里要注意:“java:comp/env/”这段是固定的,而后面内容为自己定义的名称

  <dataSource type="JNDI">
                <property name="data_source" value="java:comp/env/jdbc/mybatis"/>
  </dataSource>**

此时执行test便发现会报错

因为要使用JNDI是需要经过服务器的

这时就要用到jsp来连接数据库

<%@ page import="org.apache.ibatis.io.Resources" %>
<%@ page import="org.apache.ibatis.session.SqlSessionFactoryBuilder" %>
<%@ page import="com.gegege.dao.IUserDao" %>
<%@ page import="com.gegege.domain.User" %>
<%@ page import="java.util.List" %>
<%@ page import="java.io.InputStream" %>
<%@ page import="org.apache.ibatis.session.SqlSessionFactory" %>
<%@ page import="org.apache.ibatis.session.SqlSession" %>
<%@page language="java" contentType="text/html; charset=UTF-8" pageEncoding="utf-8" %>
<html>
<body>
<%
    InputStream in;
    SqlSessionFactoryBuilder sessionFactoryBuilder;
    SqlSessionFactory sqlSessionFactory;
    SqlSession session2;
    IUserDao dao;
    in = Resources.getResourceAsStream("SqlMapConfig.xml");
    //创建工具
    sessionFactoryBuilder=new SqlSessionFactoryBuilder();
    //创建工厂
    sqlSessionFactory=sessionFactoryBuilder.build(in);
    //生产session
    session2=sqlSessionFactory.openSession();
    //使用sqlsession 创建代理对象
    dao=session2.getMapper(IUserDao.class);
    //调用findall
    List<User> users=dao.findAll();
    for (User user:users
    ) {
        System.out.println(user);
    }
    //提交操作
    session2.commit();
    //释放资源
    session2.close();
    in.close();
%>
</body>
</html>

此时运行打开index.jsp

便会发现控制台输出了数据库中的数据


相关实践学习
如何快速连接云数据库RDS MySQL
本场景介绍如何通过阿里云数据管理服务DMS快速连接云数据库RDS MySQL,然后进行数据表的CRUD操作。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
打赏
0
0
0
0
0
分享
相关文章
Mybatis学习:Mybatis缓存配置
MyBatis缓存配置包括一级缓存(事务级)、二级缓存(应用级)和三级缓存(如Redis,跨JVM)。一级缓存自动启用,二级缓存需在`mybatis-config.xml`中开启并配置映射文件或注解。集成Redis缓存时,需添加依赖、配置Redis参数并在映射文件中指定缓存类型。适用于查询为主的场景,减少增删改操作,适合单表操作且表间关联较少的业务。
深入探讨:Spring与MyBatis中的连接池与缓存机制
Spring 与 MyBatis 提供了强大的连接池和缓存机制,通过合理配置和使用这些机制,可以显著提升应用的性能和可扩展性。连接池通过复用数据库连接减少了连接创建和销毁的开销,而 MyBatis 的一级缓存和二级缓存则通过缓存查询结果减少了数据库访问次数。在实际应用中,结合具体的业务需求和系统架构,优化连接池和缓存的配置,是提升系统性能的重要手段。
158 4
【MyBatis】MyBatis操作数据库(一)
【MyBatis】MyBatis操作数据库(一)
70 1
如何使用 MyBatis 来进行增、删、改、查操作
如何使用 MyBatis 来进行增、删、改、查操作
372 2
|
8月前
|
基于MyBatis的增删改查操作
基于MyBatis的增删改查操作
57 1
springboot学习五:springboot整合Mybatis 连接 mysql数据库
这篇文章是关于如何使用Spring Boot整合MyBatis来连接MySQL数据库,并进行基本的增删改查操作的教程。
757 0
springboot学习五:springboot整合Mybatis 连接 mysql数据库
mybatis-plus学习
MyBatis-Plus ,MyBatis 最佳搭档,只做增强不做改变,为简化开发、提高效率而生。
72 5
后端框架的学习----mybatis框架(3、配置解析)
这篇文章详细介绍了MyBatis框架的核心配置文件解析,包括环境配置、属性配置、类型别名设置、映射器注册以及SqlSessionFactory和SqlSession的生命周期和作用域管理。
后端框架的学习----mybatis框架(3、配置解析)
后端框架的学习----mybatis框架(9、多对一处理和一对多处理)
这篇文章介绍了在MyBatis框架中如何处理多对一和一对多的关联查询,通过定义`<resultMap>`和使用`<association>`与`<collection>`元素来实现对象间的关联映射。
后端框架的学习----mybatis框架(8、lombok)
这篇文章介绍了如何在MyBatis框架中使用lombok库来简化Java实体类的编写,包括在IDEA中安装Lombok插件、在项目中导入lombok依赖以及在实体类上使用Lombok提供的注解。
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等