1、数据库操作框架的历程

(1) JDBC

JDBC(Java Data Base Connection,java数据库连贯)是一种用于执行SQL语句的Java API,能够为多种关系数据库提供对立拜访,它由一组用Java语言编写的类和接口组成.JDBC提供了一种基准,据此能够构建更高级的工具和接口,使数据库开发人员可能编写数据库应用程序

  • 长处:运行期:快捷、高效
  • 毛病:编辑期:代码量大、繁琐异样解决、不反对数据库跨平台

    (2) DBUtils

DBUtils是Java编程中的数据库操作实用工具,玲珑简略实用。

DBUtils封装了对JDBC的操作,简化了JDBC操作,能够少写代码。

DBUtils三个外围性能介绍

1、QueryRunner中提供对sql语句操作的API

2、ResultSetHandler接口,用于定义select操作后,怎么封装后果集

3、DBUtils类,它就是一个工具类,定义了敞开资源与事务处理的办法

(3)Hibernate

Hibernate 是由 Gavin King 于 2001 年创立的凋谢源代码的对象关系框架。它弱小且高效的构建具备关系对象持久性和查问服务的 Java 应用程序。

Hibernate 将 Java 类映射到数据库表中,从 Java 数据类型中映射到 SQL 数据类型中,并把开发人员从 95% 的公共数据持续性编程工作中解放出来。

Hibernate 是传统 Java 对象和数据库服务器之间的桥梁,用来解决基于 O/R 映射机

Hibernate 劣势

  • Hibernate 应用 XML 文件来解决映射 Java 类别到数据库表格中,并且不必编写任何代码。
  • 为在数据库中间接贮存和检索 Java 对象提供简略的 APIs。
  • 如果在数据库中或任何其它表格中呈现变动,那么仅须要扭转 XML 文件属性。
  • 形象不相熟的 SQL 类型,并为咱们提供工作中所相熟的 Java 对象。
  • Hibernate 不须要应用程序服务器来操作。
  • 操控你数据库中对象简单的关联。
  • 最小化与拜访数据库的智能提取策略。
  • 提供简略的数据询问。

    Hibernate劣势

  • hibernate的齐全封装导致无奈应用数据的一些性能。
  • Hibernate的缓存问题。
  • Hibernate对于代码的耦合度太高。
  • Hibernate寻找bug艰难。
  • Hibernate批量数据操作须要大量的内存空间而且执行过程中须要的对象太多

    (4) JDBCTemplate

JdbcTemplate针对数据查问提供了多个重载的模板办法,你能够依据须要选用不同的模板办法.如果你的查问很简略,仅仅是传入相应SQL或者相干参数,而后获得一个繁多的后果,那么你能够抉择如下一组便当的模板办法。

长处:运行期:高效、内嵌Spring框架中、反对基于AOP的申明式事务
毛病:必须于Spring框架联合在一起应用、不反对数据库跨平台、默认没有缓存

2、什么是Mybatis?

MyBatis 是一款优良的长久层框架,它反对自定义 SQL、存储过程以及高级映射。MyBatis 罢黜了简直所有的 JDBC 代码以及设置参数和获取后果集的工作。MyBatis 能够通过简略的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,一般老式 Java 对象)为数据库中的记录。

长处:

1、与JDBC相比,缩小了50%的代码量

2、 最简略的长久化框架,简略易学

3、SQL代码从程序代码中彻底分离出来,能够重用

4、提供XML标签,反对编写动静SQL

5、提供映射标签,反对对象与数据库的ORM字段关系映射

毛病:

1、SQL语句编写工作量大,熟练度要高

2、数据库移植性比拟差,如果须要切换数据库的话,SQL语句会有很大的差别

3、第一个Mybatis我的项目

1、创立一般的maven我的项目

2、导入相干的依赖

pom.xml

