mybatis是一個封裝了jdbc的不完全的orm持久層框架,它使程序員只關注sql本身,而不需要關注創建連接、statement創建等重複操作,只要具有sql基礎就可以上手。相對於hibernate,mybatis不能自動建表,但是可以直接編寫sql語句靈活性好易於sql優化和維護。可見mybatis更擅長需求多變的場景,如互聯網場景。
創建mybatis項目
1.mybaits的代碼由github.com管理,下載地址:https://github.com/mybatis/mybatis-3/releases
創建mybatis生產環境。
2.創建數據庫和表
3.編寫pojo類
4.編寫默認全局配置文件,一般叫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>
<properties resource="db.properties">
<property name="db.username" value="666" />
</properties>-->
<settings></settings>
<!--別名-->
<typeAliases>
<!--給User類定義別名user-->
<typeAlias type="com.aloha.mybatis.po.User" alias="user"/>
<!-- package:指定包名稱來爲該包下的po類聲明別名,默認的別名就是類名(首字母大小寫都可) -->
<package name="com.aloha.mybatis.po" />
</typeAliases>
<!-- 配置mybatis的環境信息,與spring整合,該信息由spring來管理 -->
<environments default="development">
<environment id="development">
<!-- 配置JDBC事務控制,由mybatis進行管理 -->
<transactionManager type="JDBC"></transactionManager>
<!-- 配置數據源,採用mybatis連接池 -->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/mybatis1?useUnicode=true&characterEncoding=utf-8" />
<property name="username" value="root" />
<property name="password" value="root" />
</dataSource>
</environment>
</environments>
<!-- 加載映射文件 -->
<mappers>
<mapper resource="User.xml" />
<mapper resource="mapper/UserMapper.xml" />
<!-- 批量加載映射文件:此方法要求mapper接口和mapper映射文件相同且位於同一目錄中 -->
<!--<package name="com.aloha.mybatis.po" />-->
</mappers>
</configuration>
db.properties的配置同dataSource中的配置,配置後可替代value的值。
5.創建mapper映射的User.xml文件:
文件中引入mapper約束:
<?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標籤操作數據庫:
<mapper namespace="test">
<!--根據用戶id查詢用戶信息
mappedstatement對象
id:statement的唯一標識
resultType:輸出結果映射的java類型:單條結果對應的java類型
-->
<select id="findUserById" parameterType="string" resultType="com.aloha.mybatis.po.User" >
SELECT * FROM USER WHERE id = #{id}
</select>
<!--模糊查詢-->
<select id="findUserByName" parameterType="java.lang.String" resultType="com.aloha.mybatis.po.User">
SELECT * FROM USER WHERE username LIKE '%${value}%'
</select>
<!--添加
<insert id="insertUser" parameterType="com.aloha.mybatis.po.User">
INSERT INTO USER(username,birthday,sex,address) VALUES (#{username},#{birthday},#{sex},#{address})
</insert>-->
<!--自增主鍵: LAST_INSERT_ID()是mysql函數-->
<insert id="insertUser" parameterType="com.aloha.mybatis.po.User">
<selectKey keyProperty="id" resultType="int" order="AFTER">
SELECT LAST_INSERT_ID()
</selectKey>
INSERT INTO USER(username,birthday,sex,address) VALUES(#{username},#{birthday},#{sex},#{address})
</insert>
<!--主鍵返回uuid
如果使用uuid那麼id必須爲string類型,得改一些定義
-->
<insert id="insertUserUUID" keyProperty="com.aloha.mybatis.po.User">
<selectKey keyProperty="id" resultType="string" order="BEFORE">
SELECT UUID()
</selectKey>
INSERT INTO USER(id,username,birthday,sex,address) VALUES(#{id},#{username},#{birthday},#{sex},#{address})
</insert>
</mapper>
創建測試類寫測試方法:
public class MybatisTest {
@Test
public void findUserByIdTest() throws Exception {
//讀取全局配置文件路徑
String resource = "SqlMapConfig.xml" ;
InputStream inputStream = Resources.getResourceAsStream(resource);
//創建SqlSessionFactory
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//創建SqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
User o = sqlSession.selectOne("test.findUserById", 2);
System.out.println(o);
sqlSession.close();
}
}
測試結果:
如果是模糊查詢:
返回的結果數量大於2 的話應該使用selectList查詢,用List接收。
#{}和${}
#{}表示佔位符?,#{}接收簡單類型的參數時,裏面的名稱可以任意 ${}表示拼接符,${}接收簡單類型的參數時,裏面的名稱必須是value ${}裏面的值會原樣輸出,不加解析(如果該參數值是字符串,有不會添加引號) ${}存在sql注入的風險,但是有些場景下必須使用,比如排序後面會動態傳入排序的列名 |
Mapper接口開發需要遵循以下規範:
1、 Mapper.xml文件中的namespace與mapper接口的類路徑相同。
2、 Mapper接口方法名和Mapper.xml中定義的每個statement的id相同
3、 Mapper接口方法的輸入參數類型和mapper.xml中定義的每個sql 的parameterType的類型相同
4、 Mapper接口方法的輸出參數類型和mapper.xml中定義的每個sql的resultType的類型相同
接口開發簡單實例:
創建接口
public interface UserMapper {
public User findUserById(int id) throws Exception;
public void insertUser(User user) throws Exception;
}
編寫UserMapper.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="com.aloha.mybatis.po.usermapper.UserMapper">
<!-- 根據用戶ID查詢用戶信息 -->
<select id="findUserById" parameterType="int" resultType="User">
SELECT * FROM USER WHERE id =#{id}
</select>
<!-- 添加用戶 -->
<insert id="insertUser" parameterType="com.aloha.mybatis.po.User">
<selectKey keyProperty="id" resultType="int" order="AFTER">
SELECT LAST_INSERT_ID()
</selectKey>
INSERT INTO USER(username,birthday,sex,address) VALUES(#{username},#{birthday},#{sex},#{address})
</insert>
</mapper>
編寫測試類:
package com.aloha.mybatis.po.usermapper;
import com.aloha.mybatis.po.User;
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.InputStream;
public class UserMapperTest {
private SqlSessionFactory sqlSessionFactory;
@Before
public void setUp() throws Exception{
String resource = "SqlMapConfig.xml" ;
InputStream inputStream = Resources.getResourceAsStream(resource);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
}
@Test
public void userMapperTest() throws Exception{
SqlSession sqlSession = sqlSessionFactory.openSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
User userById = mapper.findUserById(1);
System.out.println(userById);
sqlSession.close();
}
@Test
public void insertUserTest() throws Exception{
SqlSession sqlSession = sqlSessionFactory.openSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
User user = new User();
user.setUsername("王尼瑪");
user.setAddress("西安");
mapper.insertUser(user);
sqlSession.commit();
sqlSession.close();
}
}
測試結果:
注意:
SqlSession對象創建不能提取公共部分是因爲SqlSession是存儲數據的是線程不安全的。
執行插入操作時需要提交事務否則執行不完成。
使用mapper接口方式開發mapper標籤的namespace屬性必須時Mapper類的全路徑。
Mapper的xml文件必須和
請遵守mapper接口編程規範。。。
MyBatis整合Spring
mybatis將加載properties、創建數據資源、sqlSessionFactory管理和bean管理(包括mapper管理)權交給Spring。
創建SqlMapConfig.xml:(可以看到,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>
<!--自定義別名-->
<typeAliases>
<package name="com.aloha.mybatis.po"/>
</typeAliases>
<!--加載映射文件-->
<mappers>
<mapper resource="mybatis/sqlMap/User.xml"/>
</mappers>
</configuration>
創建pojo的User.java和User.xml;
創建UserMapperSpring.java:
package com.aloha.mybatis.mapper;
import com.aloha.mybatis.po.User;
public interface UserMapperSpring {
public User findUserById(int id) throws Exception;
public void insertUser(User user) throws Exception;
}
在UserMapperSpring.java同目錄下創建UserMapperSpring.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="com.aloha.mybatis.mapper.UserMapperSpring">
<select id="findUserById" parameterType="int" resultType="com.aloha.mybatis.po.User">
SELECT * FROM USER WHERE id = #{id}
</select>
</mapper>
創建applicationContext.xml:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd ">
<!-- 加載jdbc的配置文件 -->
<context:property-placeholder location="db.properties"/>
<!-- 創建數據源-->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="${db.driver}"/>
<property name="url" value="${db.url}"/>
<property name="username" value="${db.username}"/>
<property name="password" value="${db.password}"/>
<property name="maxActive" value="10"/>
<property name="maxIdle" value="5"/>
</bean>
<!--管理sqlSessionFactory-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="configLocation" value="mybatis/SqlMapConfig.xml"/>
<property name="dataSource" ref="dataSource"/>
</bean>
<!--管理UserDao-->
<bean id="userDao" class="com.aloha.mybatis.dao.UserDaoImplSpring">
<!--依賴注入sqlSessionFactory-->
<property name="sqlSessionFactory" ref="sqlSessionFactory"></property>
</bean>
<!--通過mapper方式查詢:Spring創建mapper代理,可以單個,也可以批量-->
<bean id="userMapperSpring" class="org.mybatis.spring.mapper.MapperFactoryBean">
<property name="mapperInterface" value="com.aloha.mybatis.mapper.UserMapperSpring"/>
<property name="sqlSessionFactory" ref="sqlSessionFactory"/>
</bean>
</beans>
編寫測試類:
package com.aloha.mybatis.mapper;
import com.aloha.mybatis.po.User;
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class UserMapperTest {
private ApplicationContext context ;
@Before
public void SetUp() throws Exception{
context = new ClassPathXmlApplicationContext("spring/applicationContext.xml");
}
@Test
public void findUserByIdTest() throws Exception{
UserMapperSpring userMapperSpring =(UserMapperSpring) context.getBean("userMapperSpring");
User userById = userMapperSpring.findUserById(2);
System.out.println(userById);
}
}
測試結果: