MyBatis03:连接池及事务控制、xml动态SQL语句、多表操作

今日内容:
  • mybatis中的连接池、事务控制【原理了解,应用会用】
    • mybatis中连接池的使用及分析
    • mybatis中事务控制的分析
  • mybatis中基于xml配置的动态SQL语句使用【会用即可】
    • mappers配置文件中的几个标签
      • 实现代码片段
  • mybatis中的多表操作【掌握应用】
    • 一对多
    • 一对一(?)
    • 多对多
一、mybatis的连接池和事务控制
1、连接池的介绍
  • 实际开发中都会使用连接池
    • 原因:可以减少获取连接所消耗的时间
  • 图解
MyBatis03:连接池及事务控制、xml动态SQL语句、多表操作_第1张图片
  • 分析:
    • 连接池就是用于存储连接的容器
    • 容器其实就是一个集合对象,只不过该集合是线程安全的,两个线程不能拿到同一个连接
    • 该集合还需要实现队列的先进先出特性。
while (conn == null) { //连接为空时创建
      synchronized (state) {
        if (!state.idleConnections.isEmpty()) {
          // Pool has available connection
          conn = state.idleConnections.remove(0);
2、mybatis连接池的分类
mybatis连接池提供了三种方式的配置
  • 配置的位置:
    • 主配置文件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中使用unpooled配置连接池的原理分析
MyBatis03:连接池及事务控制、xml动态SQL语句、多表操作_第2张图片
  • POOLED是从池中获取一个连接来用
  • UNPOOLED是注册驱动、获取连接
4、mybatis中使用pooled配置连接的原理分析
MyBatis03:连接池及事务控制、xml动态SQL语句、多表操作_第3张图片
MyBatis03:连接池及事务控制、xml动态SQL语句、多表操作_第4张图片
  • 空闲连接池
  • 活动连接池
MyBatis03:连接池及事务控制、xml动态SQL语句、多表操作_第5张图片
5、mybatis中的事务原理和自动提交设置
  • 了解(面试)
    • 什么是事务
    • 事务的四大特性ACID
    • 不考虑隔离性会产生的3个问题
    • 解决方法:四种隔离级别
  • mybatis的事务
    • 通过sqlSession对象的commit方法和rollback方法实现事务的提交和和回滚
MyBatis03:连接池及事务控制、xml动态SQL语句、多表操作_第6张图片
  • 如何设置为自动提交
@Override
    public void saveUser(User user) {
        //1.根据factory获取SqlSession对象
        SqlSession session = factory.openSession(true);
        //2.调用SQLSession中的方法实现查询列表
        session.insert("com.itcast.dao.IUserDao.saveUser",user);
        //3.提交事务
        //session.commit();
        //4.关闭
        session.close();
    }
二、mybatis的动态sql语句(mybatis映射文件的sql深入)
与查询相关的查询条件
1、if标签

    
2、where标签

    
3、foreach和sql标签
  • 举例:select * from user where username in(43,44);
/**
     * 根据queryvo中提供的id集合,查询用户集合
     * @param vo
     * @return
     */
    List findByUserInIds(QueryVo vo);

    
/**
     * 测试foreach
     */
    @Test
    public void testfindInIds() throws IOException {
        QueryVo vo = new QueryVo();
        List list = new ArrayList<>();
        list.add(41);
        list.add(42);
        list.add(44);
        vo.setIds(list);
        List users = userDao.findByUserInIds(vo);
        for (User user : users) {
            System.out.println(user);
        }
    }
抽取代码片段及使用

        select * from user
    
    
三、mybatis的多表操作
1、mybatis表之间关系分析
  • 一对多
    • 举例:一个用户可以下多个订单
  • 多对一
    • 举例:一个班级有多个学生
  • 一对一
  • 多对多
    • 举例:一个学生可以有多个老师,一个老师可以有多个学生
  • 特例:拿出每一个订单都只属于一个用户,所以mybatis就把多对一看成一对一
2、完成account表的建立及实现单表查询
  • 示例:用户和账户
    • 一个用户可以有多个账户
    • 一个账户只能属于一个用户(多个账户可以只属于同一个用户)
  • 步骤:
    • 建立用户表和账户表
      • 让用户表和账户表之间具备一对多的关系,需要在账户表中添加外键
    • 建立两个实体类:用户实体类和账户实体类
      • 让用户和账户的实体类能体现出一对多的关系
    • 建立两个配置文件
      • 用户的配置文件
      • 账户的配置文件
    • 实现配置:
      • 当查询用户时,可以同时得到用户下所包含的账户信息
      • 当查询账户时,可以同时得到账户的所属用户信息
3、 完成account一对一操作---一对多(不常用)




    
    
    



    
    
    
    
        
        
        
        
    
    
    
        
        
            
            
            
            
                
                
                
                
            
        
    
    
    
        
        
        
    
/**
     * 测试查询所有账户,同时包含用户名称和地址
     */
    @Test
    public void testFindAllAccount(){
        List aus = accountDao.findAllAccount();
        for (AccountUser au : aus) {
            System.out.println(au);
        }
    }
@Override
    public String toString() {
        return super.toString() +
                "AccountUser{" +
                "username='" + username + '\'' +
                ", address='" + address + '\'' +
                '}';
    }
4、完成account一对一操作-建立实体类关系的方式
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;
    }




    
    
        
        
        
        
        
            
            
            
            
            
        
    
    
    
    
/**
     * 测试查询所有
     */
    @Test
    public void testFindAll(){
        List accounts = accountDao.findAll();
        for (Account account : accounts) {
            System.out.println("-----每个account的信息-----");
            System.out.println(account);
            System.out.println(account.getUser());
        }
    }
5、完成user的一对多查询操作
MyBatis03:连接池及事务控制、xml动态SQL语句、多表操作_第7张图片




    
    
        
        
        
        
        
        
        
            
            
            
        
    
    
/**
     * 测试查询所有
     */
    @Test
    public void testFindAll(){
        List users = userDao.findAll();
        for (User user : users) {
            System.out.println("-----每个account的信息-----");
            System.out.println(user);
            System.out.println(user.getAccounts());
        }
    }
public class User implements Serializable {
    private Integer id;
    private String username;
    private String address;
    private String sex;
    private Date birthday;
    //建立一对多关系映射,主表实体应该包含从表实体的集合引用
    private List accounts;

    public List getAccounts() {
        return accounts;
    }

    public void setAccounts(List accounts) {
        this.accounts = accounts;
    }
6、分析mybatis多对多的步骤并搭建环境
多对多
  • 示例:用户和角色(用户的身份)
    • 用户可以有多个角色
    • 一个角色也可以赋予多个用户
  • 步骤:
    • 建立用户表和角色表
      • 让用户表和角色表之间具备一对多的关系
      • 需要使用中间表,中间表中包含各自的主键,在中间表中是外键
    • 建立两个实体类:用户实体类和角色实体类
      • 让用户和角色的实体类能体现出多对多的关系
      • 各自包含对方的集合引用
    • 建立两个配置文件
      • 用户的配置文件
      • 角色的配置文件
    • 实现配置:
      • 当查询用户时,可以同时得到用户下所包含的角色信息
      • 当查询角色时,可以同时得到角色的所赋予的用户信息
7、mybatis多对多准备角色表的实体类和映射配置
public class Role implements Serializable {
    private Integer roleId;
    private String roleName;
    private String roleDesc;
package com.itcast.dao;

import com.itcast.domain.Role;

import java.util.List;

public interface IRoleDao {
    /**
     * 查询所有角色
     * @return
     */
    List findAll();
}



    
    
        
        
        
        
    
    
8、mybatis多对多操作-查询角色获取角色下所属用户信息
MyBatis03:连接池及事务控制、xml动态SQL语句、多表操作_第8张图片
两次左外连接才能实现功能
MyBatis03:连接池及事务控制、xml动态SQL语句、多表操作_第9张图片
public class Role implements Serializable {
    private Integer roleId;
    private String roleName;
    private String roleDesc;
    //多对多的关系映射:一个角色可以赋予多个用户
    private List users;

    public List getUsers() {
        return users;
    }

    public void setUsers(List users) {
        this.users = users;
    }

    
    
        
        
        
        
        
            
            
            
            
            
        
    
    
/**
     * 测试查询所有
     */
    @Test
    public void testFindAll(){
        List roles = roleDao.findAll();
        for (Role role : roles) {
            System.out.println("-----每个角色的信息-----");
            System.out.println(role);
            System.out.println(role.getUsers());
        }
    }
9、mybatis多对多操作-查询用户获取用户所包含的角色信息
-- 查询角色时查出用户
SELECT * FROM role;
SELECT * FROM USER;
-- 两次左外连接
SELECT u.*,r.`ID` 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 u.*,r.`ID` rid,r.`ROLE_NAME`,r.`ROLE_DESC` FROM USER u 
LEFT OUTER JOIN user_role ur ON u.id = ur.`UID`
LEFT OUTER JOIN role r ON r.id = ur.`RID`




    
    
        
        
        
        
        
        
        
            
            
            
        
    
    
public class User implements Serializable {
    private Integer id;
    private String username;
    private String address;
    private String sex;
    private Date birthday;
    //多对多的关系映射:一个用户可以具备多个角色
    private List roles;

    public List getRoles() {
        return roles;
    }

    public void setRoles(List roles) {
        this.roles = roles;
    }
四、JNDI
1、JNDI概述和原理
  • JNDI(Java Naming and Directory Interface,Java命名和目录接口)是SUN公司提供的一种标准的Java命名系统接口.
  • 是SUN公司推出的一套规范,属于JavaEE技术之一。目的是模仿windows系统中的注册表(搜索-regedit)。
    • win的 key存放的为:路径+名称
MyBatis03:连接池及事务控制、xml动态SQL语句、多表操作_第10张图片
MyBatis03:连接池及事务控制、xml动态SQL语句、多表操作_第11张图片
MyBatis03:连接池及事务控制、xml动态SQL语句、多表操作_第12张图片
2、JNDI搭建maven的war工程
MyBatis03:连接池及事务控制、xml动态SQL语句、多表操作_第13张图片
3、测试JNDI数据源的使用以及使用细节
  • 使用了tomcat的数据源,必须要经过服务器,原先的test方法无法使用
JNDI 数据源

JNDIJava Naming and Directory Interface。是SUN公司推出的一套规范,属于JavaEE技术之一。目的是模仿windows系统中的注册表。

在服务器中注册数据源:

1.1 创建Mavenwar工程并导入坐标

MyBatis03:连接池及事务控制、xml动态SQL语句、多表操作_第14张图片

          org.mybatis      mybatis      3.4.5              mysql      mysql-connector-java      5.1.6              log4j      log4j      1.2.12              junit      junit      4.10          javax.servlet    servlet-api    2.5        javax.servlet.jsp    jsp-api    2.0  

1.2 webapp文件下创建META-INF目录

MyBatis03:连接池及事务控制、xml动态SQL语句、多表操作_第15张图片

1.3 META-INF目录中建立一个名为context.xml的配置文件

MyBatis03:连接池及事务控制、xml动态SQL语句、多表操作_第16张图片

1.4 修改SqlMapConfig.xml中的配置

 

MyBatis03:连接池及事务控制、xml动态SQL语句、多表操作_第17张图片

<%@ page import="java.io.InputStream" %>
<%@ page import="org.apache.ibatis.io.Resources" %>
<%@ page import="org.apache.ibatis.session.SqlSessionFactoryBuilder" %>
<%@ page import="org.apache.ibatis.session.SqlSession" %>
<%@ page import="org.apache.ibatis.session.SqlSessionFactory" %>
<%@ page import="com.itcast.dao.IUserDao" %>
<%@ page import="com.itcast.domain.User" %>
<%@ page import="java.util.List" %>
<%@ page language="java" contentType="text/html; utf-8" pageEncoding="utf-8" %>


Hello World!

<% //1.读取配置文件 InputStream in = Resources.getResourceAsStream("SqlMapConfig.xml"); //2.创建SqlSessionFactory工厂 SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder(); SqlSessionFactory factory = builder.build(in); //3.使用工厂生产SqlSession对象 SqlSession sqlSession = factory.openSession();//与jsp的隐式对象session冲突 //4.使用SqlSession创建Dao接口的代理对象 IUserDao userDao = sqlSession.getMapper(IUserDao.class); //5.使用代理对象执行方法 System.out.println("你好"); List users = userDao.findAll(); for (User user : users) { System.out.println(user); } //6.释放资源 sqlSession.close(); in.close(); %>
来自为知笔记(Wiz)

你可能感兴趣的:(xml,sql,mybatis,java,mysql)