一、MyBatis 入門
1匈勋、架構(gòu):
- sqlMapConfig.xml文件(這個(gè)文件名可以自己定義)
- mapper.xml文件時(shí)sql的映射文件(這個(gè)文件需要在上邊的sqlMapConfig.xml進(jìn)行配置)
- 通過mybatis環(huán)境配置構(gòu)造sqlSessionFactory會(huì)話工廠
- 會(huì)話工廠創(chuàng)建sqlSession會(huì)話
- mybatis底層自定義了Executor執(zhí)行器接口操作數(shù)據(jù)庫(kù)若皱,兩個(gè)接口實(shí)現(xiàn)兔毙,一個(gè)是基本實(shí)現(xiàn),一個(gè)是緩存實(shí)現(xiàn)
- Mapped Statement 是mybatis的一個(gè)底層封裝對(duì)象,包裝了mybatis的配置信息疯趟,sql映射信息拘哨,mapper.xml中的一個(gè)sql對(duì)應(yīng)一個(gè)mapped statement對(duì)象。so sql的id就是Mapped statement 的id
- Mapped Statement對(duì)sql執(zhí)行輸入?yún)?shù)進(jìn)行定義信峻,包括HashMap基本類型 pojo 倦青。類似于jdbc的preparedStatement的參數(shù)設(shè)置。
- Mapped Statement對(duì)輸出結(jié)果進(jìn)行定義站欺,包括hashMap 基本類型 pojo
2姨夹、下載
下載文件
- mybatis-x.x.x.jar核心包
- lib依賴包
3、入門程序
創(chuàng)建java工程
-
加入mybatis的核心包矾策,依賴包磷账,數(shù)據(jù)驅(qū)動(dòng)包
- lib\asm-3.3.1.jar
lib\cglib-2.2.2.jar
lib\commons-logging-1.1.1.jar
lib\ehcache-core-2.6.5.jar
lib\javassist-3.17.1-GA.jar
lib\junit-4.9.jar
lib\log4j-1.2.17.jar
lib\log4j-api-2.0-rc1.jar
lib\log4j-core-2.0-rc1.jar
lib\mybatis-3.2.7.jar
lib\mybatis-ehcache-1.0.2.jar
lib\mysql-connector-java-5.1.7-bin.jar
lib\slf4j-api-1.7.5.jar
lib\slf4j-log4j12-1.7.5.jar
- lib\asm-3.3.1.jar
-
config目錄下創(chuàng)建log4j.properties 創(chuàng)建輸出日志
# 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
-
創(chuàng)建SqlMapConfig.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> <!--jdbc的配置方式,spring中的配置方式--> <environments default="development"> <environment id="development"> <!-- 使用jdbc事務(wù)管理--> <transactionManager type="JDBC" /> <!-- 數(shù)據(jù)庫(kù)連接池--> <dataSource type="POOLED"> <property name="driver" value="com.mysql.jdbc.Driver" /> <property name="url" value="jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8" /> <property name="username" value="root" /> <property name="password" value="mysql" /> </dataSource> </environment> </environments> </configuration>
-
創(chuàng)建PO類
Public class User { private int id; private String username;// 用戶姓名 private String sex;// 性別 private Date birthday;// 生日 private String address;// 地址 get/set……
-
程序編寫-基本的操作*查詢
- Users.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"> <mapper namespace="test"> </mapper>
- Users.xml
<select id="findUserById" parameterType="int" resultType="com.baip.po.User"> select * from user where id = #{id} </select> <!-- 自定義條件查詢用戶列表 --> <select id="findUserByUsername" parameterType="java.lang.String" resultType="com.baip.po.User"> select * from user where username like '%${value}%' </select>
paramterType定義輸入到sql中映射類型贾虽,#{id}表示使用preparedstatement設(shè)置占位符號(hào)逃糟,并將輸入變量id傳到sql
resultType:定義結(jié)果映射類型
#{id}是進(jìn)行映射的表示一個(gè)占位符號(hào),可以實(shí)現(xiàn)preparedStatement向占位符中設(shè)置值蓬豁,防止sql注入绰咽。如果傳入的參數(shù)是簡(jiǎn)單類型,括號(hào)中可以是value或者是其他的名稱地粪。
${}是進(jìn)行拼接的 取募,不進(jìn)行jdbc的類型轉(zhuǎn)換,括號(hào)中只能是value- 加載映射文件蟆技,在SqlMapConfig.xml中
<mappers> <mapper resource="sqlmap/User.xml"/> </mappers>
- 測(cè)試程序
private SqlSessionFactory sqlSessionFactory; @Before public void createSqlSessionFactory() throws IOException { // 配置文件 String resource = "SqlMapConfig.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); // 使用SqlSessionFactoryBuilder從xml配置文件中創(chuàng)建SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder() .build(inputStream); }
@Test
public void testFindUserById() {
// 數(shù)據(jù)庫(kù)會(huì)話實(shí)例
SqlSession sqlSession = null;
try {
// 創(chuàng)建數(shù)據(jù)庫(kù)會(huì)話實(shí)例sqlSession
sqlSession = sqlSessionFactory.openSession();
// 查詢單個(gè)記錄玩敏,根據(jù)用戶id查詢用戶信息
User user = sqlSession.selectOne("test.findUserById", 10);
// 輸出用戶信息
System.out.println(user);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (sqlSession != null) {
sqlSession.close();
}
}
}
```
-
新增* 自增鍵返回
User.xml中<insert id="insertUser" parameterType="com.baip.po.User"> <!-- selectKey將主鍵返回,需要再返回 --> <selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer"> select LAST_INSERT_ID() </selectKey> insert into user(username,birthday,sex,address) values(#{username},#{birthday},#{sex},#{address}); </insert>
- keyProperty 返回的主鍵放到pojo的哪個(gè)屬性上
- order 執(zhí)行順序
- resultType查看返回的追殲類型
- LAST_INSERT_ID mysql的函數(shù)
關(guān)于主鍵的賦值方式可以是:
select uuid() SELECT 自定義序列.NEXTVAL FROM DUAL
二质礼、Dao開發(fā)方法
上邊的測(cè)試方法類似于傳統(tǒng)的Dao方法旺聚,通過SqlSessionFactory創(chuàng)建sqlSession調(diào)用SqlSession的數(shù)據(jù)庫(kù)方法
調(diào)用sqlSession的數(shù)據(jù)庫(kù)方法執(zhí)行statement的id存在硬編碼,不利于開發(fā)維護(hù)眶蕉。sqlSession.selectOne
這個(gè)selectOne就是Dao寫的方法砰粹,這個(gè)就是硬編碼
1、Mapper動(dòng)態(tài)代理的方式
- 實(shí)現(xiàn)原理
Mapper接口開發(fā)方法中需要遵循如下的規(guī)范- Mapper.xml文件中的nameSpace和maper接口的類路徑相同
- Mapper接口方法名和Mapper.xml中定義的id相同
- Maper接口中輸入的參數(shù)類型和Mapper.xml中定義的每個(gè)sql的parameterType的類型相同
- Mapper接口中輸出的參數(shù)類型和mapper.xml中定義的每個(gè)sql的result的類型相同
- Mapper.xml映射文件
<mapper namespace="com.baip.mapper.UserMapper"> <select id="findUserById" parameterType="int" resultType="com.baip.po.User"> select * from user where id = #{id} </select>
- Mapper.java接口文件:
注意相等的地方:Public interface UserMapper { //根據(jù)用戶id查詢用戶信息 public User findUserById(int id) throws Exception; //查詢用戶列表 public List<User> findUserByUsername(String username) throws Exception; //添加用戶信息 public void insertUser(User user)throws Exception; }
- UserMapper namespace 和interface的接口名一致
- findUserById id和方法名一致
- UserMapper的 findUserById方法參數(shù) int類型和parameterType參數(shù)保持一致
- UserMapper的 findUserById方法返回參數(shù) 和 resultType保持一致
- 加載UserMapper.xml
在SqlMapConfig.xml中造挽,加載映射文件<!-- 加載映射文件 --> <mappers> <mapper resource="mapper/UserMapper.xml"/> </mappers>
三碱璃、SqlMapConfig.xml配置文件
1、配置內(nèi)容
從上到下依次:
- properties
- settings
- typeAliases(類型別名)
- typeHandlers(類型處理器)
- objectFactory對(duì)象工廠
- plugin(插件)
- environments(環(huán)境集合屬性對(duì)象)
environment(環(huán)境子屬性對(duì)象)
transactionManager(事務(wù)管理)
dataSource(數(shù)據(jù)源) - mappers映射器
2刽宪、properties
-
定義db.properties文件
jdbc.driver=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/mybatis jdbc.username=root jdbc.password=mysql
-
SqlMapConfig.xml中引用:
<properties resource="db.properties"/> <environments default="development"> <environment id="development"> <transactionManager type="JDBC"/> <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>
mybatis對(duì)對(duì)應(yīng)屬性的加載順序
- proerties元素內(nèi)定義的屬性首先被讀取
- properties元素中的resource或者是url加載屬性厘贼,會(huì)覆蓋讀取的同名屬性
- 最后讀取parameterType傳遞的屬性,覆蓋已經(jīng)讀取的同名屬性
3圣拄、settings配置
<settings>
<!-- 打開延遲加載 的開關(guān) -->
<setting name="lazyLoadingEnabled" value="true"/>
<!-- 將積極加載改為消極加載即按需要加載 -->
<setting name="aggressiveLazyLoading" value="false"/>
<!-- 開啟二級(jí)緩存 -->
<setting name="cacheEnabled" value="true"/>
</settings>
4嘴秸、typeAliases(類型別名)
別名 | 映射類型 |
---|---|
_byte | byte |
_long | long |
_short | short |
_int | int |
_integer | int |
_double | double |
_float | float |
_boolean | boolean |
string | String |
byte | Byte |
long | Long |
short | Short |
int | Integer |
integer | Integer |
double | Double |
float | Float |
boolean | Boolean |
date | Date |
decimal | BigDecimal |
bigdecimal | BigDecimal |
自定義別名
<typeAliases>
<!-- 單個(gè)別名定義 -->
<typeAlias alias="user" type="com.baip.po.User"/>
<!-- 批量別名定義,掃描整個(gè)包下的類,別名為類名(首字母大寫或小寫都可以) -->
<package name="com.baip.po"/>
<package name="其它包"/>
</typeAliases>
5岳掐、mappers映射器
1.類型處理器用于java類型和jdbc類型映射凭疮,如下: <mapper resource="sqlmap/User.xml" />
<mapper url="file:///D:\workspace\mybatis_01\config\sqlmap\User.xml" />
-
<mapper class="com.baip.mapper.UserMapper"/>
此種方法要求mapper接口名稱和mapper映射文件名稱相同,且放在同一個(gè)目錄中串述。 -
<package name="com.baip.mapper"/>
注冊(cè)指定包下的所有mapper接口 此種方法要求mapper接口名稱和mapper映射文件名稱相同执解,且放在同一個(gè)目錄中。
6纲酗、Mapper.xml映射文件
6.1 parameterType
傳遞pojo對(duì)象
<select id='findUserByUser' paramterType="User" resultType="user">
select * from wehre id=#{id} and usernamelike '%${usernaem}%'
</select>
上邊標(biāo)注的是user對(duì)象中的字段名
傳遞hashmap
Sql映射文件定義如下:
<!-- 傳遞hashmap綜合查詢用戶信息 -->
<select id="findUserByHashmap" parameterType="hashmap" resultType="user">
select * from user where id=#{id} and username like '%${username}%'
</select>
這里的id和username都是指hashMap的key
resultType總結(jié)
- 輸出
pojo
對(duì)象和輸出pojo
列表在sql
中定義resultType
是一樣的 - 返回單個(gè)
pojo
對(duì)象要保證sql
查詢出來的結(jié)果集為單條衰腌,內(nèi)部使用session.selectOne
方法調(diào)用 - 返回
pojo
列表表示查詢出來的結(jié)果集可能多條,內(nèi)部使用session.selectList
方法觅赊,mapper
接口使用List<pojo>
對(duì)象作為方法返回值
7右蕊、動(dòng)態(tài)sql
1、if
<!-- 傳遞pojo綜合查詢用戶信息 -->
<select id="findUserList" parameterType="user" resultType="user">
select * from user
where 1=1
<if test="id!=null and id!=''">
and id=#{id}
</if>
<if test="username!=null and username!=''">
and username like '%${username}%'
</if>
</select>
2吮螺、where
自動(dòng)處理第一個(gè)and
<select id="findUserList" parameterType="user" resultType="user">
select * from user
<where>
<if test="id!=null and id!=''">
and id=#{id}
</if>
<if test="username!=null and username!=''">
and username like '%${username}%'
</if>
</where>
</select>
3饶囚、foreach
向sql傳遞數(shù)組或List mybatis使用foreach解析
<if test="ids!=null and ids.size>0">
<foreach collection="ids" open=" and id in(" close=")" item="id" separator="," >
#{id}
</foreach>
</if>
8、sql片段
<sql id="query_user">
<if test="id!=null and id!=''">
and id=#{id}
</if>
<if test="username!=null and username!=''">
and username like '%${username}%'
</if>
</sql>
使用的時(shí)候鸠补,include
<select id="findUsers" parameterType="user" resultType="user">
select * from user
<where>
<include refid="namespace.query_user"/>
</where>
</select>
如果是其他的workspace里的代碼片段萝风,那就需要前邊追加一個(gè)namespace
四、整合spring
通過spring管理sqlSessionFactory mapper接口
mybatis提供的spring整合jar包
mybatis-spring-x.x.x.jar
SqlMapConfig.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>
<!—使用自動(dòng)掃描器時(shí)紫岩,mapper.xml文件如果和mapper.java接口在一個(gè)目錄則此處不用定義mappers -->
<mappers>
<package name="cn.baip.mapper" />
</mappers>
</configuration>
applicationContext.xml 定義數(shù)據(jù)庫(kù)連接池和sqlSessionFactory
<!-- 加載配置文件 -->
<context:property-placeholder location="classpath:db.properties"/>
<!-- 數(shù)據(jù)庫(kù)連接池 -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
<property name="maxActive" value="10"/>
<property name="maxIdle" value="5"/>
</bean>
<!-- mapper配置 -->
<!-- 讓spring管理sqlsessionfactory 使用mybatis和spring整合包中的 -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!-- 數(shù)據(jù)庫(kù)連接池 -->
<property name="dataSource" ref="dataSource" />
<!-- 加載mybatis的全局配置文件 -->
<property name="configLocation" value="classpath:mybatis/SqlMapConfig.xml" />
</bean>
</beans>
1规惰、Mapper Dao接口實(shí)現(xiàn)繼承sqlSessionDaoSupport
- 在sqlMapConfig.xml中配置映射文件
<mappers> <mapper resource="mapper.xml文件的地址" /> <mapper resource="mapper.xml文件的地址" /> </mappers>
```
- 定義dao接口
- dao接口實(shí)現(xiàn)類集成SqlSessionDaoSupport
SqlSession sqlSession = this.getSqlSession(); User user = sqlSession.selectOne("test.findUserById", id); return user;
- spring配置
<bean id="" class="mapper接口實(shí)現(xiàn)"> <property name="sqlSessionFactory" ref="sqlSessionFactory" ></property> </bean>
2、使用org.mybatis.spring.mapper.MapperFactoryBean
- 在sqlMapConfig.xmlz中配置mapper.xml位置
- d定義接口
- spring中定義
<bean id="" class="org.mybatis.spring.mapper.MapperFactoryBean"> <property name="mapperInterface" value="mapper接口地址"/> <property name="sqlSessionFactory" ref="sqlSessionFactory"/> </bean>
<bean id="userMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">
<!--mapperInterface指定mapper接口-->
<property name="mapperInterface" value="com.baip.ssm.mapper.UserMapper"/>
<property name="sqlSessionFactory" ref="sqlSessionFactory"/>
</bean>
```
3泉蝌、mapper掃描卿拴,感覺這個(gè)比較常用
mapper編寫
-
定義mapper接口
注意mapper.xml的文件名和mapper的接口名保持一致,而且放在同一個(gè)目錄下
-
配置mapper掃描在application中
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="mapper接口包地址"></property> <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/> </bean>
多個(gè)包的時(shí)候梨与,中間可以用逗號(hào)或者是分號(hào)分割
spring容器中獲取mapper的實(shí)現(xiàn)對(duì)象。
如果將mapper.xml 和mapper接口的名稱保持一致文狱,放在同一個(gè)目錄下粥鞋,不用在sqlMapConfig.xml中進(jìn)行配置