咱們今天先來簡單瞭解一下咱們持久層框架,mybatis的使用。並且如今的註解成爲趨勢,我主要說一下註解方向的使用吧(配置文件也會說)html
從使用角度只要是三個部分,mybatis-config.xml,mapper.xml,執行文件三個部分。java
mybatis-config.xml:mysql
主鍵標籤爲configuration成對出現的,而後是properties也就是咱們的配置,用於配置數據庫。settings聲明一些配置,好比打印sql語句等,後面會一個個去說。而後就是咱們的mappers,裏面包含多個mapper標籤,也就是對應咱們的mapper.xml文件,在這裏說一下一共有三種注入的方式,resource,class,url,resource是經過classpath配置的,若是你沒有把mapper放置在resources配置下面,須要在maven裏設置編譯,否則咱們的mapper.xml不會編譯到classpath裏,class經過類來注入mapper,url通常是遠程注入的。再就是咱們的typehandlers,能夠指定類型轉換的。咱們也能夠繼承BaseTypeHandler來重寫父類的方法來自定義類型轉換。sql
來一個我本身的簡單配置。數據庫
<?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="app.properties"> <property name="jdbc.driver" value="com.mysql.jdbc.Driver"/> </properties> <settings> <!-- 打印查詢語句 --> <setting name="logImpl" value="STDOUT_LOGGING"/> </settings> <environments default="${default.environment}"> <environment id="dev"> <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> <mappers> <mapper resource="mybatis/dao/StudentMapper.xml"/> <!-- <mapper class="com.tuling.mybatis.dao.UserMapper"></mapper>--> <!-- <mapper url="mybatis.dao.StudentDao"></mapper>--> </mappers> </configuration>
配置還要不少,後面源碼解析裏面會一點點來講明。apache
mapper.xml:緩存
這個文件就是咱們的編寫sql的文件了,裏面主要標籤就是select,insert,update,delete咱們的增刪改查標籤,再就是咱們的緩存設置(二級緩存)。下次博客主要說博客,源碼級的。
select裏包含咱們常見的id,resultType,resultMap,id用來指向咱們的接口文件的類名,resultType爲咱們mybatis自帶的類型,也能夠是咱們設置的對象Bean,resultMap是咱們本身定義的返回類型。這裏可能會有疑問,一堆多應該怎麼來配置?
association咱們能夠用他來指定一對多的配置,同時能夠配置懶查詢仍是及時查詢的。咱們來看一個實例,咱們現有學生表格分數表,學生對應不少科目的分數,咱們來看一下。先來一段測試代碼。
<?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> <environments default="development"> <environment id="development"> <transactionManager type="JDBC"/> <dataSource type="POOLED"> <property name="driver" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost/jdbc"/> <property name="username" value="root"/> <property name="password" value="root"/> </dataSource> </environment> </environments> <mappers> <!-- <mapper resource="mybatis/dao/StudentMapper.xml"/>--> <mapper class="mybatis.dao.StudentMapper"></mapper> <mapper class="mybatis.dao.ScoreMapper"></mapper> </mappers> </configuration>
<?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="mybatis.dao.StudentMapper"> <select id="selectUser" resultType="mybatis.bean.StudentBean"> select * from stu where id = #{id} </select> </mapper>
package mybatis.bean; import java.io.Serializable; public class StudentBean implements Serializable { private static final long serialVersionUID = 2193971369901198487L; private int id; private String name; public int getId() { return id; } public void setId(int id) { this.id = id; } @Override public String toString() { return "selectUser{" + "id=" + id + "name=" + name + '}'; } }
package mybatis; import mybatis.bean.ScoreBean; import mybatis.bean.StudentBean; import mybatis.dao.ScoreMapper; import mybatis.dao.StudentMapper; 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.Test; import java.io.IOException; import java.io.InputStream; import java.util.List; public class Test1 { @Test public void test() throws IOException { String resource = "mybatis-config.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); SqlSession session = sqlSessionFactory.openSession(); StudentMapper mapper = session.getMapper(StudentMapper.class); StudentBean result = mapper.selectUser(1); System.out.println(result); } }
這樣咱們查詢到咱們的學生信息,可是還未包含咱們的分數。咱們來改造一下。session
<?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="mybatis.dao.StudentMapper"> <resultMap id="studentMap" type="mybatis.bean.StudentBean"> <id property="id" column="id"></id> <collection property="scoreBean" ofType="mybatis.bean.ScoreBean"> <id property="id" column="sid"></id> <!-- <result property="subject" column="subject"></result>--> <result property="score" column="score"></result> <result property="studentId" column="studentId"></result> </collection> </resultMap> <select id="selectUser" resultMap="studentMap"> select t.id,t.name,t.address,t.num,s.id as sid,s.subject,s.score,s.studentId as studentId from student t left join score s on s.studentId = t.id where t.id = #{id} </select> </mapper>
這樣就能夠查詢到對應關係了。須要注意的事子表若是和主表重名,必定給子表起一個別名,並且子表的每一項須要寫result,否則沒有結果的,可是還不是很好,原本是一個對象一個集合,如今直接變成集合了,咱們再來改改。mybatis
<?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="mybatis.dao.StudentMapper"> <resultMap id="studentMap" type="mybatis.bean.StudentBean"> <id property="id" column="id"></id> <collection property="scoreBean" javaType="java.util.ArrayList" ofType="mybatis.bean.ScoreBean" select="mybatis.dao.ScoreMapper.selectScoreByStudentId" column="{studentId=id}"> </collection> </resultMap> <select id="selectUser" resultMap="studentMap"> select * from student t where t.id = #{id} </select> </mapper>
這個比較好用,可是切記,不是懶加載,不是懶加載,須要注意的是collection的property指定咱們實體類Bean類中集合的名字。ofType是指向咱們一對多中多方的實體Bean,select指定咱們對應的第二句sql語句,也就是咱們的子查詢語句。app
column="{studentId=id}" 中studentId是咱們的子查詢參數名,id是和咱們主表的對應關係。就是說,咱們要子表的什麼參數等於咱們的主表的哪一個參數傳遞過去。
接下來就是咱們簡單的一對一了(也能夠當作一對多,可是沒啥卵用的多對一,項目經理讓從多往一查的時候,請你吐他。。。)咱們來看我一下個人配置
<?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="mybatis.dao.ScoreMapper"> <resultMap id="scoreMap" type="mybatis.bean.ScoreBean"> <id property="id" column="id"></id> <result property="subject" column="subject"></result> <result property="score" column="score"></result> <association property="studentBean" javaType="mybatis.bean.StudentBean" column="studentId"> <id property="id" column="id"></id> <result property="name" column="name"></result> <result property="address" column="address"></result> <result property="num" column="num"></result> </association> </resultMap> <select id="selectScoreByStudentId" resultMap="scoreMap"> select * from score s left join student t on s.studentId = t.id where studentId = #{studentId} </select> </mapper>
這個比較簡單,就不說了,就是寫了一個resultMap。咱們來看一下兩條sql的怎麼來進行。
<?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="mybatis.dao.ScoreMapper"> <resultMap id="scoreMap" type="mybatis.bean.ScoreBean"> <id property="id" column="id"></id> <result property="subject" column="subject"></result> <result property="score" column="score"></result> <association property="studentBean" javaType="mybatis.bean.StudentBean" select="mybatis.dao.StudentMapper.selectUser" column="studentId"> <id property="id" column="id"></id> <result property="name" column="name"></result> <result property="address" column="address"></result> <result property="num" column="num"></result> </association> </resultMap> <select id="selectScoreByStudentId" resultMap="scoreMap"> select * from score where studentId = #{studentId} </select> </mapper>
簡單解釋一下,其實和上面collection差很少的,select指定查詢sql位置,column執行傳遞過去的參數。
其他的insert,update,delete都差很少,我這裏就放在一塊兒說了。
id | 命名空間中的惟一標識符,可被用來表明這條語句。 |
parameterType | 將要傳入語句的參數的徹底限定類名或別名。這個屬性是可選的,由於 MyBatis 能夠經過類型處理器推斷出具體傳入語句的參數,默認值爲未設置(unset)。 |
flushCache | 將其設置爲 true 後,只要語句被調用,都會致使本地緩存和二級緩存被清空,默認值:true(對於 insert、update 和 delete 語句)。 |
timeout | 這個設置是在拋出異常以前,驅動程序等待數據庫返回請求結果的秒數。默認值爲未設置(unset)(依賴驅動)。 |
statementType | STATEMENT,PREPARED 或 CALLABLE 的一個。這會讓 MyBatis 分別使用 Statement,PreparedStatement 或 CallableStatement,默認值:PREPARED。 |
useGeneratedKeys | (僅對 insert 和 update 有用)這會令 MyBatis 使用 JDBC 的 getGeneratedKeys 方法來取出由數據庫內部生成的主鍵(好比:像 MySQL 和 SQL Server 這樣的關係數據庫管理系統的自動遞增字段),默認值:false。 |
keyProperty | (僅對 insert 和 update 有用)惟一標記一個屬性,MyBatis 會經過 getGeneratedKeys 的返回值或者經過 insert 語句的 selectKey 子元素設置它的鍵值,默認值:未設置(unset)。若是但願獲得多個生成的列,也能夠是逗號分隔的屬性名稱列表。 |
keyColumn | (僅對 insert 和 update 有用)經過生成的鍵值設置表中的列名,這個設置僅在某些數據庫(像 PostgreSQL)是必須的,當主鍵列不是表中的第一列的時候須要設置。若是但願使用多個生成的列,也能夠設置爲逗號分隔的屬性名稱列表。 |
databaseId | 若是配置了數據庫廠商標識(databaseIdProvider),MyBatis 會加載全部的不帶 databaseId 或匹配當前 databaseId 的語句;若是帶或者不帶的語句都有,則不帶的會被忽略。 |
useGeneratedKeys=」true」這個至關來講配置的仍是比較多的,也就是咱們新增成功後,咱們的對象能夠返回咱們插入成功的主鍵ID。
拼裝sql:
#{}:是預處理,也是一個佔位符的方式來執行sql,${}是sql的拼接,咱們其實能夠這樣來寫。
@Select("select * from ${}_sys_log where id=#{condition}") public SystemLog findSystemLog(String year,String condition);
也就是說,咱們對日誌sys_log表作了分庫分表,按照年份來區分的表,這時咱們能夠採用sql拼接的方式來作。
但盡力不要用拼接的方式來作,後面我將動態sql會說具體怎麼來實現。${}容易被sql注入。因此咱們盡力還用佔位符的方式來處理咱們的SQL。
而後就是咱們的插件集成,還有緩存,下次博客咱們來講說緩存吧。
忘記了,學mybatis的使用,推薦一個網站https://mybatis.org/mybatis-3/zh/index.html 上面挺全的(沒有源碼解析,源碼還得回來看我博客)。
最進弄了一個公衆號,小菜技術,歡迎你們的加入
原文出處:https://www.cnblogs.com/cxiaocai/p/11520734.html