public class MybatisTest { public static void main(String[] args) throws Exception{ //1.讀取配置文件 InputStream in = Resources.getResourceAsStream("SqlMapConfig.xml"); //2.建立SqlSessionFactory工廠 SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder(); SqlSessionFactory factory = builder.build(in); //3.使用工廠生產SqlSession對象 SqlSession session = factory.openSession(); //4.使用SqlSession建立Dao的代理對象 IUserDao userDao = session.getMapper(IUserDao.class); //5.使用代理對象執行方法 List<User> users = userDao.findAll(); for(User user : users) { System.out.println(user); } //6.釋放資源 session.close(); in.close(); } }
在讀取文件時,一般有兩種方法,一種是採用絕對路徑,另外一種是採用相對路徑。若是採用絕對路徑,其缺點爲不易遷移和部署,在開發時若是咱們路徑爲「D:\SqlMapConfig.xml」,部署到服務器時,可能服務器上沒有D盤。相對路徑的缺點就在於,若是項目爲Web工程,部署以後src目錄就不存在了。所以在讀取配置文件時,只有兩種方法:html
1.使用類加載器:只能讀取類路徑的配置文件。java
2.使用SeverletContext對象的getPath()方法。mysql
在建立工廠時,mybatis使用了構建者模式,builder就是構建者,把對象的建立細節隱藏,使用戶直接調用方法即可得到對象。sql
生產SqlSession對象時使用了工廠模式,能夠下降類間的依賴關係,便於以後對項目進行修改。數據庫
建立DAO接口實現類的代理對象實現了使用了代理模式,這樣就不須要本身寫DAO實現類。設計模式
1.註冊驅動,獲取connection對象數組
2.建立數據庫的執行sql的預處理對象服務器
3.執行sql語句session
4.封裝查詢結果mybatis
5.釋放資源
public class JDBCTest { public static void main(String[] args) { JDBCTest test=new JDBCTest(); test.firstJDBC(); } public void firstJDBC(){ Connection connection=null; PrepareStatement prepareStatement=null; ResultSet resultSet=null; try { //1.register,註冊驅動 DriverManager.registerDriver(new Driver()); //2.獲得數據鏈接。url格式:jdbc:mysql://主機IP:端口號/數據庫名?user=用戶名&password=密碼 //由於MySQL安裝時,端口號默認設置的是3306,因此都是3306 String url="jdbc:mysql://localhost:3306/sport?user=root&password=12345678"; connection=DriverManager.getConnection(url); //3.獲得數據庫的執行sql對象 String sql="select * from player"; //SQL查詢語句 prepareStatement=connection.prepareStatement(); //4.執行語句 resultSet=prepareStatement.executeQuery(); while(resultSet.next()){ //取出查詢的信息 String name=resultSet.getString("player_name"); int age=resultSet.getInt("player_age"); int score=resultSet.getInt("player_score"); System.out.println("name="+name+",age="+age+",score="+score); } } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); }finally { //5.關閉資源 if(connection!=null){ try { connection.close(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } if(prepareStatement!=null){ try { prepareStatement.close(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } if(resultSet!=null){ try { resultSet.close(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } }
<!-- mybatis的主配置文件 --> <configuration> <!-- 配置環境 --> <environments default="mysql"> <!-- 配置mysql的環境 --> <environment id="mysql"> <!-- 配置事務的類型 --> <transactionManager type="JDBC"></transactionManager> <!-- 配置數據源(鏈接池) --> <dataSource type="POOLED"> <!-- 配置鏈接數據庫的四個基本信息 --> <property name="driver" value="com.mysql.cj.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/mybatis"/> <property name="username" value="root"/> <property name="password" value="12345678"/> </dataSource> </environment> </environments> <!-- 指定映射配置文件的位置,映射配置文件指的是每一個dao獨立的配置文件 --> <mappers> <mapper resource="dao/IUserDao.xml" /> </mappers> </configuration>
1.建立connection對象。經過主被配置文件SqlMapConfig.xml,咱們能夠得到鏈接數據庫的信息(驅動、路徑、用戶名和密碼)以及映射配置文件的位置。經過鏈接數據庫的信息,咱們能夠構建connection對象。
<mapper namespace="dao.IUserDao"> <!-- 配置查詢全部 --> <select id="findAll" resultType="domain.User"> select * from user; </select> </mapper>
2.建立prepareStatement對象。經過映射配置文件的信息,咱們能夠得到執行的SQL語句和封裝的實體類全限定類名,就能夠建立prepareStatement對象。mybatis經過dom4j技術來解析xml文件獲取上述信息。
3.存儲解析結果。在獲取相關信息中後,mybatis須要將執行的SQL語句和封裝結果的實體類全限定類名組合起來定義成一個Mapper對象,每個Mapper對象對應一個完整String類型的id(namespace+「.」+id)。例如本項目中的SQL語句爲「select * from user;」,封裝結果的實體類全限定類名爲「domain.user」,完整的id爲"dao.IUserDao.findAll",這些都是String類型的字段。
4.利用反射技術封裝。建立prePareStatement對象以後,經過resultSet = prepareStatement.executeQuery();語句咱們能夠得到查詢結果集,在對查詢結果集進行封裝時。咱們經過完整的id(即封裝結果的全限定類名),利用反射技術(Class.forName("domain.User").getDeclaredConstructor().newInstance();)便可進行封裝。因爲實體類的屬性和數據庫表中的列名一致,能夠把表的列名看成是實體類的屬性名稱,而後利用反射技術來根據名稱獲取每一個屬性,並把值賦進去。反射參考連接。
//MybatisTest.class IUserDao userDao = session.getMapper(IUserDao.class); //DefaultSqlSession.class public <T> T getMapper(Class<T> type) { return this.configuration.getMapper(type, this); } //Configuration.class public <T> T getMapper(Class<T> type, SqlSession sqlSession) { return this.mapperRegistry.getMapper(type, sqlSession); } //MapperRegistry.class public <T> T getMapper(Class<T> type, SqlSession sqlSession) { MapperProxyFactory<T> mapperProxyFactory = (MapperProxyFactory)this.knownMappers.get(type); if (mapperProxyFactory == null) { throw new BindingException("Type " + type + " is not known to the MapperRegistry."); } else { try { return mapperProxyFactory.newInstance(sqlSession); } catch (Exception var5) { throw new BindingException("Error getting mapper instance. Cause: " + var5, var5); } } } //MapperProxyFactory.class public T newInstance(SqlSession sqlSession) { MapperProxy<T> mapperProxy = new MapperProxy(sqlSession, this.mapperInterface, this.methodCache); return this.newInstance(mapperProxy); } protected T newInstance(MapperProxy<T> mapperProxy) { return Proxy.newProxyInstance(this.mapperInterface.getClassLoader(), new Class[]{this.mapperInterface}, mapperProxy); } //Proxy.class public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) { Objects.requireNonNull(h); final Class<?> caller = System.getSecurityManager() == null ? null : Reflection.getCallerClass(); /* * Look up or generate the designated proxy class and its constructor. */ Constructor<?> cons = getProxyConstructor(caller, loader, interfaces); return newProxyInstance(caller, cons, h); }
上述是MybatisTest類中,getMapper()的調用層級。能夠看到最終調用的方法是public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h),這個方法有三個參數,分別是:
1.類加載器loader:使用和被代理對象相同的類加載器
2.代理對象要實現的接口字節碼數組interfaces:和被代理對象實現的是相同的接口
3.代理方式h:就是加強的方法,實際上就是一個InvocationHandler接口的實現類,在實現類中調用selectList方法(查詢全部方法)。
mybatis入門案例,能夠參考個人上一篇博客:mybatis入門實例