mybatis教程--实现增删改查的入门教程
1?開發(fā)環(huán)境
jdk1.7.0_72
eclipse:eclipse-3.7-indigo
mysql:mysql5.1
1.1?創(chuàng)建數(shù)據(jù)庫
?
先導(dǎo)入sql_table.sql,再導(dǎo)入sql_data.sql(記錄系統(tǒng)的初始化數(shù)據(jù))
通常需要提供初始化數(shù)據(jù)的數(shù)據(jù)庫腳本。
?
2?jdbc編程中問題
企業(yè)開發(fā)中,根據(jù)項(xiàng)目大小、特點(diǎn)進(jìn)行技術(shù)選型 ,jdbc操作數(shù)據(jù)庫時(shí)效率是很高的,jdbc也是技術(shù)選型的參考。
2.1? jdbc程序
需要數(shù)據(jù)庫的驅(qū)動(dòng)包:
?
上邊是mysql的驅(qū)動(dòng),下邊是oracle的驅(qū)動(dòng)。
2.2?jdbc問題總結(jié)
1、數(shù)據(jù)庫連接頻繁的創(chuàng)建和關(guān)閉,缺點(diǎn)浪費(fèi)數(shù)據(jù)庫的資源,影響操作效率
設(shè)想:使用數(shù)據(jù)庫連接池
2、sql語句是硬編碼,如果需求變更需要修改sql,就需要修改java代碼,需要重新編譯,系統(tǒng)不易維護(hù)。
設(shè)想:將sql語句 統(tǒng)一配置在文件中,修改sql不需要修改java代碼。
3、通過preparedStatement向占位符設(shè)置參數(shù),存在硬編碼( 參數(shù)位置,參數(shù))問題。系統(tǒng)不易維護(hù)。
設(shè)想:將sql中的占位符及對應(yīng)的參數(shù)類型配置在配置文件中,能夠自動(dòng)輸入 映射。
4、遍歷查詢結(jié)果集存在硬編碼(列名)。
設(shè)想:自動(dòng)進(jìn)行sql查詢結(jié)果向java對象的映射(輸出映射)。
3?mybatis架構(gòu)
3.1?mybatis介紹
MyBatis 本是apache的一個(gè)開源項(xiàng)目iBatis, 2010年這個(gè)項(xiàng)目由apache software foundation遷移到了google code,并且改名為MyBatis,實(shí)質(zhì)上Mybatis對ibatis進(jìn)行一些改進(jìn)。 目前mybatis在github上托管。git(分布式版本控制,當(dāng)前比較流程)
?
MyBatis是一個(gè)優(yōu)秀的持久層框架,它對jdbc的操作數(shù)據(jù)庫的過程進(jìn)行封裝,使開發(fā)者只需要關(guān)注SQL 本身,而不需要花費(fèi)精力去處理例如注冊驅(qū)動(dòng)、創(chuàng)建connection、創(chuàng)建statement、手動(dòng)設(shè)置參數(shù)、結(jié)果集檢索等jdbc繁雜的過程代碼。
Mybatis通過xml或注解的方式將要執(zhí)行的各種statement(statement、preparedStatemnt、CallableStatement)配置起來,并通過java對象和statement中的sql進(jìn)行映射生成最終執(zhí)行的sql語句,最后由mybatis框架執(zhí)行sql并將結(jié)果映射成java對象并返回。
3.2?mybatis架構(gòu)
?
4?mybatis入門程序
4.1?需求
實(shí)現(xiàn)用戶查詢:
根據(jù)用戶id(主鍵)查詢用戶信息(單條記錄)
根據(jù)用戶名稱模糊查詢用戶信息(多條記錄)
用戶添加
用戶刪除
用戶修改
4.2?導(dǎo)入jar包
從mybatis管網(wǎng)下載(地址:https://github.com/mybatis/mybatis-3/releases)
?
mybatis-3.2.7.pdf---操作手冊
mybatis-3.2.7.jar--核心 jar包
依賴的jar包
?
4.3?工程結(jié)構(gòu)
4.4?log4j.properties(公用文件)
# Global logging configuration,建議開發(fā)環(huán)境中要用debuglog4j.rootLogger=DEBUG, stdout# Console output...log4j.appender.stdout=org.apache.log4j.ConsoleAppenderlog4j.appender.stdout.layout=org.apache.log4j.PatternLayoutlog4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n4.5?SqlMapConfig.xml(公用文件)
通過SqlMapConfig.xml加載mybatis運(yùn)行環(huán)境。
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration><!-- 屬性定義加載一個(gè)properties文件在 properties標(biāo)簽 中配置屬性值--><properties resource="db.properties"><!-- <property name="" value=""/> --></properties><!-- 定義 別名 --><typeAliases><!--單個(gè)別名的定義alias:別名,type:別名映射的類型 --><!-- <typeAlias type="com.sihai.mybatis.po.User" alias="user"/> --><!-- 批量別名定義指定包路徑,自動(dòng)掃描包下邊的pojo,定義別名,別名默認(rèn)為類名(首字母小寫或大寫)--><package name="com.sihai.mybatis.po"/></typeAliases><!-- 和spring整合后 environments配置將廢除--><environments default="development"><environment id="development"><!-- 使用jdbc事務(wù)管理--><transactionManager type="JDBC" /><!-- 數(shù)據(jù)庫連接池--><dataSource type="POOLED"><property name="driver" value="${jdbc.driver}"/><property name="url" value="${jdbc.url}"/><property name="username" value="${jdbc.username}"/><property name="password" value="${jdbc.password}"/></dataSource></environment></environments><!--加載mapper映射如果將和spring整合后,可以使用整合包中提供的mapper掃描器,此處的mappers不用配置了。--><mappers><!-- 通過resource引用mapper的映射文件 --><mapper resource="sqlmap/User.xml" /><!-- <mapper resource="mapper/UserMapper.xml" /> --><!-- 通過class引用mapper接口 class:配置mapper接口全限定名要求:需要mapper.xml和mapper.java同名并且在一個(gè)目錄 中--><!-- <mapper class="com.sihai.mybatis.mapper.UserMapper"/> --><!-- 批量mapper配置 通過package進(jìn)行自動(dòng)掃描包下邊的mapper接口,要求:需要mapper.xml和mapper.java同名并且在一個(gè)目錄 中--><package name="com.sihai.mybatis.mapper"/></mappers></configuration>4.6? 實(shí)現(xiàn)用戶增刪改查
4.6.1?pojo(User.java)
package com.sihait.mybatis.po;import java.util.Date;/*** @author sihai*/ public class User {private int id;private String username;// 用戶姓名private String sex;// 性別private Date birthday;// 生日private String address;// 地址public int getId() {return id;}public void setId(int id) {this.id = id;}public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}public String getSex() {return sex;}public void setSex(String sex) {this.sex = sex;}public Date getBirthday() {return birthday;}public void setBirthday(Date birthday) {this.birthday = birthday;}public String getAddress() {return address;}public void setAddress(String address) {this.address = address;}@Overridepublic String toString() {return "User [id=" + id + ", username=" + username + ", sex=" + sex+ ", birthday=" + birthday + ", address=" + address + "]";}}4.6.2?User.xml(重點(diǎn))
建議命名規(guī)則:表名+mapper.xml
早期ibatis命名規(guī)則:表名.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命名空間,為了對sql語句進(jìn)行隔離,方便管理 ,mapper開發(fā)dao方式,使用namespace有特殊作用 mapper代理開發(fā)時(shí)將namespace指定為mapper接口的全限定名--> <mapper namespace="test"> <!-- 在mapper.xml文件中配置很多的sql語句,執(zhí)行每個(gè)sql語句時(shí),封裝為MappedStatement對象 mapper.xml以statement為單位管理sql語句--><!-- 根據(jù)id查詢用戶信息 --><!-- id:唯一標(biāo)識 一個(gè)statement#{}:表示 一個(gè)占位符,如果#{}中傳入簡單類型的參數(shù),#{}中的名稱隨意parameterType:輸入 參數(shù)的類型,通過#{}接收parameterType輸入 的參數(shù)resultType:輸出結(jié)果 類型,不管返回是多條還是單條,指定單條記錄映射的pojo類型--><select id="findUserById" parameterType="int" resultType="com.sihai.mybatis.po.User">SELECT * FROM USER WHERE id= #{id}</select><!-- 根據(jù)用戶名稱查詢用戶信息,可能返回多條${}:表示sql的拼接,通過${}接收參數(shù),將參數(shù)的內(nèi)容不加任何修飾拼接在sql中。--><select id="findUserByName" parameterType="java.lang.String" resultType="com.sihai.mybatis.po.User">select * from user where username like '%${value}%'</select><!-- 添加用戶parameterType:輸入 參數(shù)的類型,User對象 包括 username,birthday,sex,address#{}接收pojo數(shù)據(jù),可以使用OGNL解析出pojo的屬性值#{username}表示從parameterType中獲取pojo的屬性值selectKey:用于進(jìn)行主鍵返回,定義了獲取主鍵值的sqlorder:設(shè)置selectKey中sql執(zhí)行的順序,相對于insert語句來說keyProperty:將主鍵值設(shè)置到哪個(gè)屬性resultType:select LAST_INSERT_ID()的結(jié)果 類型--><insert id="insertUser" parameterType="com.sihai.mybatis.po.User"><selectKey keyProperty="id" order="AFTER" resultType="int">select LAST_INSERT_ID()</selectKey>INSERT INTO USER(username,birthday,sex,address) VALUES(#{username},#{birthday},#{sex},#{address})</insert><!-- mysql的uuid生成主鍵 --><!-- <insert id="insertUser" parameterType="com.sihai.mybatis.po.User"><selectKey keyProperty="id" order="BEFORE" resultType="string">select uuid()</selectKey>INSERT INTO USER(id,username,birthday,sex,address) VALUES(#{id},#{username},#{birthday},#{sex},#{address})</insert> --><!-- oracle在執(zhí)行insert之前執(zhí)行select 序列.nextval() from dual取出序列最大值,將值設(shè)置到user對象 的id屬性--><!-- <insert id="insertUser" parameterType="com.sihai.mybatis.po.User"><selectKey keyProperty="id" order="BEFORE" resultType="int">select 序列.nextval() from dual</selectKey>INSERT INTO USER(id,username,birthday,sex,address) VALUES(#{id},#{username},#{birthday},#{sex},#{address})</insert> --><!-- 用戶刪除? --><delete id="deleteUser" parameterType="int">delete from user where id=#{id}</delete><!-- 用戶更新 要求:傳入的user對象中包括 id屬性值--><update id="updateUser" parameterType="com.sihai.mybatis.po.User">update user set username=#{username},birthday=#{birthday},sex=#{sex},address=#{address} where id=#{id}</update></mapper>4.6.3 測試
創(chuàng)建SqlSessionFactory:
package com.sihai.mybatis.first;import java.io.IOException; import java.io.InputStream; import java.util.Date; import java.util.List;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 com.sihai.mybatis.po.User;/*** @author sihai*/ public class MybatisFirst {// 會話工廠private SqlSessionFactory sqlSessionFactory;// 創(chuàng)建工廠@Beforepublic void init() throws IOException {// 配置文件(SqlMapConfig.xml)String resource = "SqlMapConfig.xml";// 加載配置文件到輸入 流InputStream inputStream = Resources.getResourceAsStream(resource);// 創(chuàng)建會話工廠sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);}// 測試根據(jù)id查詢用戶(得到單條記錄)@Testpublic void testFindUserById() {// 通過sqlSessionFactory創(chuàng)建sqlSessionSqlSession sqlSession = sqlSessionFactory.openSession();// 通過sqlSession操作數(shù)據(jù)庫// 第一個(gè)參數(shù):statement的位置,等于namespace+statement的id// 第二個(gè)參數(shù):傳入的參數(shù)User user = null;try {user = sqlSession.selectOne("test.findUserById", 2);} catch (Exception e) {e.printStackTrace();} finally {// 關(guān)閉sqlSessionsqlSession.close();}System.out.println(user);}// 測試根據(jù)id查詢用戶(得到單條記錄)@Testpublic void testFindUserByName() {// 通過sqlSessionFactory創(chuàng)建sqlSessionSqlSession sqlSession = sqlSessionFactory.openSession();// 通過sqlSession操作數(shù)據(jù)庫// 第一個(gè)參數(shù):statement的位置,等于namespace+statement的id// 第二個(gè)參數(shù):傳入的參數(shù)List<User> list = null;try {list = sqlSession.selectList("test.findUserByName", "小明");} catch (Exception e) {e.printStackTrace();} finally {// 關(guān)閉sqlSessionsqlSession.close();}System.out.println(list.get(0).getUsername());}// 測試根據(jù)id查詢用戶(得到單條記錄)@Testpublic void testInsertUser() {// 通過sqlSessionFactory創(chuàng)建sqlSessionSqlSession sqlSession = sqlSessionFactory.openSession();// 通過sqlSession操作數(shù)據(jù)庫// 創(chuàng)建插入數(shù)據(jù)對象User user = new User();user.setUsername("浪子燕青");user.setAddress("河南鄭州");user.setBirthday(new Date());user.setSex("1");try {sqlSession.insert("test.insertUser", user);// 需要提交事務(wù)sqlSession.commit();} catch (Exception e) {e.printStackTrace();} finally {// 關(guān)閉sqlSessionsqlSession.close();}System.out.println("用戶的id=" + user.getId());}// 測試根據(jù)id刪除用戶(得到單條記錄)@Testpublic void testDeleteUser() {// 通過sqlSessionFactory創(chuàng)建sqlSessionSqlSession sqlSession = sqlSessionFactory.openSession();// 通過sqlSession操作數(shù)據(jù)庫try {sqlSession.delete("test.deleteUser", 35);// 需要提交事務(wù)sqlSession.commit();} catch (Exception e) {e.printStackTrace();} finally {// 關(guān)閉sqlSessionsqlSession.close();}}// 測試根據(jù)id更新用戶(得到單條記錄)@Testpublic void testUpdateUser() {// 通過sqlSessionFactory創(chuàng)建sqlSessionSqlSession sqlSession = sqlSessionFactory.openSession();// 通過sqlSession操作數(shù)據(jù)庫// 創(chuàng)建更新數(shù)據(jù)對象,要求必須包括 idUser user = new User();user.setId(35);user.setUsername("燕青");user.setAddress("河南鄭州"); // user.setBirthday(new Date());user.setSex("1");try {sqlSession.update("test.updateUser", user);// 需要提交事務(wù)sqlSession.commit();} catch (Exception e) {e.printStackTrace();} finally {// 關(guān)閉sqlSessionsqlSession.close();}System.out.println("用戶的id=" + user.getId());}}5 Mybatis解決jdbc編程的問題
1、?數(shù)據(jù)庫鏈接創(chuàng)建、釋放頻繁造成系統(tǒng)資源浪費(fèi)從而影響系統(tǒng)性能,如果使用數(shù)據(jù)庫鏈接池可解決此問題。
解決:在SqlMapConfig.xml中配置數(shù)據(jù)鏈接池,使用連接池管理數(shù)據(jù)庫鏈接。
2、?Sql語句寫在代碼中造成代碼不易維護(hù),實(shí)際應(yīng)用sql變化的可能較大,sql變動(dòng)需要改變java代碼。
解決:將Sql語句配置在XXXXmapper.xml文件中與java代碼分離。
3、?向sql語句傳參數(shù)麻煩,因?yàn)閟ql語句的where條件不一定,可能多也可能少,占位符需要和參數(shù)一一對應(yīng)。
解決:Mybatis自動(dòng)將java對象映射至sql語句,通過statement中的parameterType定義輸入?yún)?shù)的類型。
4、?對結(jié)果集解析麻煩,sql變化導(dǎo)致解析代碼變化,且解析前需要遍歷,如果能將數(shù)據(jù)庫記錄封裝成pojo對象解析比較方便。
解決:Mybatis自動(dòng)將sql執(zhí)行結(jié)果映射至java對象,通過statement中的resultType定義輸出結(jié)果的類型。
6 mybatis與hibernate重要區(qū)別
企業(yè)開發(fā)進(jìn)行技術(shù)選型 ,考慮mybatis與hibernate適用場景。
mybatis:入門簡單,程序容易上手開發(fā),節(jié)省開發(fā)成本 。mybatis需要程序員自己編寫sql語句,是一個(gè)不完全 的ORM框架,對sql修改和優(yōu)化非常容易實(shí)現(xiàn) 。
mybatis適合開發(fā)需求變更頻繁的系統(tǒng),比如:互聯(lián)網(wǎng)項(xiàng)目。
hibernate:入門門檻高,如果用hibernate寫出高性能的程序不容易實(shí)現(xiàn)。hibernate不用寫sql語句,是一個(gè)ORM框架。
hibernate適合需求固定,對象數(shù)據(jù)模型穩(wěn)定,中小型項(xiàng)目,比如:企業(yè)OA系統(tǒng)。
總之,企業(yè)在技術(shù)選型時(shí)根據(jù)項(xiàng)目實(shí)際情況,以降低成本和提高系統(tǒng) 可維護(hù)性為出發(fā)點(diǎn)進(jìn)行技術(shù)選型。
7 總結(jié)
7.1?#{}
表示一個(gè)占位符,向占位符輸入?yún)?shù),mybatis自動(dòng)進(jìn)行java類型和jdbc類型的轉(zhuǎn)換。
程序員不需要考慮參數(shù)的類型,比如:傳入字符串,mybatis最終拼接好的sql就是參數(shù)兩邊加單引號。
#{}接收pojo數(shù)據(jù),可以使用OGNL解析出pojo的屬性值
7.2?${}
表示sql的拼接,通過${}接收參數(shù),將參數(shù)的內(nèi)容不加任何修飾拼接在sql中。
${}也可以接收pojo數(shù)據(jù),可以使用OGNL解析出pojo的屬性值
缺點(diǎn):不能防止sql注入。
總結(jié)
以上是生活随笔為你收集整理的mybatis教程--实现增删改查的入门教程的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【struts2+spring+hibe
- 下一篇: mybatis教程--原始方式和mapp