Mybatis

作者: 王小杰at2019 | 来源:发表于2019-02-14 23:20 被阅读47次
    1. Mybatis 介绍

      MyBatis是支持普通 SQL 查询,存储过程和高级映射的优秀持久 层框架。MyBatis 消除了几乎所有的 JDBC 代码和参数的手工设置以 及对结果集的检索封装。MyBatis 可以使用简单的 XML 或注解用于 配置和原始映射,将接口和 Java 的 POJO(Plain Old Java Objects,普 通的 Java 对象)映射成数据库中的记录.

    2. 常见的ORM框架

      JDBC‐dbUtils‐ MyBatis‐ Hibernate 
      
    3. mybatis 快速入门

    maven依赖

    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>3.3.0</version>
    </dependency>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.36</version>
    </dependency>
    

    建库建表

    CREATE TABLE emp
    (
        empno INT(10) UNSIGNED PRIMARY KEY NOT NULL AUTO_INCREMENT,
        ename VARCHAR(15),
        job VARCHAR(10),
        mgr INT(10) UNSIGNED,
        hiredate DATE,
        sal DECIMAL(7,2),
        comm DECIMAL(7,2),
        deptno INT(10) UNSIGNED,
        hiredateb DATETIME,
        mgrb INT(11),
        phone VARCHAR(255),
        CONSTRAINT emp_ibfk_1 FOREIGN KEY (deptno) REFERENCES dept (deptno)
    );
     
    CREATE INDEX deptno ON emp (deptno);   
    INSERT INTO scott.emp (ename, job, mgr, hiredate, sal, comm, deptno, hiredateb, mgrb, phone) VALUES ('JONES', 'MANAGER', 7839, '1981-04-02', 2975.00, null, 20, null, null, null);
    INSERT INTO scott.emp (ename, job, mgr, hiredate, sal, comm, deptno, hiredateb, mgrb, phone) VALUES ('MARTIN', 'SALESMAN', 7698, '1981-09-28', 1250.00, 1400.00, 30, null, null, null);
    INSERT INTO scott.emp (ename, job, mgr, hiredate, sal, comm, deptno, hiredateb, mgrb, phone) VALUES ('BLAKE', 'MANAGER', 7839, '1981-05-01', 2850.00, null, 30, null, null, null);
    INSERT INTO scott.emp (ename, job, mgr, hiredate, sal, comm, deptno, hiredateb, mgrb, phone) VALUES ('CLARK', 'MANAGER', 7839, '1981-06-09', 2450.00, null, 10, null, null, null);
    INSERT INTO scott.emp (ename, job, mgr, hiredate, sal, comm, deptno, hiredateb, mgrb, phone) VALUES ('SCOTT', 'ANALYST', 7566, '1987-07-13', 3000.00, null, 20, null, null, null);
    INSERT INTO scott.emp (ename, job, mgr, hiredate, sal, comm, deptno, hiredateb, mgrb, phone) VALUES ('KING', 'PRESIDENT', null, '1981-11-17', 5000.00, null, 10, null, null, null);
    INSERT INTO scott.emp (ename, job, mgr, hiredate, sal, comm, deptno, hiredateb, mgrb, phone) VALUES ('TURNER', 'SALESMAN', 7698, '1981-09-08', 1500.00, 0.00, 30, null, null, null);
    INSERT INTO scott.emp (ename, job, mgr, hiredate, sal, comm, deptno, hiredateb, mgrb, phone) VALUES ('ADAMS', 'CLERK', 7788, '1987-07-13', 1100.00, null, 20, null, null, null);
    INSERT INTO scott.emp (ename, job, mgr, hiredate, sal, comm, deptno, hiredateb, mgrb, phone) VALUES ('JAMES', 'CLERK', 7698, '1981-12-03', 950.00, null, 30, null, null, null);
    INSERT INTO scott.emp (ename, job, mgr, hiredate, sal, comm, deptno, hiredateb, mgrb, phone) VALUES ('FORD', 'ANALYST', 7566, '1981-12-03', 3000.00, null, 20, null, null, null);
    

    添加配置文件

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE configuration
            PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
            "http://mybatis.org/dtd/mybatis-3-config.dtd">
    <configuration>
        <properties resource="jdbc.properties"></properties>
        <environments default="development">
            <environment id="development">
                <transactionManager type="JDBC"/>
                <dataSource type="POOLED">
                    <property name="driver" value="com.mysql.jdbc.Driver"/>
                    <property name="url" value="jdbc:mysql:///scott"/>
                    <property name="username" value="root"/>
                    <property name="password" value="root"/>
                </dataSource>
            </environment>
        </environments>
        <mappers>
            <mapper resource="*/*/bean/EmpMapper.xml"></mapper>
        </mappers>
    </configuration>
    
    创建实体类
    public class Emp implements Serializable {
        private Integer empno;
        private String ename;
        private String job;
        private  Double sal;
        private Dept dept;
    }
    
    创建mapper文件
    <?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="*.*.EmpMapper">
    </mapper>
    注册mapper文件
    <mappers>
            <mapper resource="*/*/bean/EmpMapper.xml"></mapper>
    </mappers>
    
    执行定义的select语句
    String resource = "mybatis-config.xml";
            InputStream inputStream = Resources.getResourceAsStream(resource);
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
            SqlSession sqlSession = sqlSessionFactory.openSession();
            List<Emp> emps = sqlSession.selectList("cn.bdqn.bean.EmpMapper.selectEmp");
            for (Emp emp : emps) {
                System.out.println(emp);
            }
    

    操作 users 表的 CRUD
    XML的实现
    注解的实现

    几个可以优化的地方
    连接数据库的配置单独放在一个 properties 文件中

    driver=com.mysql.jdbc.Driver
    url=jdbc:mysql:///scott
    username=root
    password=root
     
    <properties resource="jdbc.properties"></properties>
     可以在 src 下加入 log4j 的配置文件,打印日志信息 
    log4j.rootLogger=DEBUG, Console
    #Console
    log4j.appender.Console=org.apache.log4j.ConsoleAppender
    log4j.appender.Console.layout=org.apache.log4j.PatternLayout
    log4j.appender.Console.layout.ConversionPattern=%d [%t] %‐5p [%c] ‐ %m%n
    log4j.logger.java.sql.ResultSet=INFO
    log4j.logger.org.apache=INFO
    log4j.logger.java.sql.Connection=DEBUG
    log4j.logger.java.sql.Statement=DEBUG
    log4j.logger.java.sql.PreparedStatement=DEBUG
    
    <settings>
           <setting name="logImpl" value="LOG4J" />
    </settings>
    

    SqlSessionFacotryUtils

    private static final ThreadLocal<SqlSession> threadLocal = new ThreadLocal<SqlSession>();
        private static SqlSessionFactory sessionFactory;
        static String CONFIG_FILE_LOCATION = "mybatis-config.xml";
        static InputStream inputStream;
        private static Properties properties;
     
        static {
            try {
                properties= new Properties();
                properties.load(MyBatisSessionFactory.class.getClassLoader().getResourceAsStream("jdbc.properties"));
    inputStream = Resources.getResourceAsStream(CONFIG_FILE_LOCATION);
                sessionFactory = new SqlSessionFactoryBuilder().build(inputStream,properties);
            } catch (Exception e) {
                System.err.println("%%%% Error Creating SessionFactory %%%%");
                e.printStackTrace();
            }
        }
     
        private MyBatisSessionFactory() {
        }
     
     
        public static SqlSession getSession() {
            System.out.println("1111111111111");
            SqlSession session = (SqlSession) threadLocal.get();
     
            if (session == null) {
                if (sessionFactory == null) {
                    rebuildSessionFactory();
                }
                 session = (sessionFactory != null) ? sessionFactory.openSession()
                        : null;
                threadLocal.set(session);
            }
     
            return session;
        }
     
     
        public static void rebuildSessionFactory() {
            try {
                inputStream = Resources.getResourceAsStream(CONFIG_FILE_LOCATION);
                sessionFactory = new SqlSessionFactoryBuilder().build(inputStream,properties);
             } catch (Exception e) {
                System.err.println("%%%% Error Creating SessionFactory %%%%");
                e.printStackTrace();
            }
        }
     
     
        public static void closeSession() {
            SqlSession session = (SqlSession) threadLocal.get();
            threadLocal.set(null);
     
            if (session != null) {
                session.close();
            }
        }
     
       
        public static SqlSessionFactory getSessionFactory() {
            return sessionFactory;
        }
     
       
        public static void setConfigFile(String configFile) {
            MyBatisSessionFactory.CONFIG_FILE_LOCATION = configFile;
            sessionFactory = null;
        }
    

    解决字段名与实体类属性名不相同的冲突
    准备表和数据
    定义实体类
    查询
    as
    ResultMap
    实现关联表查询
    需求
    员工和员工详细信息
    一对一
    Association 用于一对一的关联查询
    Property :对象属性的名称
    Javatype:对象属性的类型
    Column:所对应的外键字段名称
    Select:使用另一个查询封装结果
    嵌套结果

    嵌套查询

    一对多关联
    Collection : 一对多关联查询
    ofType:指定集合中元素对象的类型

    嵌套结果

    嵌套查询

    动态 SQL 与模糊查询
    If
    Choose(when otherwise)
    Trim(where,set)
    Foreach
    调用存储过程

    Mybatis 缓存
    一级缓存: 基于 PerpetualCache 的 HashMap 本地缓存,其存储作用域为 Session,当 Session flush 或 close 之后,该 Session 中的所有 Cache 就将清空。
    二级缓存与一级缓存其机制相同,默认也是采用 PerpetualCache,HashMap 存储,不同在于 其存储作用域为 Mapper(Namespace),并且可自定义存储源,如 Ehcache
    对于缓存数据更新机制,当某一个作用域(一级缓存 Session/二级缓存 Namespaces)的进行了 C/U/D 操作后,默认该作用域下所有 select 中的缓存将被 clear。
    spring 集成 mybatis
    maven依赖
    实体类
    mapper文件
    数据表和数据
    数据库
    Spring配置
    关联properties文件
    数据源
    sqlSessionFatory
    加载mapper文件
    事务管理
    测试

    相关文章

      网友评论

          本文标题:Mybatis

          本文链接:https://www.haomeiwen.com/subject/jyrueqtx.html