【開課吧javaEE每日一學190803】mybatis開發DAO層與SqlMapConfig.xml配置檔案
阿新 • • 發佈:2019-08-04
原始開發方式
實現流程
- 編寫SqlMapConfig.xml配置檔案和mapper.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"></properties> <environments default="development"> <environment id="development"> <transactionManager type="JDBC"/> <dataSource type="POOLED"> <property name="driver" value="${db.driver}"/> <property name="url" value="${db.url}"/> <property name="username" value="${db.username}"/> <property name="password" value="${db.password}"/> </dataSource> </environment> </environments> <mappers> <mapper resource="UserMapper.xml"/> </mappers> </configuration>
UserMapper.xmldb.driver=com.mysql.jdbc.Driver db.url=jdbc:mysql://localhost:3306/ssm db.username=root db.password=admin
上面使用like的時候用的是$而不是#,至於$和#的區別看$和#的區別<?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作用是為了分類管理對映檔案中的MapperdStatement物件--> <mapper namespace="test"> <select id="findUserById" parameterType="int" resultType="test.User"> select * from User where id = #{hello} </select> <!--${value}表示輸入引數將${value}替換,直接做字串的拼接,如果是取簡單數量型別的引數,括號中的引數名必須是value--> <select id="findUserByUsername" parameterType="java.lang.String" resultType="test.User"> select * from user where username like '%${value}%' </select> <insert id="insertUser" parameterType="test.User"> <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> </mapper>
- 開發介面(DAO層介面)
package top.dao; import test.User; public interface UserDao { User findUserById(int id) throws Exception; void insertUser(User user) throws Exception; }
- 實現介面(DAO實現類,在實現類中通過sqlsesion與資料庫打交道)
package top.dao.impl; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import test.User; import top.dao.UserDao; public class UserDaoImpl implements UserDao { private SqlSessionFactory sqlSessionFactory; // 注入sqlsessionFactory public UserDaoImpl(SqlSessionFactory sqlSessionFactory) { this.sqlSessionFactory = sqlSessionFactory; } @Override public User findUserById(int id) throws Exception { SqlSession sqlSession = sqlSessionFactory.openSession(); User user = sqlSession.selectOne("test.findUserById", id); sqlSession.close(); return user; } @Override public void insertUser(User user) throws Exception { SqlSession sqlSession = sqlSessionFactory.openSession(); sqlSession.insert("test.insertUser", user); sqlSession.commit(); sqlSession.close(); } }
- 測試類
@Test public void testFindById() throws Exception { UserDao userDao = new UserDaoImpl(sqlSessionFactory); User user = userDao.findUserById(1); System.out.println(user); }
幾個物件的生命週期
-
sqlSession: 方法級別
所謂的方法級別就是需要在方法裡面建立的物件
-
sqlSessionFactory: 全域性範圍,是應用級別
-
sqlSessionFactoryBuilder: 方法級別
mapper代理開發方式(xml配置檔案)
mapper代理開發方式就是使用介面開發方式,上面使用原始的dao進行開發的時候不僅僅建立了dao介面,還有dao的實現類,我們是在實現類裡面去建立sqlsession物件來操作資料庫的,現在所謂的mapper代理開發方式就是去掉dao的實現類,只需要保留介面即可,但是使用mapper代理方式開發是有前置條件的。具體條件如下:
- mapper介面的類路徑需要與mapper.xml檔案中的namespace相同 這裡需要注意的是類路徑而不是包路徑,如果是寫的包路徑就會出現下面的錯誤 org.apache.ibatis.binding.BindingException: Type interface top.mapper.UserMapper is not known to the MapperRegistry.
- mapper介面的方法名稱需要和mapper.xml中定義的每一個statement的id相同
- mapper介面的方法輸入引數型別需要和mapper.xml中定義的每一個sql的parameterType的型別相同
- mapper介面的方法的輸出引數型別和mapper.xml中定義的每一個sql的resultType的型別相同 依然是上面的案例進行修改:
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">
<!--namespace作用是為了分類管理對映檔案中的MapperdStatement物件-->
<mapper namespace="top.mapper.UserMapper">
<select id="findUserById" parameterType="int" resultType="test.User">
select * from User where id = #{hello}
</select>
<!--${value}表示輸入引數將${value}替換,直接做字串的拼接,如果是取簡單數量型別的引數,括號中的引數名必須是value-->
<select id="findUserByUsername" parameterType="java.lang.String" resultType="test.User">
select * from user where username like '%${value}%'
</select>
<insert id="insertUser" parameterType="test.User">
<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>
</mapper>
這裡可以看到mapper檔案中namespace已經改了,是mapper介面的類路徑。
mapper介面
package top.mapper;
import test.User;
public interface UserMapper {
User findUserById(int id) throws Exception;
void insertUser(User user) throws Exception;
}
測試程式碼
package test;
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 top.mapper.UserMapper;
import top.mapper.impl.UserMapperImpl;
import java.io.IOException;
import java.io.InputStream;
import java.util.Date;
import java.util.List;
public class TestUser {
// 會話工廠
private SqlSessionFactory sqlSessionFactory;
// 該註解可以在@test註解之前執行
@Before
public void createSqlSessionFactory() throws IOException {
// 載入配置檔案
String resource = "SqlMapConfig.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
// 使用sqlSessionFactoryBuilder從xml中建立sqlsessionfactory
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
}
@Test
public void testMapperFind() throws Exception {
SqlSession sqlSession = sqlSessionFactory.openSession();
// 獲取mapper介面的代理物件
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
// 呼叫代理物件方法
User user = userMapper.findUserById(1);
System.out.println(user);
sqlSession.close();
}
}
SqlMapperConfig.xml配置檔案常用的標籤
mybatis的主配置檔案可以配置如下所示的標籤:
- properties(屬性,可以將外部的屬性檔案載入進來。比如資料庫的配置檔案)
-
<!--載入配置檔案--> <properties resource="db.properties"></properties>
-
除了使用resource屬性之外還可以使用properties標籤中定義property子標籤來定義資料可屬性值
<properties> <property name="driver" value="com.mysql.jdbc.Driver"/> </properties>
-
mybatis是先讀取properties元素體內的屬性,然後再去讀取url或者resource載入的屬性,此時會覆蓋已讀取的同名的屬性。
-
- settings(全域性配置引數)
- typeAlias標籤,定義別名的
- 批量或者單個定義別名
<typeAliases> <!--定個定義別名--> <!--<typeAlias type="test.User" alias="user"/>--> <!--批量定義別名.掃描整個包下面的類,別名為類名(首字母大小或小寫都可以)--> <package name="test"/> </typeAliases>
- 批量或者單個定義別名
- mappers標籤
- <mapper resource=" " />(單個)
- 使用相對於類路徑的資源
- 案例: <mapper resource="sqlmap/User.xml" />
- <mapper class=" " />(單個)
- 使用的是介面類路徑
- 案例: <mapper class="com.kkb.mybatis.mapper.UserMapper"/>
- 此時需要注意的是要求mapper介面名稱和mapper對映檔名稱相同,並且應該放在同一個目錄中
- <package name=""/>(批量)
- 註冊指定包下的所有mapper介面,來載入對映檔案
- 案例:<package name="com.kkb.mybatis.mapper"/>
- 使用批量的方式要求mapper介面名稱和mapper對映檔案的名稱相同,並且放在同一個目錄中
- <mapper resource=" " />(單個)