栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

MyBatis

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

MyBatis

1 什么是MyBatis?

MyBatis 是一款优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射。MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作,使得程序员在开发时只需要关注SQL语句本身,不需要花费精力去处理加载驱动、创建连接、创建statement等繁杂的过程,花更多的精力在业务开发中。MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。

2 MyBatis全局配置文件基础设置 2.1 配置顺序

2.2 属性(properties)

属性可以在外部进行配置,可以进行动态替换。如:

	
	
		
		
	

默认值特性参考官网例子:

	
	  
	   
	
2.3 设置(settings)
 	
        
        

        
        
        

        
        
    
2.4 类型别名(typeAliases)
    
        
        

        
        
    
2.5 插件(plugins)

分页插件如下:

	
        
        
            
            
        
    
2.6 环境配置(environments)
	
    
        
            
            
                
                
                  
                
            
        
    
2.7 映射器(mappers)
    
        
        

        
        

        
        
    
3 基于MyBatis实现单表CRUD(XML) 3.1 pom.xml


    4.0.0

    org.example
    HelloMybatis
    1.0-SNAPSHOT

    
        9
        9
    

    
        
        
            org.mybatis
            mybatis
            3.4.5
        
        
        
            mysql
            mysql-connector-java
            8.0.18
        
        
        
            log4j
            log4j
            1.2.12
        
        
        
            junit
            junit
            4.12
            test
        
    


3.2 SqlMapConfig.xml配置文件



    
    
    
        
        
    

    
    
        
        

        
        
        

        
        


    

    
    
        
        

        
        
    

    
    
    
        
            
            
                
                
                  
                
            
        
    

    
    
        
        

        
        

        
        
    

