JDBC(Java Data Base Connection,java數據庫鏈接)是一種用於執行SQL語句的Java API,能夠爲多種關係數據庫提供統一訪問,它由一組用Java語言編寫的類和接口組成.JDBC提供了一種基準,據此能夠構建更高級的工具和接口,使數據庫開發人員可以編寫數據庫應用程序java
缺點:編輯期:代碼量大、繁瑣異常處理、不支持數據庫跨平臺
mysql
DBUtils是Java編程中的數據庫操做實用工具,小巧簡單實用。spring
DBUtils封裝了對JDBC的操做,簡化了JDBC操做,能夠少寫代碼。sql
DBUtils三個核心功能介紹數據庫
一、QueryRunner中提供對sql語句操做的APIapache
二、ResultSetHandler接口,用於定義select操做後,怎樣封裝結果集編程
三、DBUtils類,它就是一個工具類,定義了關閉資源與事務處理的方法緩存
Hibernate 是由 Gavin King 於 2001 年建立的開放源代碼的對象關係框架。它強大且高效的構建具備關係對象持久性和查詢服務的 Java 應用程序。服務器
Hibernate 將 Java 類映射到數據庫表中,從 Java 數據類型中映射到 SQL 數據類型中,並把開發人員從 95% 的公共數據持續性編程工做中解放出來。網絡
Hibernate 是傳統 Java 對象和數據庫服務器之間的橋樑,用來處理基於 O/R 映射機
Hibernate 優點
提供簡單的數據詢問。
Hibernate劣勢
Hibernate批量數據操做須要大量的內存空間並且執行過程當中須要的對象太多
JdbcTemplate針對數據查詢提供了多個重載的模板方法,你能夠根據須要選用不一樣的模板方法.若是你的查詢很簡單,僅僅是傳入相應SQL或者相關參數,而後取得一個單一的結果,那麼你能夠選擇以下一組便利的模板方法。
優勢:運行期:高效、內嵌Spring框架中、支持基於AOP的聲明式事務
缺點:必須於Spring框架結合在一塊兒使用、不支持數據庫跨平臺、默認沒有緩存
MyBatis 是一款優秀的持久層框架,它支持自定義 SQL、存儲過程以及高級映射。MyBatis 免除了幾乎全部的 JDBC 代碼以及設置參數和獲取結果集的工做。MyBatis 能夠經過簡單的 XML 或註解來配置和映射原始類型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 對象)爲數據庫中的記錄。
優勢:
一、與JDBC相比,減小了50%的代碼量
二、 最簡單的持久化框架,簡單易學
三、SQL代碼從程序代碼中完全分離出來,能夠重用
四、提供XML標籤,支持編寫動態SQL
五、提供映射標籤,支持對象與數據庫的ORM字段關係映射
缺點:
一、SQL語句編寫工做量大,熟練度要高
二、數據庫移植性比較差,若是須要切換數據庫的話,SQL語句會有很大的差別
一、建立普通的maven項目
二、導入相關的依賴
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>
三、建立對應的數據表
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);
四、建立與表對應的實體類對象
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 + '}'; } }
五、建立對應的dao類
EmpDao.java
package com.mashibing.dao; import com.mashibing.bean.Emp; public interface EmpDao { public Emp findEmpByEmpno(Integer empno); }
六、編寫配置文件
log4j.properties
# 全局日誌配置 log4j.rootLogger=info, stdout # MyBatis 日誌配置 log4j.logger.com.mashibing=TRACE # 控制檯輸出 log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.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>
七、編寫測試類
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); } }
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(); } }
在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>--> <!-- 當包含多個配置文件或者配置類的時候,可使用批量註冊的功能,也就是引入對應的包,而不是具體的配置文件或者類 可是須要注意的是, 一、若是使用的配置文件的形式,必需要將配置文件跟dao類放在一塊兒,這樣才能找到對應的配置文件. 若是是maven的項目的話,還須要添加如下配置,緣由是maven在編譯的文件的時候只會編譯java文件 <build> <resources> <resource> <directory>src/main/java</directory> <includes> <include>**/*.xml</include> </includes> </resource> </resources> </build> 二、將配置文件在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); }