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>

此语句进行调用

多表查询

先了解一下表之间的关系
在这里插入图片描述
先了解一下测试用的数据库
数据库分为用户数据库User:
在这里插入图片描述
账户数据库account:
在这里插入图片描述
其中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
在这里插入图片描述
此时便可以配置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);
    }

此时便可以获得结果:
在这里插入图片描述

一对多操作

由上面两表可知 一个用户可以拥有多个账户,这便是一对多的关系
我们怎么实现一对多的查询呢
同样我们先写出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());
        }
    }

输出结果为:
在这里插入图片描述

多对多操作

在这里插入图片描述
按照步骤来建立数据库
建立完成后有这样三个表
1.角色表(role):
在这里插入图片描述
2.用户表(user):
在这里插入图片描述
3.中间表(user_role):
UID的外键是user表中的id
RID的外键是角色表中的ID
在这里插入图片描述
和一对多操作相同,我们想要查询用户表时可以查询到对应角色相关信息
查询角色表时可以查询到对应用户相关信息
可以写出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
便会发现控制台输出了数据库中的数据

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值