文檔版本
|
開發(fā)工具
|
測試平臺
|
工程名字
|
日期
|
作者
|
備注
|
V1.0
|
|
|
|
2016.06.25
|
lutianfei
|
none
|
原生態(tài)jdbc程序中問題總結(jié)
-
1、數(shù)據(jù)庫連接,使用時就創(chuàng)建,不使用立即釋放,對數(shù)據(jù)庫進行頻繁連接開啟和關(guān)閉,造成數(shù)據(jù)庫資源浪費,影響 數(shù)據(jù)庫性能。
-
2、將sql語句硬編碼到j(luò)ava代碼中,如果sql 語句修改,需要重新編譯java代碼,不利于系統(tǒng)保護。
-
假想:將sql語句配置在xml配置文件中,即便sql變化,不需要對java代碼進行重新編譯。
-
3、向preparedStatement中設(shè)置參數(shù),對占位符號位置和設(shè)置參數(shù)值,硬編碼在java代碼中,不利于系統(tǒng)保護。
-
假想:將sql語句及占位符號和參數(shù)全部配置在xml中。
-
4、從resutSet中遍歷結(jié)果集數(shù)據(jù)時,存在硬編碼,將獲得表的字段進行硬編碼,不利于系統(tǒng)保護。
-
假想:將查詢的結(jié)果集,自動映照成java對象。
Mybatis框架
-
MyBatis 本是apache的1個開源項目iBatis, 2010年這個項目由apache software foundation 遷移到了google code,并且改名為MyBatis,實質(zhì)上Mybatis對ibatis進行1些改進。
-
MyBatis是1個優(yōu)秀的持久層框架,它對jdbc的操作數(shù)據(jù)庫的進程進行封裝,使開發(fā)者只需要關(guān)注 SQL 本身,而不需要花費精力去處理例如注冊驅(qū)動、創(chuàng)建connection、創(chuàng)建statement、手動設(shè)置參數(shù)、結(jié)果集檢索等jdbc復(fù)雜的進程代碼。
-
Mybatis通過xml或注解的方式將要履行的各種statement(statement、preparedStatemnt、CallableStatement)配置起來,并通過java對象和statement中的sql進行映照生成終究履行的sql語句,最后由mybatis框架履行sql并將結(jié)果映照成java對象并返回。
-
mybatis可以將向 preparedStatement中的輸入?yún)?shù)自動進行輸入映照,將查詢結(jié)果集靈活映照成java對象。(輸出映照)
-
MyBatis框架示意圖
-
mapper.xml文件即sql映照文件,文件中配置了操作數(shù)據(jù)庫的sql語句。此文件需要在SqlMapConfig.xml中加載。
-
通過mybatis環(huán)境等配置信息構(gòu)造SqlSessionFactory即會話工廠
-
由會話工廠創(chuàng)建sqlSession即會話,操作數(shù)據(jù)庫需要通過sqlSession進行。
-
mybatis底層自定義了Executor履行器接口操作數(shù)據(jù)庫,Executor接口有兩個實現(xiàn),1個是基本履行器、1個是緩存履行器。
-
Mapped Statement也是mybatis1個底層封裝對象,它包裝了mybatis配置信息及sql映照信息等。mapper.xml文件中1個sql對應(yīng)1個Mapped Statement對象,sql的id即是Mapped statement的id。
-
Mapped Statement對sql履行輸入?yún)?shù)進行定義,包括HashMap、基本類型、pojo,Executor通過Mapped Statement在履行sql前將輸入的java對象映照至sql中,輸入?yún)?shù)映照就是jdbc編程中對preparedStatement設(shè)置參數(shù)。
-
Mapped Statement對sql履行輸出結(jié)果進行定義,包括HashMap、基本類型、pojo,Executor通過Mapped Statement在履行sql后將輸出結(jié)果映照至java對象中,輸出結(jié)果映照進程相當(dāng)于jdbc編程中對結(jié)果的解析處理進程。
MyBatis入門程序
-
需求
-
根據(jù)用戶id(主鍵)查詢用戶信息
-
根據(jù)用戶名稱模糊查詢用戶信息
-
添加用戶
-
刪除用戶
-
更新用戶
-
3.1 環(huán)境
-
java環(huán)境:jdk1.7.0_72
-
eclipse:indigo
-
mysql:5.1
-
mybatis運行環(huán)境(jar包):
-
從 https://github.com/mybatis/mybatis⑶/releases 下載,3.2.7版本
-
lib下:依賴包
-
mybatis⑶.2.7.jar:核心包
-
mybatis⑶.2.7.pdf,操作指南
# Global logging configuration log4j.rootLogger=DEBUG, stdout # Console output... log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n
-
工程結(jié)構(gòu)
-
SqlMapConfig.xml
-
配置Mybatis的運行環(huán)境,數(shù)據(jù)源、事務(wù)等。
<configuration> <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://localhost:3306/mybatis?characterEncoding=utf⑻" /> <property name="username" value="root" /> <property name="password" value="mysql" /> dataSource> environment> environments> configuration>
根據(jù)用戶id(主鍵)查詢用戶信息
創(chuàng)建po類
-
Po類作為mybatis進行sql映照使用,po類通常與數(shù)據(jù)庫表對應(yīng),User.java以下:
Public class User { private int id; private String username; private String sex; private Date birthday; private String address; get/set... toString
映照文件
-
映照文件命名:
-
User.xml(原始ibatis命名)
-
MyBatis的mapper代理開發(fā)映照文件名稱叫XXXMapper.xml
-
比如:UserMapper.xml、ItemsMapper.xml
-
在映照文件中配置sql語句
-
在classpath下的sqlmap目錄下創(chuàng)建sql映照文件Users.xml:
-
namespace : 命名空間,用于隔離sql語句,后面會講另外一層非常重要的作用。
-
配置參數(shù)說明
-
id:標(biāo)識 映照文件中的 sql 將sql語句封裝到mappedStatement對象中,所以將id稱為statement的id
-
parameterType:指定輸入 參數(shù)的類型,這里指定int型
-
#{}表示1個占位符號
-
#{id}:其中的id表示接收輸入 的參數(shù),參數(shù)名稱就是id,如果輸入 參數(shù)是簡單類型,#{}中的參數(shù)名可以任意,可以value或其它名稱
-
resultType:指定sql輸出結(jié)果的所映照的java對象類型,select指定resultType表示將單條記錄映照成的java對象。
<mapper namespace="test"> <select id="findUserById" parameterType="int" resultType="cn.itcast.mybatis.po.User"> SELECT * FROM USER WHERE id=#{value} select>
在SqlMapConfig.xml加載映照文件
-
在sqlMapConfig.xml中加載User.xml;
-
parameterType:定義輸入到sql中的映照類型,#{id}表示使用preparedstatement設(shè)置占位符號并將輸入變量id傳到sql。
-
resultType:定義結(jié)果映照類型。
<mappers> <mapper resource="sqlmap/User.xml"/> mappers>
測試程序編寫
public class MybatisFirst { @Test public void findUserByIdTest() throws IOException { String resource = "SqlMapConfig.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder()
.build(inputStream); SqlSession sqlSession = sqlSessionFactory.openSession(); User user = sqlSession.selectOne("test.findUserById", 1);
System.out.println(user); sqlSession.close();
}
}
根據(jù)用戶名稱模糊查詢用戶信息
映照文件
-
使用User.xml,添加根據(jù)用戶名稱模糊查詢用戶信息的sql語句。
-
resultType:指定就是單條記錄所映照的java對象 類型
-
${}:表示拼接sql串,將接收到參數(shù)的內(nèi)容不加任何修飾拼接在sql中。
-
value:接收輸入參數(shù)的內(nèi)容,如果傳入類型是簡單類型,{}中只能使用value
<select id="findUserByName" parameterType="java.lang.String" resultType="cn.itcast.mybatis.po.User"> SELECT * FROM USER WHERE username LIKE '%${value}%' select>
程序代碼
@Test public void findUserByNameTest() throws IOException { String resource = "SqlMapConfig.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder()
.build(inputStream); SqlSession sqlSession = sqlSessionFactory.openSession(); Listlist = sqlSession.selectList("test.findUserByName", "小明");
System.out.println(list);
sqlSession.close();
}
-
知識點回顧
-
#{}和${}
-
#{}表示1個占位符號,通過#{}可以實現(xiàn)preparedStatement向占位符中設(shè)置值,自動進行java類型和jdbc類型轉(zhuǎn)換,#{}可以有效避免sql注入。#{}可以接收簡單類型值或pojo屬性值。 如果parameterType傳輸單個簡單類型值,#{}括號中可以是value或其它名稱。
-
${}表示拼接sql串,通過${}可以將parameterType 傳入的內(nèi)容拼接在sql中且不進行jdbc類型轉(zhuǎn)換,${}可以接收簡單類型值或pojo屬性值,如果parameterType傳輸單個簡單類型值,${}括號中只能是value。
-
parameterType和resultType
-
parameterType:指定輸入?yún)?shù)類型,mybatis通過ognl從輸入對象中獲得參數(shù)值拼接在sql中。
-
resultType:指定輸出結(jié)果類型,mybatis將sql查詢結(jié)果的1行記錄數(shù)據(jù)映照為resultType指定類型的對象。
-
selectOne和selectList
-
selectOne查詢1條記錄,如果使用selectOne查詢多條記錄則拋出異常:
-
org.apache.ibatis.exceptions.TooManyResultsException: Expected one result (or null) to be returned by selectOne(), but found: 3 at org.apache.ibatis.session.defaults.DefaultSqlSession.selectOne(DefaultSqlSession.java:70)
-
selectList可以查詢1條或多條記錄。
添加用戶
-
在 User.xml中配置添加用戶的Statement
@Test public void insertUserTest() throws IOException { String resource = "SqlMapConfig.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder()
.build(inputStream); SqlSession sqlSession = sqlSessionFactory.openSession(); User user = new User();
user.setUsername("王小軍");
user.setBirthday(new Date());
user.setSex("1");
user.setAddress("河南鄭州");
sqlSession.insert("test.insertUser", user); sqlSession.commit(); System.out.println(user.getId()); sqlSession.close();
}
<insert id="insertUser" parameterType="cn.itcast.mybatis.po.User"> <selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer"> SELECT LAST_INSERT_ID() selectKey> insert into user ( username,birthday,sex,address) value(#{username},#{birthday},#{sex},#{address}) insert>
<selectKey keyProperty="id" order="BEFORE" resultType="java.lang.String"> SELECT uuid() selectKey> insert into user ( id,username,birthday,sex,address) value(#{id},#{username},#{birthday},#{sex},#{address})
SELECT 序列名.nextval()insert into user ( id,username,birthday,sex,address) value(#{id},#{username},#{birthday},#{sex},#{address})
刪除用戶
<delete id="deleteUser" parameterType="java.lang.Integer"> delete from user where id=#{id} delete>
@Test public void deleteUserTest() throws IOException { String resource = "SqlMapConfig.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder()
.build(inputStream); SqlSession sqlSession = sqlSessionFactory.openSession(); sqlSession.delete("test.deleteUser", 39); sqlSession.commit(); sqlSession.close();
}
更新用戶