<?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0"         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">    <modelVersion>4.0.0</modelVersion>    <groupId>com.mashibing</groupId>    <artifactId>mybatis_helloworld</artifactId>    <version>1.0-SNAPSHOT</version>    <dependencies>        <dependency>            <groupId>org.mybatis</groupId>            <artifactId>mybatis</artifactId>            <version>3.5.4</version>        </dependency>        <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->        <dependency>            <groupId>mysql</groupId>            <artifactId>mysql-connector-java</artifactId>            <version>8.0.16</version>        </dependency>        <!-- https://mvnrepository.com/artifact/log4j/log4j -->        <dependency>            <groupId>log4j</groupId>            <artifactId>log4j</artifactId>            <version>1.2.17</version>        </dependency>    </dependencies></project>

3、创立对应的数据表

CREATE TABLE `demo`.`Untitled`  (  `empno` int(4) NOT NULL,  `ename` varchar(10) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,  `job` varchar(9) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,  `mgr` int(4) NULL DEFAULT NULL,  `hiredate` date NULL DEFAULT NULL,  `sal` int(11) NULL DEFAULT NULL,  `comm` int(11) NULL DEFAULT NULL,  `deptno` int(11) NULL DEFAULT NULL) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
INSERT INTO `emp` VALUES (7369, 'SMITH', 'CLERK', 7902, '1980-12-17', 800, NULL, 20);INSERT INTO `emp` VALUES (7499, 'ALLEN', 'SALESMAN', 7698, '1981-02-20', 1600, 300, 30);INSERT INTO `emp` VALUES (7521, 'WARD', 'SALESMAN', 7698, '1981-02-22', 1250, 500, 30);INSERT INTO `emp` VALUES (7566, 'JONES', 'MANAGER', 7839, '1981-04-02', 2975, NULL, 20);INSERT INTO `emp` VALUES (7654, 'MARTIN', 'SALESMAN', 7698, '1981-09-28', 1250, 1400, 30);INSERT INTO `emp` VALUES (7698, 'BLAKE', 'MANAGER', 7839, '1981-05-01', 2850, NULL, 30);INSERT INTO `emp` VALUES (7782, 'CLARK', 'MANAGER', 7839, '1981-06-09', 2450, NULL, 10);INSERT INTO `emp` VALUES (7788, 'SCOTT', 'ANALYST', 7566, '1987-04-19', 3000, NULL, 20);INSERT INTO `emp` VALUES (7839, 'KING', 'PRESIDENT', NULL, '1981-11-17', 5000, NULL, 10);INSERT INTO `emp` VALUES (7844, 'TURNER', 'SALESMAN', 7698, '1981-09-08', 1500, 0, 30);INSERT INTO `emp` VALUES (7876, 'ADAMS', 'CLERK', 7788, '1987-05-23', 1100, NULL, 20);INSERT INTO `emp` VALUES (7900, 'JAMES', 'CLERK', 7698, '1981-12-03', 950, NULL, 30);INSERT INTO `emp` VALUES (7902, 'FORD', 'ANALYST', 7566, '1981-12-03', 3000, NULL, 20);INSERT INTO `emp` VALUES (7934, 'MILLER', 'CLERK', 7782, '1982-01-23', 1300, NULL, 10);

4、创立与表对应的实体类对象

emp.java