3.3 User类、UserDao接口
package com.hc.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 accounts;

    // 多对多:一个用户可以赋予多个角色
    private List roles;

    
    public User() {
    }

    public User(Integer id, String username, Date birthday, String sex, String address) {
        this.id = id;
        this.username = username;
        this.birthday = birthday;
        this.sex = sex;
        this.address = address;
    }

    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;
    }

    public List getAccounts() {
        return accounts;
    }

    public void setAccounts(List accounts) {
        this.accounts = accounts;
    }

    public List getRoles() {
        return roles;
    }

    public void setRoles(List roles) {
        this.roles = roles;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", username='" + username + ''' +
                ", birthday=" + birthday +
                ", sex='" + sex + ''' +
                ", address='" + address + ''' +
                ", accounts=" + accounts +
                ", roles=" + roles +
                '}';
    }
}

package com.hc.dao;

import com.hc.domain.QueryVo;
import com.hc.domain.User;

import java.util.List;

public interface UserDao {
    
    User findOneById(Integer id);

    List findAllByName(String username);

    List findAllByCondition(User user);

    List findAllByQueryVo(QueryVo queryVo);

    List findAllAndAccount();

    List findAllAndRole();

    List findAll();

    int findTotal();

    void insertOne(User user);

    void updateOne(User user);

    void deleteOne(Integer id);
}

3.4 UserDao.xml




    
    

    
    
        select *
        from user
    

    
    
        
        
        
        
        

        
        
        
    

    
    
        
        
        
        
        

        
        
            
            
            
        
    

    
    
           
        select * from user where username like '%${value}%';         
    

    
    
    

    
    

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


    
    
        select count(1)
        from user;
    

    
    
        
        
            select last_insert_id();
        
        insert into user(username, birthday, sex, address)
        values (#{username}, #{birthday}, #{sex}, #{address});
    

    
    
        update user
        set username = #{username},
            birthday = #{birthday},
            sex=#{sex},
            address=#{address}
        where id = #{id};
    

    
    
        delete
        from user
        where id = #{id};
    

3.5 测试
import com.hc.dao.UserDao;
import com.hc.domain.QueryVo;
import com.hc.domain.User;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public class testMybatis {

    private InputStream in;
    private SqlSessionFactoryBuilder builder;
    private SqlSessionFactory factory;
    private SqlSession session;
    private UserDao userDao;

    @Before
    public void init() throws Exception {
        // 1.从 XML 中构建 SqlSessionFactory
        in = Resources.getResourceAsStream("SqlMapConfig.xml");
        builder = new SqlSessionFactoryBuilder();
        factory = builder.build(in);
        // 2.使用SqlSessionFactory生产SqlSession对象
        session = factory.openSession(true);
        // 3.使用SqlSession创建dao接口的代理对象
        userDao = session.getMapper(UserDao.class);
    }

    @After
    public void destroy() throws Exception {
        // 关闭资源
        session.close();
        in.close();
    }

    
    @Test
    public void testFindOneById() throws Exception {
        User user = userDao.findOneById(49);

        // 关闭SqlSession和清除SqlSession的缓存都会重新进行数据库的查询
        // session.close();
        // session.commit();
        session.clearCache();

        User user01 = userDao.findOneById(49);

        // true说明该用户是同一个用户
        System.out.println(user == user01);
    }

    
    @Test
    public void testFindAllByName() throws Exception {
        List users = userDao.findAllByName("覃");
        for (User u : users) {
            System.out.println(u);
        }
    }

    
    @Test
    public void testFindAllByCondition() throws Exception {
        User user = new User(null, "HC", new Date(), "男", "湖南岳阳");
        List users = userDao.findAllByCondition(user);
        for (User u : users) {
            System.out.println(u);
        }
    }

    
    @Test
    public void testFindAllByQueryVo() throws Exception {
        QueryVo queryVo = new QueryVo();
        List list = new ArrayList<>();
        list.add(41);
        list.add(42);
        queryVo.setIds(list);
        List users = userDao.findAllByQueryVo(queryVo);
        for (User u : users) {
            System.out.println(u);
        }
    }

    
    @Test
    public void testFindAllAndAccount() throws Exception {
        List users = userDao.findAllAndAccount();
        for (User u : users) {
            System.out.println(u);
        }
    }

    
    @Test
    public void testFindAllAndRole() throws Exception {
        List users = userDao.findAllAndRole();
        for (User u : users) {
            System.out.println(u);
        }
    }

    
    @Test
    public void testFindAll() throws Exception {
        List users = userDao.findAll();
        for (User u : users) {
            System.out.println(u);
        }
    }

    
    @Test
    public void testFindTotal() throws Exception {
        System.out.println(userDao.findTotal());
    }

    
    @Test
    public void testInsertOne() {
        User user = new User(null, "HC", new Date(), "男", "湖南岳阳");
        System.out.println("添加用户前:" + user.toString());
        userDao.insertOne(user);
        session.commit();  // 提交事务
        System.out.println("添加用户后:" + user.toString());
    }

    
    @Test
    public void testUpdateOne() {
        User user = new User(49, "覃杰", new Date(), "男", "湖北恩施");

        userDao.updateOne(user);
        session.commit();
    }

    
    @Test
    public void testDeleteOne() {
        userDao.deleteOne(48);
        session.commit();
    }

    @Test
    public void testTwoCache() {

        SqlSession session1 = factory.openSession();
        UserDao userDao1 = session1.getMapper(UserDao.class);
        User user01 = userDao1.findOneById(49);
        session1.clearCache();

        SqlSession session2 = factory.openSession();
        UserDao userDao2 = session1.getMapper(UserDao.class);
        User user02 = userDao2.findOneById(49);
        session2.clearCache();

        // 尽管使用了二级缓存,但是这二者也不是同一个对象,因为从SqlSessionFactory拿出的数据创建一个新的对象返回
        System.out.println(user01 == user02);
    }


}

4 Mapper.xml探索

MyBatis的用法参见官方文档。

4.1 占位符${}和#{}

参照此文。

4.2 resultMap
  • resultType:指定结果集的类型,支持基本类型和实体类类型。注意,当实体类的属性名和查询的列名不一致时,封装会失败。
    
        select *
        from t_setmeal
        where id = #{id}
    
    
        
        
        
        
        
        
        
    

    
        
    
    
    
        select *
        from t_checkitem
        where id in (select checkitem_id from t_checkgroup_checkitem where checkgroup_id = #{id})
    
4.3 MyBatis连接池

数据库连接池负责分配、管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接,而不是重新建立一个。它可以减少我们获取连接所消耗的时间,连接池里面有若干连接,每个线程需要连接的时候就取一个出来,用完了就把连接放回去,连接池本质上就是一个存储连接的容器,也可以理解为一个集合对象且该集合必须是线程安全的,不能两个线程拿到同一个连接。同时,该集合还要实现队列的特性——先进先出。

4.3.1 分类

Mybatis连接池一般分为以下三类:

  • UNPOOLED:不使用连接池的数据源,MyBatis 会创建 UnpooledDataSource 实例。
  • POOLED:使用连接池的数据源,MyBatis 会创建 PooledDataSource 实例。
  • JNDI: 使用JNDI实现数据源。
4.3.2 配置
    
        
            
            
                
                
                
                
            
        
    
4.3.3 分析

MyBatis配置使用连接池的数据源后,会创建PooledDataSource 实例。

可以看到,PooledDataSource 实例中持有一个UnpooledDataSource,也就是说当PooledDataSource需要创建java.sql.Connection对象时,还是通过UnpooledDataSource来创建,PooledDataSource 只是提供一种缓存连接池机制。注意,只有当SqlSession对象要去执行SQL语句时,MyBatis才会去调用DataSource对象创建java.sql.Connection,毕竟数据库连接是比较珍贵的资源。

4.4 主键自增与返回、缓存、动态SQL和延迟加载

参照此文。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/946801.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号