1.背景
在上篇中咱們使用了MyBatis實現簡單的增刪改查,並無進行dao層的封裝,因此在這裏咱們進行dao層開發:html
(1)傳統的jdbc dao層開發(寫dao接口,實現dao接口類)java
(2)mapper代理方法 (只須要寫mapper接口類,至關於dao接口類)mysql
在Mybatis操做的時候,咱們使用的是SqlSession 來進行數據庫操做,其中SqlSession的使用範圍:
經過SqlSessionFactoryBuilder建立SqlSessionFactory ,而SqlSession經過SqlSessionFactory 建立,因此使用單例模式管理SqlSessionFactory,未來使用mybatis和spring整合後,使用單例模式管理SqlSessionFactory;
spring
SqlSession的做用是:
1)提供接口,不少操做數據庫的方法,如:selectOne ,selectList
2)線程不安全,在sqlSession實現類中除了有接口中的方法,還有數據域的屬性;
3)最佳應用的場合在方法體內,定義成局部變量使用。sql
2.原始dao開發實現
(1)dao接口
- package mybatie.dao;
-
- import mybatis.po.FClient;
-
-
-
-
-
-
-
-
-
- public interface ClientDao {
-
- FClient findClientById(int id) throws Exception;
-
- void updateClient(FClient f) throws Exception;
-
- void deleteClient(int id) throws Exception;
-
- void insertClient(FClient f) throws Exception;
-
- }
(2)實現dao接口
實現數據庫操做的幾個方法:數據庫
- package mybatie.dao;
-
- import mybatis.po.FClient;
- import oracle.net.aso.s;
-
- import org.apache.ibatis.session.SqlSession;
- import org.apache.ibatis.session.SqlSessionFactory;
-
- public class ClientDaoImp implements ClientDao {
-
- private SqlSessionFactory sqlSessionFactory;
-
- public ClientDaoImp(SqlSessionFactory sqlSessionFactory) {
- this.sqlSessionFactory = sqlSessionFactory;
- }
-
- @Override
- public FClient findClientById(int id) {
-
- SqlSession sqlSession = sqlSessionFactory.openSession();
- FClient c = sqlSession.selectOne("test.findClientById", id);
- sqlSession.close();
- return c;
- }
-
- @Override
- public void updateClient(FClient f) {
- SqlSession sqlSession=sqlSessionFactory.openSession();
- sqlSession.update("test.updateClient",f);
- sqlSession.commit();
- sqlSession.close();
- }
-
- @Override
- public void deleteClient(int id) {
- SqlSession session = sqlSessionFactory.openSession();
- session.delete("test.deleteClient", id);
- session.commit();
- session.close();
- }
-
- @Override
- public void insertClient(FClient f) {
- SqlSession session = sqlSessionFactory.openSession();
- session.insert("test.insertClient", f);
- session.commit();
- session.close();
- }
-
-
- }
(3)測試類
- public class TestClient {
-
- private SqlSessionFactory sqlSessionFactory;
-
- @Before
- public void setUp() throws Exception {
- InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml");
- sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
- }
-
- @Test
- public void test() {
- fail("Not yet implemented");
- }
-
- @Test
- public void findClientById() throws Exception {
-
- ClientDao clientDao = new ClientDaoImp(sqlSessionFactory);
- FClient c = clientDao.findClientById(1);
- System.out.println(c);
- }
-
- }
(4)原始的dao層遇到的問題
1)dao接口實現類方法中存在大量的模板方法,設想可否將這些代碼提取出來
2)調用sqlsession方法的時候將statement存在硬編碼
3)調用sqlsession的方法的時候,傳入參數爲Object 類型,及時傳入錯誤,也不會報錯
apache
3.使用Mapper代理的方式實現
基本步驟爲 : 安全
1)編寫mapper.xml映射文件 session
2)編寫Mapper接口,至關於dao接口 mybatis
3)mybatis能夠自動生成mapper接口的實現類代理對象
(1)實現Mapper映射文件
mapper.xml 規範 :
1)namespace 等於mapper接口地址
2)mapper.Java 接口中的方法和mapper.xml中的statement 的id一致
3)mapper.java 接口中的方法的參數和mapper.xml中的statement 的paramterType類型一致
4)mapper.java 接口中的方法的返回值和mapper.xml中的statement的resultType類型一致
總結 :mapper.xml實現的規範,就是對SqlSession接口中的方法進行統一的生成
好比 :
- <?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="mybatie.mapper.ClientMapper">
-
-
- <!-- 經過select 執行數據庫查詢 id:表示映射文件的sql, 將sql語句封裝到mappedStatement對象中,因此將id稱爲statement的id
- #{}: 表示一個佔位符,至關於jdbc中的? parameterType : 指定參數類型,好比指定爲int #{id} : 其中的id表示接入輸入的參數,參數名稱就是id,若是輸入的參數是簡單類型
- #{}中參數名能夠任意,能夠value或其餘名稱; resultType :指定sql輸出的結果的映射java對象類型,select指定的resultType表示將單條記錄映射成java對象 -->
-
- <select id="findClientById" parameterType="int" resultType="mybatis.po.FClient">
- select * from f_client where id=#{id}
- </select>
-
- <!-- 根據用戶名模糊查詢 resultType :指定的單條記錄所映射的java對象類型 #{} 表示佔位符 ${}:表示拼接sql串,將接收到的參數內容不加任何修飾拼接在sql中,使用${}拼接,引發sql注入
- ${value} :接入輸入參數的內容,若是傳入類型是簡單類型,${}簡單的 -->
- <select id="findClientByName" parameterType="java.lang.String"
- resultType="mybatis.po.FClient">
- select *from f_client where username like '%${value}%'
- </select>
-
-
- <select id="insertClient" parameterType="mybatis.po.FClient"
- resultType="java.lang.Integer">
- insert into
- f_client(id,username,client_certificate_no,born_date,family_register_address,now_address,contact_mode,urgency_contact_mode,create_date)
- values (#{id},
- #{username},#{client_certificate_no},#{born_date},#{family_register_address},#{now_address},#{contact_mode},#{urgency_contact_mode},#{create_data})
- </select>
-
-
- <delete id="deleteClient" parameterType="int">
- delete from f_client where id=#{id}
- </delete>
-
-
- <update id="updateClient" parameterType="mybatis.po.FClient">
-
- update f_client set
- username=#{username},client_certificate_no=#{client_certificate_no},born_date=#{born_date},family_register_address=#{family_register_address},now_address=#{now_address},contact_mode=#{contact_mode},urgency_contact_mode=#{urgency_contact_mode}
- where id=#{id}
-
- </update>
-
-
- </mapper>
(2)mapper接口
注意接口定義的和Mapper.xml對比下,看看mapper.xml的 規範!!
- package mybatie.mapper;
-
- import java.util.List;
-
- import mybatis.po.FClient;
-
-
-
-
-
-
-
-
- public interface ClientMapper {
-
- public FClient findClientById(int id) throws Exception;
-
- public void updateClient(FClient f) throws Exception;
-
- public void deleteClient(int id) throws Exception;
-
- public int insertClient(FClient f) throws Exception;
-
- public List<FClient> findClientByName(String name) throws Exception;
- }
(3)測試
- private SqlSessionFactory sqlfactory;
-
- @Before
- public void setUp() throws Exception {
- InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml");
- sqlfactory=new SqlSessionFactoryBuilder().build(is);
- }
-
- @Test
- public void testFindClientById() throws Exception {
- SqlSession session = sqlfactory.openSession();
- ClientMapper mapper = session.getMapper(ClientMapper.class);
- FClient fc = mapper.findClientById(1);
- System.out.println(fc);
- session.close();
- }
4.一些問題
(1)代理對象內部調用selectOne或 selectList
若是mapper方法返回單個pojo對象,代理對象內部經過selectOne查詢數據庫;
若是mapper方法返回集合對象,代理對象內部經過內部經過selectList查詢數據庫;
不然會報錯誤。
(2) mapper接口方法參數只能有一個是否影響系統開發
系統框架中,dao層的代碼是不是被業務層公用的,即便mapper接口只有一個參數,可使用包裝
類型pojo知足不一樣業務方法需求;
注意:持久層方法的參數能夠包裝類型,map,service方法中建議不要使用包裝類型,由於不利於
業務層的可擴展性。
1.背景
在上篇中咱們使用了MyBatis實現簡單的增刪改查,並無進行dao層的封裝,因此在這裏咱們進行dao層開發:
(1)傳統的jdbc dao層開發(寫dao接口,實現dao接口類)
(2)mapper代理方法 (只須要寫mapper接口類,至關於dao接口類)
在Mybatis操做的時候,咱們使用的是SqlSession 來進行數據庫操做,其中SqlSession的使用範圍:
經過SqlSessionFactoryBuilder建立SqlSessionFactory ,而SqlSession經過SqlSessionFactory 建立,因此使用單例模式管理SqlSessionFactory,未來使用mybatis和spring整合後,使用單例模式管理SqlSessionFactory;
SqlSession的做用是:
1)提供接口,不少操做數據庫的方法,如:selectOne ,selectList
2)線程不安全,在sqlSession實現類中除了有接口中的方法,還有數據域的屬性;
3)最佳應用的場合在方法體內,定義成局部變量使用。
2.原始dao開發實現
(1)dao接口
- package mybatie.dao;
-
- import mybatis.po.FClient;
-
-
-
-
-
-
-
-
-
- public interface ClientDao {
-
- FClient findClientById(int id) throws Exception;
-
- void updateClient(FClient f) throws Exception;
-
- void deleteClient(int id) throws Exception;
-
- void insertClient(FClient f) throws Exception;
-
- }
(2)實現dao接口
實現數據庫操做的幾個方法:
- package mybatie.dao;
-
- import mybatis.po.FClient;
- import oracle.net.aso.s;
-
- import org.apache.ibatis.session.SqlSession;
- import org.apache.ibatis.session.SqlSessionFactory;
-
- public class ClientDaoImp implements ClientDao {
-
- private SqlSessionFactory sqlSessionFactory;
-
- public ClientDaoImp(SqlSessionFactory sqlSessionFactory) {
- this.sqlSessionFactory = sqlSessionFactory;
- }
-
- @Override
- public FClient findClientById(int id) {
-
- SqlSession sqlSession = sqlSessionFactory.openSession();
- FClient c = sqlSession.selectOne("test.findClientById", id);
- sqlSession.close();
- return c;
- }
-
- @Override
- public void updateClient(FClient f) {
- SqlSession sqlSession=sqlSessionFactory.openSession();
- sqlSession.update("test.updateClient",f);
- sqlSession.commit();
- sqlSession.close();
- }
-
- @Override
- public void deleteClient(int id) {
- SqlSession session = sqlSessionFactory.openSession();
- session.delete("test.deleteClient", id);
- session.commit();
- session.close();
- }
-
- @Override
- public void insertClient(FClient f) {
- SqlSession session = sqlSessionFactory.openSession();
- session.insert("test.insertClient", f);
- session.commit();
- session.close();
- }
-
-
- }
(3)測試類
- public class TestClient {
-
- private SqlSessionFactory sqlSessionFactory;
-
- @Before
- public void setUp() throws Exception {
- InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml");
- sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
- }
-
- @Test
- public void test() {
- fail("Not yet implemented");
- }
-
- @Test
- public void findClientById() throws Exception {
-
- ClientDao clientDao = new ClientDaoImp(sqlSessionFactory);
- FClient c = clientDao.findClientById(1);
- System.out.println(c);
- }
-
- }
(4)原始的dao層遇到的問題
1)dao接口實現類方法中存在大量的模板方法,設想可否將這些代碼提取出來
2)調用sqlsession方法的時候將statement存在硬編碼
3)調用sqlsession的方法的時候,傳入參數爲Object 類型,及時傳入錯誤,也不會報錯
3.使用Mapper代理的方式實現
基本步驟爲 :
1)編寫mapper.xml映射文件
2)編寫Mapper接口,至關於dao接口
3)mybatis能夠自動生成mapper接口的實現類代理對象
(1)實現Mapper映射文件
mapper.xml 規範 :
1)namespace 等於mapper接口地址
2)mapper.Java 接口中的方法和mapper.xml中的statement 的id一致
3)mapper.java 接口中的方法的參數和mapper.xml中的statement 的paramterType類型一致
4)mapper.java 接口中的方法的返回值和mapper.xml中的statement的resultType類型一致
總結 :mapper.xml實現的規範,就是對SqlSession接口中的方法進行統一的生成
好比 :
- <?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="mybatie.mapper.ClientMapper">
-
-
- <!-- 經過select 執行數據庫查詢 id:表示映射文件的sql, 將sql語句封裝到mappedStatement對象中,因此將id稱爲statement的id
- #{}: 表示一個佔位符,至關於jdbc中的? parameterType : 指定參數類型,好比指定爲int #{id} : 其中的id表示接入輸入的參數,參數名稱就是id,若是輸入的參數是簡單類型
- #{}中參數名能夠任意,能夠value或其餘名稱; resultType :指定sql輸出的結果的映射java對象類型,select指定的resultType表示將單條記錄映射成java對象 -->
-
- <select id="findClientById" parameterType="int" resultType="mybatis.po.FClient">
- select * from f_client where id=#{id}
- </select>
-
- <!-- 根據用戶名模糊查詢 resultType :指定的單條記錄所映射的java對象類型 #{} 表示佔位符 ${}:表示拼接sql串,將接收到的參數內容不加任何修飾拼接在sql中,使用${}拼接,引發sql注入
- ${value} :接入輸入參數的內容,若是傳入類型是簡單類型,${}簡單的 -->
- <select id="findClientByName" parameterType="java.lang.String"
- resultType="mybatis.po.FClient">
- select *from f_client where username like '%${value}%'
- </select>
-
-
- <select id="insertClient" parameterType="mybatis.po.FClient"
- resultType="java.lang.Integer">
- insert into
- f_client(id,username,client_certificate_no,born_date,family_register_address,now_address,contact_mode,urgency_contact_mode,create_date)
- values (#{id},
- #{username},#{client_certificate_no},#{born_date},#{family_register_address},#{now_address},#{contact_mode},#{urgency_contact_mode},#{create_data})
- </select>
-
-
- <delete id="deleteClient" parameterType="int">
- delete from f_client where id=#{id}
- </delete>
-
-
- <update id="updateClient" parameterType="mybatis.po.FClient">
-
- update f_client set
- username=#{username},client_certificate_no=#{client_certificate_no},born_date=#{born_date},family_register_address=#{family_register_address},now_address=#{now_address},contact_mode=#{contact_mode},urgency_contact_mode=#{urgency_contact_mode}
- where id=#{id}
-
- </update>
-
-
- </mapper>
(2)mapper接口
注意接口定義的和Mapper.xml對比下,看看mapper.xml的 規範!!
- package mybatie.mapper;
-
- import java.util.List;
-
- import mybatis.po.FClient;
-
-
-
-
-
-
-
-
- public interface ClientMapper {
-
- public FClient findClientById(int id) throws Exception;
-
- public void updateClient(FClient f) throws Exception;
-
- public void deleteClient(int id) throws Exception;
-
- public int insertClient(FClient f) throws Exception;
-
- public List<FClient> findClientByName(String name) throws Exception;
- }
(3)測試
- private SqlSessionFactory sqlfactory;
-
- @Before
- public void setUp() throws Exception {
- InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml");
- sqlfactory=new SqlSessionFactoryBuilder().build(is);
- }
-
- @Test
- public void testFindClientById() throws Exception {
- SqlSession session = sqlfactory.openSession();
- ClientMapper mapper = session.getMapper(ClientMapper.class);
- FClient fc = mapper.findClientById(1);
- System.out.println(fc);
- session.close();
- }
4.一些問題
(1)代理對象內部調用selectOne或 selectList 若是mapper方法返回單個pojo對象,代理對象內部經過selectOne查詢數據庫; 若是mapper方法返回集合對象,代理對象內部經過內部經過selectList查詢數據庫; 不然會報錯誤。 (2) mapper接口方法參數只能有一個是否影響系統開發 系統框架中,dao層的代碼是不是被業務層公用的,即便mapper接口只有一個參數,可使用包裝 類型pojo知足不一樣業務方法需求; 注意:持久層方法的參數能夠包裝類型,map,service方法中建議不要使用包裝類型,由於不利於 業務層的可擴展性。