package com.mashibing.bean;import java.util.Date;public class Emp {    private Integer empno;    private String ename;    private String job;    private Integer mgr;    private Date hiredate;    private Double sal;    private Double common;    private Integer deptno;    public Emp() {    }    public Emp(Integer empno, String ename, String job, Integer mgr, Date hiredate, Double sal, Double common, Integer deptno) {        this.empno = empno;        this.ename = ename;        this.job = job;        this.mgr = mgr;        this.hiredate = hiredate;        this.sal = sal;        this.common = common;        this.deptno = deptno;    }    public Integer getEmpno() {        return empno;    }    public void setEmpno(Integer empno) {        this.empno = empno;    }    public String getEname() {        return ename;    }    public void setEname(String ename) {        this.ename = ename;    }    public String getJob() {        return job;    }    public void setJob(String job) {        this.job = job;    }    public Integer getMgr() {        return mgr;    }    public void setMgr(Integer mgr) {        this.mgr = mgr;    }    public Date getHiredate() {        return hiredate;    }    public void setHiredate(Date hiredate) {        this.hiredate = hiredate;    }    public Double getSal() {        return sal;    }    public void setSal(Double sal) {        this.sal = sal;    }    public Double getCommon() {        return common;    }    public void setCommon(Double common) {        this.common = common;    }    public Integer getDeptno() {        return deptno;    }    public void setDeptno(Integer deptno) {        this.deptno = deptno;    }    @Override    public String toString() {        return "Emp{" +                "empno=" + empno +                ", ename='" + ename + '\'' +                ", job='" + job + '\'' +                ", mgr=" + mgr +                ", hiredate=" + hiredate +                ", sal=" + sal +                ", common=" + common +                ", deptno=" + deptno +                '}';    }}

5、创立对应的dao类

EmpDao.java

package com.mashibing.dao;import com.mashibing.bean.Emp;public interface EmpDao {    public Emp findEmpByEmpno(Integer empno);    }

6、编写配置文件

log4j.properties

# 全局日志配置log4j.rootLogger=info, stdout# MyBatis 日志配置log4j.logger.com.mashibing=TRACE# 控制台输入log4j.appender.stdout=org.apache.log4j.ConsoleAppenderlog4j.appender.stdout.layout=org.apache.log4j.PatternLayoutlog4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n

mybatis-config.xml

<?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>    <environments default="development">        <environment id="development">            <transactionManager type="JDBC"/>            <!--配置数据库连贯-->            <dataSource type="POOLED">                <property name="driver" value="com.mysql.cj.jdbc.Driver"/>                <property name="url" value="jdbc:mysql://localhost:3306/demo?serverTimezone=UTC"/>                <property name="username" value="root"/>                <property name="password" value="123456"/>            </dataSource>        </environment>    </environments>    <!--引入每一个接口对应点xml文件-->    <mappers>        <mapper resource="EmpDao.xml"/>    </mappers></configuration>

EmpDao.xml

<?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"><!--namespace:编写接口的全类名,就是通知要实现该配置文件是哪个接口的具体实现--><mapper namespace="com.mashibing.dao.EmpDao">    <!--    select:示意这个操作是一个查问操作    id示意的是要匹配的办法的名称    resultType:示意返回值的类型,查问操作必须要蕴含返回值的类型    #{属性名}:示意要传递的参数的名称    -->    <select id="findEmpByEmpno" resultType="com.mashibing.bean.Emp">        select * from emp where empno = #{empno}  </select></mapper>

7、编写测试类

MyTest.java

package com.mashibing.test;import com.mashibing.bean.Emp;import com.mashibing.dao.EmpDao;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.Test;import java.io.IOException;import java.io.InputStream;public class MyTest {    @Test    public void test01() {        // 依据全局配置文件创立出SqlSessionFactory        // SqlSessionFactory:负责创立SqlSession对象的工厂        // SqlSession:示意跟数据库倡议的一次会话        String resource = "mybatis-config.xml";        InputStream inputStream = null;        try {            inputStream = Resources.getResourceAsStream(resource);        } catch (IOException e) {            e.printStackTrace();        }        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);        // 获取数据库的会话        SqlSession sqlSession = sqlSessionFactory.openSession();        Emp empByEmpno = null;        try {            // 获取要调用的接口类            EmpDao mapper = sqlSession.getMapper(EmpDao.class);            // 调用办法开始执行            empByEmpno = mapper.findEmpByEmpno(7369);        } catch (Exception e) {            e.printStackTrace();        } finally {            sqlSession.close();        }        System.out.println(empByEmpno);    }}

4、增删改查的基本操作

EmpDao.java

package com.mashibing.dao;import com.mashibing.bean.Emp;public interface EmpDao {    public Emp findEmpByEmpno(Integer empno);    public int updateEmp(Emp emp);    public int deleteEmp(Integer empno);    public int insertEmp(Emp emp);}

EmpDao.xml

<?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"><!--namespace:编写接口的全类名,就是通知要实现该配置文件是哪个接口的具体实现--><mapper namespace="com.mashibing.dao.EmpDao">    <!--    select:示意这个操作是一个查问操作    id示意的是要匹配的办法的名称    resultType:示意返回值的类型,查问操作必须要蕴含返回值的类型    #{属性名}:示意要传递的参数的名称    -->    <select id="findEmpByEmpno" resultType="com.mashibing.bean.Emp">        select * from emp where empno = #{empno}    </select>    <!--增删改查操作不须要返回值,增删改返回的是影响的行数,mybatis会主动做判断-->    <insert id="insertEmp">        insert into emp(empno,ename) values(#{empno},#{ename})    </insert>    <update id="updateEmp">        update emp set ename=#{ename} where empno = #{empno}    </update>    <delete id="deleteEmp">        delete from emp where empno = #{empno}    </delete></mapper>

MyTest.java

package com.mashibing.test;import com.mashibing.bean.Emp;import com.mashibing.dao.EmpDao;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.Before;import org.junit.Test;import java.io.IOException;import java.io.InputStream;public class MyTest {    SqlSessionFactory sqlSessionFactory = null;    @Before    public void init(){        // 依据全局配置文件创立出SqlSessionFactory        // SqlSessionFactory:负责创立SqlSession对象的工厂        // SqlSession:示意跟数据库倡议的一次会话        String resource = "mybatis-config.xml";        InputStream inputStream = null;        try {            inputStream = Resources.getResourceAsStream(resource);            sqlSessionFactory= new SqlSessionFactoryBuilder().build(inputStream);        } catch (IOException e) {            e.printStackTrace();        }    }    @Test    public void test01() {        // 获取数据库的会话        SqlSession sqlSession = sqlSessionFactory.openSession();        Emp empByEmpno = null;        try {            // 获取要调用的接口类            EmpDao mapper = sqlSession.getMapper(EmpDao.class);            // 调用办法开始执行            empByEmpno = mapper.findEmpByEmpno(7369);        } catch (Exception e) {            e.printStackTrace();        } finally {            sqlSession.close();        }        System.out.println(empByEmpno);    }    @Test    public void test02(){        SqlSession sqlSession = sqlSessionFactory.openSession();        EmpDao mapper = sqlSession.getMapper(EmpDao.class);        int zhangsan = mapper.insertEmp(new Emp(1111, "zhangsan"));        System.out.println(zhangsan);        sqlSession.commit();        sqlSession.close();    }    @Test    public void test03(){        SqlSession sqlSession = sqlSessionFactory.openSession();        EmpDao mapper = sqlSession.getMapper(EmpDao.class);        int zhangsan = mapper.updateEmp(new Emp(1111, "lisi"));        System.out.println(zhangsan);        sqlSession.commit();        sqlSession.close();    }    @Test    public void test04(){        SqlSession sqlSession = sqlSessionFactory.openSession();        EmpDao mapper = sqlSession.getMapper(EmpDao.class);        int zhangsan = mapper.deleteEmp(1111);        System.out.println(zhangsan);        sqlSession.commit();        sqlSession.close();    }}

5、配置文件详解

在mybatis的我的项目中,相干的配置在mybatis-config.xml,这个配置文件是mybatis的全局配置文件,用来进行相干的全局配置,在任何操作下都失效的配置。

mybatis-config.xml

<?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>    <!--引入内部配置文件,相似于Spring中的property-placeholder    resource:从类门路引入    url:从磁盘门路或者网络门路引入    -->    <properties resource="db.properties"></properties>    <!--用来管制mybatis运行时的行为,是mybatis中的重要配置-->    <settings>        <!--设置列名映射的时候是否是驼峰标识-->        <setting name="mapUnderscoreToCamelCase" value="true"/>    </settings>    <!--typeAliases示意为咱们援用的实体类起别名,默认状况下咱们须要写类的齐全限定名    如果在此处做了配置,那么能够间接写类的名称,在type中配置上类的齐全限定名,在应用的时候能够疏忽大小写    还能够通过alias属性来示意类的别名    -->    <typeAliases><!--        <typeAlias type="com.mashibing.bean.Emp" alias="Emp"></typeAlias>-->        <!--如果须要援用多个类,那么给每一个类起别名必定会很麻烦,因而能够指定对应的包名,那么默认用的是类名-->        <package name="com.mashibing.bean"/>    </typeAliases>    <!--    在理论的开发过程中,咱们可能分为开发环境,生产环境,测试环境等等,每个环境的配置能够是不一样的    environment就用来示意不同环境的细节配置,每一个环境中都须要一个事务管理器以及数据源的配置    咱们在后续的我的项目开发中简直都是应用spring中配置的数据源和事务管理器来配置,此处不须要钻研    -->    <!--default:用来抉择须要的环境-->    <environments default="development">        <!--id:示意不同环境的名称-->        <environment id="development">            <transactionManager type="JDBC"/>            <!--配置数据库连贯-->            <dataSource type="POOLED">                <!--应用${}来引入内部变量-->                <property name="driver" value="${driverClassname}"/>                <property name="url" value="${url}"/>                <property name="username" value="${username}"/>                <property name="password" value="${password}"/>            </dataSource>        </environment>    </environments>    <!--    在不同的数据库中,可能sql语句的写法是不一样的,为了加强移植性,能够提供不同数据库的操作实现    在编写不同的sql语句的时候,能够指定databaseId属性来标识以后sql语句能够运行在哪个数据库中    -->    <databaseIdProvider type="DB_VENDOR">        <property name="MySQL" value="mysql"/>        <property name="SQL Server" value="sqlserver"/>        <property name="Oracle" value="orcl"/>    </databaseIdProvider>        <!--将sql的映射文件实用mappers进行映射-->    <mappers>        <!--        指定具体的不同的配置文件        class:间接引入接口的全类名,能够将xml文件放在dao的同级目录下,并且设置雷同的文件名称,同时能够应用注解的形式来进行相干的配置        url:能够从磁盘或者网络门路查找sql映射文件        resource:在类门路下寻找sql映射文件        --><!--        <mapper resource="EmpDao.xml"/>        <mapper resource="UserDao.xml"/>        <mapper class="com.mashibing.dao.EmpDaoAnnotation"></mapper>-->        <!--        当蕴含多个配置文件或者配置类的时候,能够应用批量注册的性能,也就是引入对应的包,而不是具体的配置文件或者类        然而须要留神的是,        1、如果应用的配置文件的模式,必须要将配置文件跟dao类放在一起,这样能力找到对应的配置文件.            如果是maven的我的项目的话,还须要增加以下配置,起因是maven在编译的文件的时候只会编译java文件                <build>                    <resources>                        <resource>                            <directory>src/main/java</directory>                        <includes>                            <include>**/*.xml</include>                        </includes>                    </resource>                    </resources>                </build>        2、将配置文件在resources资源门路下创立跟dao雷同的包名        -->        <package name="com.mashibing.dao"/>    </mappers></configuration>

EmpDaoAnnotation.java

package com.mashibing.dao;import com.mashibing.bean.Emp;import org.apache.ibatis.annotations.Delete;import org.apache.ibatis.annotations.Insert;import org.apache.ibatis.annotations.Select;import org.apache.ibatis.annotations.Update;public interface EmpDaoAnnotation {    @Select("select * from emp where empno = #{empno}")    public Emp findEmpByEmpno(Integer empno);    @Update("update emp set ename=#{ename} where empno = #{empno}")    public int updateEmp(Emp emp);    @Delete("delete from emp where empno = #{empno}")    public int deleteEmp(Integer empno);    @Insert("insert into emp(empno,ename) values(#{empno},#{ename})")    public int insertEmp(Emp emp);}