mybatis自己学习的一些总结
以前一直在使用spring的JDBCTEMPLATE和hibernate做項(xiàng)目;兩個(gè)都還不錯(cuò),spring的jdbctemplate用起來比較麻煩,雖然很簡單。而hibernate呢,用起來很好用,很方便,但是很多規(guī)矩,規(guī)則還有方法到現(xiàn)在都還是入門階段。所以我就學(xué)習(xí)了一下mybatis來充實(shí)一下自己。
mybatis的學(xué)習(xí)(我也只是入門),我參考了這個(gè)博客地址----大神的總結(jié),通過對(duì)他的博客的一些學(xué)習(xí),我做了一些自己的總結(jié),所以下面的一些內(nèi)容都是自己在學(xué)習(xí)的時(shí)候的一些東西,也是參考著大神的博客來做的。當(dāng)然做了一些錯(cuò)誤的修改和自己理解的實(shí)現(xiàn)。
mybatis實(shí)戰(zhàn)教程(mybatis in action)之一:開發(fā)環(huán)境搭建
1.關(guān)于數(shù)據(jù)庫表的創(chuàng)建,參見大神的博文,這里就不再多說;
2.在user_src下的Configuration.xml內(nèi)容解讀:
<?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><!--這里給我們要使用的數(shù)據(jù)實(shí)體類設(shè)置一個(gè)在mybatis中使用的別名,以后在mybatis中直接使用他們的別名來映射到對(duì)應(yīng)的實(shí)體對(duì)象中 --><typeAliases><typeAlias alias="User" type="com.mpc.mybaits.model.User" /><typeAlias alias="Article" type="com.mpc.mybaits.model.Article" /></typeAliases><!-- 指定mybatis中使用的數(shù)據(jù)庫環(huán)境,默認(rèn)使用development,其中development使用的是JDBC來鏈接數(shù)據(jù)庫,數(shù)據(jù)庫是mysql --><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://127.0.0.1:3306/mybaits" /><property name="username" value="root" /><property name="password" value="root" /></dataSource></environment></environments><!--這里使用mapper來指定相應(yīng)的實(shí)體類的處理方法,(這些mapper就是處理數(shù)據(jù)的增刪改查方法的xml集合,在這里面你可以寫任何的查詢方法 ,在這些xml中我們可以使用typeAliases中申明的對(duì)象來包裝我們的查詢結(jié)果,傳入查詢參數(shù)), 這寫mapper都是可以寫任意的查詢方法的,(任意的表,任意的查詢語句)但是在開發(fā)中我們?yōu)槊恳粋€(gè)類指定一個(gè)mapper文件,這樣是為了方便管理和項(xiàng)目的開發(fā) ;總之就是一點(diǎn):mapper和typeAliases是沒有任何對(duì)應(yīng)關(guān)系的,只是為了開發(fā)方便才會(huì)有什么Usermapper、Articlemapper這些分類 --><mappers><mapper resource="com/mpc/mybaits/model/User.xml" /></mappers> </configuration>3.具體User類的實(shí)現(xiàn)參照大神的博文,我這里就不獻(xiàn)丑了。只說一句:這個(gè)類是用在typeAliases那里的;
4.和User類在同一個(gè)包下的User.xml,這個(gè)User.xml是用在mappers中的,它的作用是提供數(shù)據(jù)庫增刪改查的方法。
<?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"> <!-- 這里我們要通過xml來進(jìn)行數(shù)據(jù)庫的操作,所以我餓美女給這個(gè)mapper指定一個(gè)唯一的空間名稱, --> <mapper namespace="com.mpc.mybaits.model.UserMapper"><!-- 這里定一個(gè)select方法,從user表中查找指定id的數(shù)據(jù),然后用 resultType="User" User類來進(jìn)行包裝 --><!-- id是這個(gè)方法的唯一標(biāo)識(shí),通過id來調(diào)用這個(gè)方法,parameterType是傳入的參數(shù)的類型,這里是整形。通過#{xxx}來獲得傳入的參數(shù)--><select id="selectUserByID" parameterType="int" resultType="User">select * from `user` where id = #{id}</select></mapper> 5.建立測試類
package com.mpc.test;import java.io.Reader;import lombok.Getter;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.Assert; import org.junit.Test;import com.mpc.mybaits.model.User;public class Test1 {private static @Getter SqlSessionFactory sqlSessionFactory;private static Reader reader;static {// 在一個(gè)static塊中處理我們的相關(guān)初始化操作,這里做的操作是用Configuration.xml中的配置信息來初始化一個(gè)mybatis使用的sqlSessionFactorytry {reader = Resources.getResourceAsReader("Configuration.xml");sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);} catch (Exception e) {e.printStackTrace();}}@Testpublic void test() {SqlSession session = sqlSessionFactory.openSession();// 獲得sessionAssert.assertNotNull(session);// 斷言session不為空try {// 通過session來調(diào)用com.mpc.mybaits.model.UserMapper.selectUserByID方法,傳入的參數(shù)是1// 其中com.mpc.mybaits.model.UserMapper是我們的mapper的命名空間。selectUserByID是方法的idUser user = (User) session.selectOne("com.mpc.mybaits.model.UserMapper.selectUserByID", 1);Assert.assertNotNull(user);// 斷言u(píng)ser不為空Assert.assertEquals("User(id=1, userName=summer, userAge=100, userAddress=shanghai,pudong)",user.toString());// 對(duì)user內(nèi)容的斷言} finally {session.close();// 最后要關(guān)閉session}}// public static void main(String[] args) {// SqlSession session = sqlSessionFactory.openSession();// try {// User user = (User) session.selectOne(// "com.mpc.mybaits.model.UserMapper.selectUserByID", 1);// System.out.println(user.toString());// } finally {// session.close();// }// } }
測試結(jié)果:
mybatis實(shí)戰(zhàn)教程(mybatis in action)之二:以接口的方式編程
使用接口編程的方式可以提高我們?cè)诜椒ㄖ惺褂胢ybatis的效率,減少很多不必要錯(cuò)誤,讓我們不用總是查來查去,思來想去。。
1.在inter包中定義我們的接口
package com.mpc.mybaits.inter;import java.util.List; import java.util.Map;import org.apache.ibatis.annotations.Param;import com.mpc.mybaits.model.Article; import com.mpc.mybaits.model.User; import com.mpc.mybaits.utils.PageInfo;/*** @author Administrator**/ public interface IUserOperation {/*** 方法的名稱必須與User。xml中的 select 的id 對(duì)應(yīng)(<select id="selectUserByID")* * @param id* @return*/public User selectUserByID(int id);} 2.修改user.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="ccom.mpc.mybaits.inter.IUserOperation"><!-- 這里定一個(gè)select方法,從user表中查找指定id的數(shù)據(jù),然后用 resultType="User" User類來進(jìn)行包裝 --><!-- id是這個(gè)方法的唯一標(biāo)識(shí),通過id來調(diào)用這個(gè)方法,parameterType是傳入的參數(shù)的類型,這里是整形。通過#{xxx}來獲得傳入的參數(shù)--><select id="selectUserByID" parameterType="int" resultType="User">select * from `user` where id = #{id}</select></mapper> 3.測試方法
package com.mpc.test;import java.io.Reader;import lombok.Getter;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 com.mpc.mybaits.inter.IUserOperation; import com.mpc.mybaits.model.User;public class Test2 {private static @Getter SqlSessionFactory sqlSessionFactory;private static Reader reader;static {try {reader = Resources.getResourceAsReader("Configuration.xml");sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);} catch (Exception e) {e.printStackTrace();}}@Testpublic void test() {new Test1();SqlSession session = sqlSessionFactory.openSession();try {IUserOperation iUserOperation = session.getMapper(IUserOperation.class);//通過session來獲得IUserOperation的實(shí)例對(duì)象User user = iUserOperation.selectUserByID(1);//直接調(diào)用接口中 的方法就可以了System.out.println(user.toString());} finally {session.close();}} }
測試結(jié)果:
mybatis實(shí)戰(zhàn)教程(mybatis in action)之三:實(shí)現(xiàn)數(shù)據(jù)的增刪改查
*用list來返回多個(gè)查詢結(jié)果,要使用list來返回多個(gè)查詢結(jié)果,那么我們要定義自己的resultMap;
在User.xml中加入自己定義的resultMap;
<!-- 為了返回list 類型而定義的returnMap --><resultMap type="User" id="resultListUser"><id column="id" property="id" /><result column="userName" property="userName" /><result column="userAge" property="userAge" /><result column="userAddress" property="userAddress" /></resultMap>
這是大神的博文中提到的,但是根據(jù)我自己的實(shí)踐···這里完全沒有必要使用resultMap,使用resultType就可以達(dá)到目的,所以我在user.xml中使用如下語句也是可以的:
<select id="selectUsers" parameterType="string" resultType="User">select * from user where userName like #{userName}</select>當(dāng)然按照大神的博文中記載的方式也是可以的--》在User.xml中加入新的查詢語句; <!-- 返回list 的select 語句,注意 resultMap 的值是指向前面定義好的 --><select id="selectUsers" parameterType="string" resultMap="resultListUser">select * from user where userName like #{userName}</select>
個(gè)人理解,resultMap就是我們自己定義的一種返回結(jié)果的包裝,在從表中查處數(shù)據(jù)口,MyBatis把所有的查詢結(jié)果都放在一個(gè)map中,都是用key-value的形式存放的,如果指定的是resultType,那么Mybatis會(huì)為我們進(jìn)行封裝,指定的為resultMap的話,Mabatis會(huì)按照resultMap定義的格式來進(jìn)行封裝而已-----------;
測試結(jié)果:
*使用mybatis來增加數(shù)據(jù)
在User.xml中添加如下代碼:
<!--執(zhí)行增加操作的SQL語句。id和parameterType 分別與IUserOperation接口中的addUser方法的名字和 參數(shù)類型一致。以#{name}的形式引用Student參數(shù) 的name屬性,MyBatis將使用反射讀取Student參數(shù) 的此屬性。#{name}中name大小寫敏感。引用其他 的gender等屬性與此一致。seGeneratedKeys設(shè)置 為"true"表明要MyBatis獲取由數(shù)據(jù)庫自動(dòng)生成的主 鍵;keyProperty="id"指定把獲取到的主鍵值注入 到Student的id屬性 --><insert id="addUser" parameterType="User" useGeneratedKeys="true"keyProperty="id">insert into user(userName,userAge,userAddress)values(#{userName},#{userAge},#{userAddress})</insert>在IUserOperation接口中加入addUser這個(gè)id所對(duì)應(yīng)的接口方法public void addUser(User user);
Mybatis在接受到user對(duì)象以后,會(huì)把user的屬性都封裝到一個(gè)map中,key是user的屬性名,value就是user的屬性值了。所在通過#{屬性名}在user.xml中就能取得傳入的user的屬性值。
測試方法:
package com.mpc.test;import java.io.Reader;import lombok.Getter;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 com.mpc.mybaits.inter.IUserOperation; import com.mpc.mybaits.model.User;public class Test3 {private static @Getter SqlSessionFactory sqlSessionFactory;private static Reader reader;static {try {reader = Resources.getResourceAsReader("Configuration.xml");sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);} catch (Exception e) {e.printStackTrace();}}public static void main(String[] args) {User user = new User();user.setUserAddress("人民廣場123");user.setUserName("飛鳥123");user.setUserAge("80123");SqlSession session = sqlSessionFactory.openSession();try {IUserOperation iUserOperation = session.getMapper(IUserOperation.class);iUserOperation.addUser(user);session.commit();// 必須的,不然的話是保存不到數(shù)據(jù)庫中的System.out.println("添加了用戶,當(dāng)前用戶的id為" + user.getId());} finally {session.close();}} }測試結(jié)果:
*使用mybatis來更新數(shù)據(jù)
在User.xml中添加如下代碼
<update id="updateUser" parameterType="User">update user setuserName=#{userName},userAge=#{userAge},userAddress=#{userAddress}where id=#{id}</update>在IUserOperation中添加對(duì)應(yīng)的接口方法 public void updateUser(User user);
*mybatis刪除數(shù)據(jù)
在User.xml中添加如下代碼
<delete id="deleteUser" parameterType="int">delete from user whereid=#{id}</delete>在IUserOperaiton中添加對(duì)應(yīng)的接口方法: public void deleteUser(int id);測試方法: package com.mpc.test;import java.io.Reader;import lombok.Getter;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 com.mpc.mybaits.inter.IUserOperation; import com.mpc.mybaits.model.User;public class TestDelete {private static @Getter SqlSessionFactory sqlSessionFactory;private static Reader reader;static {try {reader = Resources.getResourceAsReader("Configuration.xml");sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);} catch (Exception e) {e.printStackTrace();}}public static void main(String[] args) {SqlSession session = sqlSessionFactory.openSession();try {IUserOperation iUserOperation = session.getMapper(IUserOperation.class);User user = iUserOperation.selectUserByID(4);iUserOperation.deleteUser(6);session.commit();// 必須的,不然的話是保存不到數(shù)據(jù)庫中的System.out.println("刪除了用戶,當(dāng)前用戶的id為" + user.getId());} finally {session.close();}} }
mybatis實(shí)戰(zhàn)教程(mybatis in action)之四:實(shí)現(xiàn)關(guān)聯(lián)數(shù)據(jù)的查詢
1.article表和實(shí)體的創(chuàng)建參加大神的博文,這里我就不寫了。
2.在User.xml中添加如下代碼
<!-- User 聯(lián)合文章進(jìn)行查詢 方法之一的配置 (多對(duì)一的方式) --><resultMap id="resultUserArticleList" type="Article"><id property="id" column="aid" /><result property="title" column="title" /><result property="content" column="content" /><association property="user" javaType="User"><id property="id" column="id" /><result property="userName" column="userName" /><result property="userAddress" column="userAddress" /><result property="userAge" column="userAge" /></association><!-- <association property="user" javaType="User" resultMap="resultListUser" /> --></resultMap>這里要使用到resultMap,因?yàn)槲覀兊臄?shù)據(jù)庫中的表結(jié)構(gòu)和我們自己定義的類的字段是不對(duì)應(yīng)的,通過聯(lián)合查詢以后,mybatis并不知道要用怎樣的映射關(guān)系來專配,所以我們?cè)谶@里自己定義。
在User.xml中加入查詢代碼
<select id="getUserArticles" parameterType="int"resultMap="resultUserArticleList">select user.id,user.userName,user.userAddress,user.userAge,article.idaid,article.title,article.content from user,articlewhereuser.id=article.userid and user.id=#{id}</select> 3.在IUserOperation中加入相應(yīng)的接口方法
public List<Article> getUserArticles(int userid); 4.測試方法
package com.mpc.test;import java.io.Reader; import java.util.List;import lombok.Getter;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 com.mpc.mybaits.inter.IUserOperation; import com.mpc.mybaits.model.Article; import com.mpc.mybaits.model.User;public class Test5 {private static @Getter SqlSessionFactory sqlSessionFactory;private static Reader reader;static {try {reader = Resources.getResourceAsReader("Configuration.xml");sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);} catch (Exception e) {e.printStackTrace();}}public static void main(String[] args) {SqlSession session = sqlSessionFactory.openSession();try {IUserOperation iUserOperation = session.getMapper(IUserOperation.class);List<Article> articles = iUserOperation.getUserArticles(1);System.out.println(articles.size());for (Article article : articles) {System.out.println(article.getUser().toString());System.out.println(article.getTitle() + ":"+ article.getContent() + ":作者是:"+ article.getUser().getUserName() + ":地址:"+ article.getUser().getUserAddress());}} finally {session.close();}} } 5.測試結(jié)果
也可以在已經(jīng)定義好user的resultMap的情況下,在association處直接使用
mybatis實(shí)戰(zhàn)教程(mybatis in action)之五:與spring3集成
mybatis實(shí)戰(zhàn)教程(mybatis in action)之六:與Spring MVC 的集成
mybatis SqlSessionDaoSupport的使用
在大神的博文中,這三個(gè)是分開寫的,這里我就整合到一起了,使用spring,一般也會(huì)用springmvc。然后SqlSessionDaoSupport這個(gè)的話,我覺得沒必要去在乎,可以直接實(shí)現(xiàn)dao就可以了,具體實(shí)現(xiàn)如下:
具體的項(xiàng)目結(jié)構(gòu)如下圖所示:
1.修改web.xml來進(jìn)行spring和pringmvc的配置:
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0"><!-- log4j配置文件 --><context-param><param-name>log4jConfigLocation</param-name><param-value>classpath:/config/log4j.properties</param-value></context-param><!-- Spring的log4j監(jiān)聽器 --><listener><listener-class>org.springframework.web.util.Log4jConfigListener</listener-class></listener><!--配置參數(shù) 和具體項(xiàng)目沒有關(guān)系 在容器初始化項(xiàng)目還沒有啟動(dòng)執(zhí)行--><context-param><param-name>contextConfigLocation</param-name><param-value>classpath:/config/*.xml</param-value></context-param><!-- 維護(hù)ioc --><listener><listener-class>org.springframework.web.context.ContextLoaderListener</listener-class></listener><!-- 可以使用RequestContextHolder.currentRequestAttributes() 獲取到請(qǐng)求的attr --><listener><listener-class>org.springframework.web.context.request.RequestContextListener</listener-class></listener><!-- 前端核心分發(fā)器 --><servlet><servlet-name>dispatcher</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><!--業(yè)務(wù)控制器配置文件 --><init-param><param-name>contextConfigLocation</param-name><param-value>classpath:/config/spring-mvc-servlet.xml</param-value></init-param><load-on-startup>2</load-on-startup></servlet><servlet-mapping><servlet-name>dispatcher</servlet-name><!-- <url-pattern>*.do</url-pattern>--><!-- 配置為/ 不帶文件后綴,會(huì)造成其它靜態(tài)文件(js,css等)不能訪問。如配為*.do,則不影響靜態(tài)文件的訪問 --><url-pattern>/</url-pattern></servlet-mapping><!-- pushlet 推送 <servlet><servlet-name>pushlet</servlet-name><servlet-class>nl.justobjects.pushlet.servlet.Pushlet</servlet-class><load-on-startup>3</load-on-startup></servlet><servlet-mapping><servlet-name>pushlet</servlet-name><url-pattern>/pushlet.srv</url-pattern></servlet-mapping>--><!-- 字符集 過濾器 --><filter><filter-name>CharacterEncodingFilter</filter-name><filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class><init-param><param-name>encoding</param-name><param-value>UTF-8</param-value></init-param><init-param><param-name>forceEncoding</param-name><param-value>true</param-value></init-param></filter><filter-mapping><filter-name>CharacterEncodingFilter</filter-name><url-pattern>/*</url-pattern></filter-mapping><session-config><session-timeout>30</session-timeout></session-config><error-page><error-code>500</error-code><location>/500.html</location></error-page><error-page><error-code>404</error-code><location>/404.html</location></error-page></web-app>2.配置config包下的applicationContext.xml的內(nèi)容,這個(gè)xml文件包含了所有關(guān)于spring的配置。 <beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"xmlns:context="http://www.springframework.org/schema/context"xmlns:util="http://www.springframework.org/schema/util" xmlns:jee="http://www.springframework.org/schema/jee"xmlns:tx="http://www.springframework.org/schema/tx" xmlns:mvc="http://www.springframework.org/schema/mvc"xmlns:aop="http://www.springframework.org/schema/aop"xsi:schemaLocation="http://www.springframework.org/schema/utilhttp://www.springframework.org/schema/util/spring-util-3.0.xsdhttp://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsdhttp://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsdhttp://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.0.xsdhttp://www.springframework.org/schema/mvchttp://www.springframework.org/schema/mvc/spring-mvc-3.0.xsdhttp://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd"default-lazy-init="false"><!-- 加載properties文件到spring中,方便在spring中使用 --><bean id="propertyConfigurer"class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"><property name="locations"><list><value>classpath:/config/jdbc.properties</value></list></property></bean><!-- 使用jdbc來鏈接數(shù)據(jù)庫,創(chuàng)建數(shù)據(jù)源 --><bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"destroy-method="close"><property name="driverClassName" value="${connection.driverClassName}" /><property name="url" value="${connection.url}" /><property name="username" value="${connection.username}" /><property name="password" value="${connection.password}" /><property name="maxActive" value="${connection.maxActive}" /><property name="maxIdle" value="${connection.maxIdle}" /><property name="minIdle" value="${connection.minIdle}" /><property name="removeAbandoned" value="${connection.removeAbandoned}" /><property name="removeAbandonedTimeout" value="${connection.removeAbandonedTimeout}" /><property name="logAbandoned" value="${connection.logAbandoned}" /><property name="defaultAutoCommit" value="${connection.defaultAutoCommit}" /><property name="defaultReadOnly" value="${connection.defaultReadOnly}" /></bean><!--配置事務(wù)管理器 --><bean id="transactionManager"class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><property name="dataSource" ref="dataSource" /></bean><!-- 這里我在原來博文的基礎(chǔ)上加入了spring的aop事務(wù)管理 --><aop:config><!-- 設(shè)置pointCut表示哪些方法要加入事務(wù)處理 --><!-- 以下的事務(wù)是聲明在DAO中,但是通常都會(huì)在Service來處理多個(gè)業(yè)務(wù)對(duì)象邏輯的關(guān)系,注入刪除,更新等,此時(shí)如果在執(zhí)行了一個(gè)步驟之后拋出異常 就會(huì)導(dǎo)致數(shù)據(jù)不完整,所以事務(wù)不應(yīng)該在DAO層處理,而應(yīng)該在service,這也就是Spring所提供的一個(gè)非常方便的工具,聲明式事務(wù) --><aop:pointcut id="txPointcut"expression="execution(* com.mpc.*.service..*.*(..))" /><!-- 通過advisor來確定具體要加入事務(wù)控制的方法 --><aop:advisor advice-ref="txAdvice" pointcut-ref="txPointcut" /></aop:config><!-- 配置哪些方法要加入事務(wù)控制 --><tx:advice id="txAdvice" transaction-manager="transactionManager"><tx:attributes><tx:method name="get*" propagation="REQUIRED" read-only="true" /><tx:method name="count*" propagation="REQUIRED" read-only="true" /><tx:method name="find*" propagation="REQUIRED" read-only="true" /><tx:method name="list*" propagation="REQUIRED" read-only="true" /><tx:method name="*" propagation="REQUIRED" read-only="true" /><!-- 一下方法都是可能設(shè)計(jì)修改的方法,無法設(shè)置為只讀 --><tx:method name="add*" propagation="REQUIRED" /><tx:method name="create*" propagation="REQUIRED" /><tx:method name="insert*" propagation="REQUIRED" /><tx:method name="merge*" propagation="REQUIRED" /><tx:method name="del*" propagation="REQUIRED" /><tx:method name="remove*" propagation="REQUIRED" /><tx:method name="put*" propagation="REQUIRED" /><tx:method name="update*" propagation="REQUIRED" /><tx:method name="save*" propagation="REQUIRED" /><!-- 這個(gè)hhh是我測試在aop事務(wù)和mybatis配合的時(shí)候,事務(wù)是否生效 --><tx:method name="hhh*" propagation="REQUIRED" /></tx:attributes></tx:advice><!-- 下面是mybatis的相關(guān)配置,這些都需要導(dǎo)入jar包,mybaits-spring.jar,這個(gè)在我參考的博文中有,我就不多說了 --><bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"><!--dataSource屬性指定要用到的連接池 --><property name="dataSource" ref="dataSource" /><!--configLocation屬性指定mybatis的核心配置文件 --><property name="configLocation" value="classpath:/config/Configuration.xml" /><!-- 這里指定了我們的User.xml這類規(guī)定數(shù)據(jù)庫操作的xml文件的位置,在項(xiàng)目中獨(dú)立把他們放到了一個(gè)mapper包下 --><property name="mapperLocations" value="classpath*:com/mpc/mybaits/mapper/*.xml" /></bean><!-- 這個(gè)就是用接口變成的方式中,指定從哪里掃描我們的接口,托管到spring中管理,這樣在spring的service或dao中就可以使用了 --><bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"><property name="basePackage" value="com.mpc.mybaits.inter" /></bean><!-- <bean id="userMapper" class="org.mybatis.spring.mapper.MapperFactoryBean"> sqlSessionFactory屬性指定要用到的SqlSessionFactory實(shí)例 <property name="sqlSessionFactory" ref="sqlSessionFactory" /> mapperInterface屬性指定映射器接口,用于實(shí)現(xiàn)此接口并生成映射器對(duì)象 <property name="mapperInterface" value="com.mpc.mybaits.inter.IUserOperation" /> </bean> --><context:component-scan base-package="com.mpc.mybaits"><!-- 注意在這里掃描的時(shí)候不要掃描controller,因?yàn)樵谶@里裝載了controller的話 controller獲得的service和dao就是沒有事務(wù)的--><context:exclude-filter type="annotation"expression="org.springframework.stereotype.Controller" /><!-- secuirty模塊需要 --><context:exclude-filter type="annotation"expression="org.springframework.web.bind.annotation.ControllerAdvice" /></context:component-scan> </beans>3.配置config下的spring-mvc-servlet.xml,這xml文件是用來配置springmvc的,主要包括視圖的解析以及相關(guān)請(qǐng)求的配置 <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"xmlns:context="http://www.springframework.org/schema/context"xmlns:util="http://www.springframework.org/schema/util" xmlns:jee="http://www.springframework.org/schema/jee"xmlns:tx="http://www.springframework.org/schema/tx" xmlns:mvc="http://www.springframework.org/schema/mvc"xmlns:aop="http://www.springframework.org/schema/aop"xsi:schemaLocation="http://www.springframework.org/schema/utilhttp://www.springframework.org/schema/util/spring-util-3.2.xsdhttp://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsdhttp://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsdhttp://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.2.xsdhttp://www.springframework.org/schema/mvchttp://www.springframework.org/schema/mvc/spring-mvc-3.2.xsdhttp://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd"default-lazy-init="false"><bean id="multipartResolver"class="org.springframework.web.multipart.commons.CommonsMultipartResolver" /><!-- 默認(rèn)的視圖解析器 --><bean id="defaultViewResolver"class="org.springframework.web.servlet.view.InternalResourceViewResolver"p:order="3"><!-- 如果使用freemaker 或者velocity 需要更改viewClass --><property name="viewClass"value="org.springframework.web.servlet.view.JstlView" /><property name="contentType" value="text/html" /><property name="prefix" value="/WEB-INF/view/" /><property name="suffix" value=".jsp" /></bean><!-- 開啟controller注解支持 --><!-- 注:如果base-package=com.mpc 則注解事務(wù)不起作用 TODO 讀源碼 --><context:component-scan base-package="com.mpc.mybaits"use-default-filters="false"><!-- 在這里掃描controller,controller就能獲得有事務(wù)的service和dao --><context:include-filter type="annotation"expression="org.springframework.stereotype.Controller" /><!-- security 模塊需要 --><context:include-filter type="annotation"expression="org.springframework.web.bind.annotation.ControllerAdvice" /></context:component-scan><!-- 開啟注解 --><mvc:annotation-driven /><!-- 在配置為/的時(shí)候,靜態(tài)文件的訪問會(huì)有問題,配置了這個(gè)以后,就不會(huì)有問題了 --><mvc:default-servlet-handler /> </beans>
4.config下的Configuration.xml,這個(gè)就是我們的mybatis的核心配置文件,是session的配置信息,由于很多功能托管給了spring,所以變的很瘦小 <?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><typeAlias alias="User" type="com.mpc.mybaits.model.User" /><typeAlias alias="Article" type="com.mpc.mybaits.model.Article" /></typeAliases><!-- 數(shù)據(jù)源的相關(guān)配置已經(jīng)托管給了spring --><!-- <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://127.0.0.1:3306/mybaits" /> <property name="username" value="root" /> <property name="password" value="root" /> </dataSource> </environment> </environments> --><!-- mappers的配置托管給了spring --><!-- <mappers> <mapper resource="com/mpc/mybaits/model/User.xml" /> </mappers> --> </configuration>
5.DAO層的實(shí)現(xiàn) package com.mpc.mybaits.dao;import java.util.List;import com.mpc.mybaits.model.Article; import com.mpc.mybaits.model.User;public interface UserDAO {public List<Article> getUserArticles(int userid);public User hhhh(User user); }
6.service層的實(shí)現(xiàn)
package com.mpc.mybaits.service;import java.util.List;import com.mpc.mybaits.model.Article; import com.mpc.mybaits.model.User;public interface UserService {public List<Article> getUserArticles(int userid);public User hhhh(User user); }
package com.mpc.mybaits.service.impl;import java.util.List;import javax.annotation.Resource;import org.springframework.stereotype.Service;import com.mpc.mybaits.dao.UserDAO; import com.mpc.mybaits.model.Article; import com.mpc.mybaits.model.User; import com.mpc.mybaits.service.UserService;@Service public class UserServiceImpl implements UserService {@Resourceprivate UserDAO userDao;@Overridepublic List<Article> getUserArticles(int userid) {return userDao.getUserArticles(userid);}@Overridepublic User hhhh(User user) {// TODO Auto-generated method stubreturn userDao.hhhh(user);}}
7.controller層的實(shí)現(xiàn) package com.mpc.mybaits.controller;import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map;import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody;import com.mpc.mybaits.inter.IUserOperation; import com.mpc.mybaits.model.Article; import com.mpc.mybaits.model.User; import com.mpc.mybaits.service.UserService; import com.mpc.mybaits.utils.PageInfo;/*** @author Administrator**/ @Controller @RequestMapping("/article") public class UserController {@ResourceUserService userService;@RequestMapping("/listspring")@ResponseBodypublic List<Article> listallSpring(HttpServletRequest request,HttpServletResponse response) {List<Article> articles = userService.getUserArticles(1);return articles;}}
8.啟動(dòng)項(xiàng)目,測試結(jié)果:
mybatis實(shí)戰(zhàn)教程(mybatis in action)之七:實(shí)現(xiàn)mybatis分頁
1.按照我參考的博文的相關(guān)內(nèi)容給util包中添加PageInfo、PagePlugin、ReflectHelper這三個(gè)類以后,就給代碼中添加了分頁插件。
2.在user.xml中添加如下代碼
<!-- 分頁查詢測試 --><select id="selectArticleListPage" resultMap="resultUserArticleList">selectuser.id,user.userName,user.userAddress,article.idaid,article.title,article.content from user,articlewhereuser.id=article.userid and user.id=#{userid}</select>
3.給inter包的接口中添加相應(yīng)的方法
public List<Article> selectArticleListPage(@Param("page") PageInfo page,@Param("userid") int userid);4.在Configuration.xml中添加插件
<plugins><plugin interceptor="com.mpc.mybaits.utils.PagePlugin"><property name="dialect" value="mysql" /><property name="pageSqlId" value=".*ListPage.*" /></plugin></plugins>這樣所有包含ListPage的mapper中的方法都會(huì)執(zhí)行分頁動(dòng)作。
5.在controller中添加如下方法測試
@RequestMapping("/listpage")public @ResponseBody List<Article> listpage(HttpServletRequest request,HttpServletResponse response) {int currentPage = (request.getParameter("page") == null || Integer.parseInt(request.getParameter("page")) <= 0) ? 1 : Integer.parseInt(request.getParameter("page"));int pageSize = 2;int currentResult = (currentPage - 1) * pageSize;System.out.println(request.getRequestURI());System.out.println(request.getQueryString());PageInfo info = new PageInfo();info.setShowCount(pageSize);info.setCurrentResult(currentResult);List<Article> list = userMapper.selectArticleListPage(info, 1);System.out.println(info);int totalCount = info.getTotalResult();int lastPage = 0;if (totalCount % pageSize == 0) {lastPage = totalCount / pageSize;} else {lastPage = 1 + totalCount / pageSize;}if (currentPage >= lastPage) {currentPage = lastPage;}String pageStr = "";// pageStr = String.format(// "<a href=\"%s\">上一頁</a> <a href=\"%s\">下一頁</a>",// request.getRequestURI() + "?page=" + (currentPage - 1),// request.getRequestURI() + "?page=" + (currentPage + 1));//// ModelAndView mav = new ModelAndView("list");// mav.addObject("articles", list);// mav.addObject("pageStr", pageStr);// return mav;return list;}
6.測試結(jié)果
我規(guī)定的是一頁顯示兩條,查詢結(jié)果如下:
確實(shí)是兩條,而我的數(shù)據(jù)庫中有3條數(shù)據(jù)的。
mybatis實(shí)戰(zhàn)教程(mybatis in action)之八:mybatis 動(dòng)態(tài)sql語句(這部分貌似和分頁一樣··沒有自己的一些感覺,只是在照貓畫虎的學(xué)習(xí)一些語法來完成動(dòng)態(tài)語句,參照的博客原文中介紹的都很詳細(xì)了,這里我只是想記錄一下自己足跡,不愛的同學(xué)可以跳過這一段)
1.mybatis if語句處理
在User.xml中添加如下代碼,用來測試if語句
<select id="selectUsersInCondition" parameterType="User"resultMap="resultListUser">select * from user where<if test="userAge !=null">userAge=#{userAge}</if><!-- 自己修改修改··因?yàn)槿绻麄魅氲膗serAge是null的話,語句就變成了 and userAddress=xxxx,所以多了些判斷,往后才知道·原來這種不靠譜的情況有其他解決方式 --><if test="userAddress !=null and userAge!=null">and userAddress=#{userAddress}</if><if test="userAddress !=null and userAge==null">userAddress=#{userAddress}</if></select>
在IUserOperation中添加相應(yīng)的接口方法
public List<User> selectUsersInCondition(User user);
/*** @return 測試if動(dòng)態(tài)查詢*/@RequestMapping("/listusercon")@ResponseBodypublic List<User> listUserCon() {User user = new User();// user.setUserAge("100");user.setUserAddress("shanghai,pudong");return userMapper.selectUsersInCondition(user);}
測試結(jié)果
2.choose (when,otherwize)只走其中一條路
在User.xml中添加如下代碼
<select id="dynamicChooseTest" parameterType="User" resultMap="resultListUser">select * from user where<choose><when test="userAddress != null">userAddress=#{userAddress}</when><when test="userAge != null">userAge = #{userAge}</when><otherwise>id=1</otherwise></choose></select>
當(dāng)傳如的user對(duì)象的userAddress不為空就根據(jù)userAddress查詢,userAge不為空就根據(jù)userAge查詢,otherwise在所有的when都不滿足的時(shí)候生效。但是永遠(yuǎn)只能選一個(gè)。
在IUserOperation中添加如下語句
public List<User> dynamicChooseTest(User user);測試方法
@RequestMapping("/listuserwhere")@ResponseBodypublic List<User> listUserWhere() {User user = new User();// user.setUserAge("100");// user.setUserAddress("shanghai,pudong");return userMapper.dynamicChooseTest(user);}
測試結(jié)果
可以看到的是在userAge,userAddress都為空的情況下,根據(jù)id=1來查詢的
3.trim (對(duì)包含的內(nèi)容加上 prefix,或者 suffix 等,前綴,后綴)
trim的作用就是可以為<trim></trim>標(biāo)簽所包含的內(nèi)容加上一個(gè)前綴或者后綴,并且可以指定這個(gè)前綴或者后綴覆蓋住指定的字符串。
在User.xml中添加如下代碼
<select id="dynamicTrimTest" parameterType="User" resultMap="resultListUser">select * from user<trim prefix="where" prefixOverrides="and |or"><if test="userAge != null">and userAge = #{userAge}</if><if test="userAddress != null">and userAddress = #{userAddress}</if></trim></select>這樣寫的話,就算是userAge不是空的,那么出現(xiàn)在where后面的也是 userAge=xxx不是and userAge=xxx;
在IUserOperation中添加對(duì)應(yīng)的接口方法;
public List<User> dynamicTrimTest(User user);
測試方法
@RequestMapping("/listusertrim")@ResponseBodypublic List<User> listUserTrim() {User user = new User();// user.setUserAge("110");user.setUserAddress("shanghai,pudong");return userMapper.dynamicTrimTest(user);}
測試結(jié)果
可以看到,并沒有報(bào)sql語句錯(cuò)誤,trim是成功的。
4. where (主要是用來簡化sql語句中where條件判斷的,能智能的處理 and or 條件)
個(gè)人理解就是<where> ====<trim prefix="where" prefixOverrides="and |or">
在User.xml中添加如下代碼
<select id="dynamicWhereTest" parameterType="User" resultMap="resultListUser">select * from user<where><if test="userAge != null">and userAge = #{userAge}</if><if test="userAddress != null">and userAddress = #{userAddress}</if></where></select>在IUserOperation中添加對(duì)應(yīng)的接口方法 public List<User> dynamicWhereTest(User user);
測試方法: @RequestMapping("/listuserauto")@ResponseBodypublic List<User> listUserAuto() {User user = new User();// user.setUserAge("110");user.setUserAddress("shanghai,pudong");return userMapper.dynamicWhereTest(user);}
測試結(jié)果
5.set (主要用于更新時(shí))
在User.xml中添加如下代碼
<update id="dynamicSetTest" parameterType="User">update user<set><if test="userAge != null">userAge = #{userAge},</if><if test="userAddress != null">userAddress = #{userAddress},</if></set>where id = #{id}</update><set>可以智能處理最后一個(gè)多出來的逗號(hào)在IUserOperation中添加對(duì)應(yīng)的接口方法
public void dynamicSetTest(User user);測試方法 @RequestMapping("/dynamicSetTest")@ResponseBodypublic User dynamicSetTest() {User user = new User();user.setId(1);user.setUserAge("120");user.setUserAddress("shanghai,pudong,laolao");userMapper.dynamicSetTest(user);return user;}
6. foreach (在實(shí)現(xiàn) mybatis in 語句查詢時(shí)特別有用)?
6.1但參數(shù)List類型
在User.xml中的配置內(nèi)容如下:
<select id="dynamicForeachTest" resultMap="resultUserArticleList">selectuser.id,user.userName,user.userAddress,user.userAge,article.idaid,article.title,article.content from user,articlewhereuser.id=article.userid and article.userid in<foreach collection="list" index="index" item="item" open="("separator="," close=")">#{item}</foreach></select>在IUserOperation中添加對(duì)應(yīng)的接口方法 public List<Article> dynamicForeachTest(List<Integer> ids);測試方法 @RequestMapping("/dynamicForeachTest")@ResponseBodypublic List<Article> dynamicForeachTest() {List<Integer> list = new ArrayList<Integer>();list.add(1);list.add(3);return userMapper.dynamicForeachTest(list);}
測試結(jié)果
6.2數(shù)組類型的參數(shù)
在User.xml添加如下代碼
<select id="dynamicForeach2Test" resultMap="resultUserArticleList">selectuser.id,user.userName,user.userAddress,user.userAge,article.idaid,article.title,article.content from user,articlewhereuser.id=article.userid and article.userid in<foreach collection="array" index="index" item="item" open="("separator="," close=")">#{item}</foreach></select>在IUserOperation中添加對(duì)應(yīng)的接口方法 public List<Article> dynamicForeach2Test(int[] ids);
測試方法 @RequestMapping("/dynamicForeach2Test")@ResponseBodypublic List<Article> dynamicForeach2Test() {int[] ints = new int[] { 1, 3 };return userMapper.dynamicForeach2Test(ints);}
測試結(jié)果
只是查詢參數(shù)用數(shù)組來傳入了,查詢結(jié)果和list傳入?yún)?shù)的結(jié)果是一樣的
6.3map類型的參數(shù),用map類型的參數(shù)可以傳入多個(gè)參數(shù),其中一個(gè)用來迭代
在User.xml中添加如下代碼,使用map來傳遞參數(shù),那么參數(shù)的key值是很有用的,通過id這個(gè)key來獲得id的value值,通過指定collection為ids,從而迭代ids這個(gè)key所指定的value值。
<select id="dynamicForeach3Test" resultMap="resultUserArticleList">selectuser.iduid,user.userName,user.userAddress,user.userAge,article.idaid,article.title,article.content from user,articlewherearticle.userid=#{id}and user.id=article.userid and article.userid in<foreach collection="ids" index="index" item="item" open="("separator="," close=")">#{item}</foreach></select>在IUserOperation中添加對(duì)應(yīng)的接口方法 public List<Article> dynamicForeach3Test(Map<String, Object> params);
測試方法 @RequestMapping("/dynamicForeach3Test")@ResponseBodypublic List<Article> dynamicForeach3Test() {Map<String, Object> map = new HashMap<String, Object>();int[] ints = new int[] { 1, 3 };map.put("id", 1);map.put("ids", ints);return userMapper.dynamicForeach3Test(map);}
測試結(jié)果
mybatis實(shí)戰(zhàn)教程(mybatis in action)之九:mybatis 代碼生成工具的使用
這方面的內(nèi)容按照參考博客中大神的方法,把各種信息本地化成自己的,就直接運(yùn)行程序后,我們的各種類和xml文件就自動(dòng)生成到自己的包里了,這里我就不煩人了。
總結(jié):通過參照高手的博客,可以說對(duì)mybatis有了一個(gè)很基礎(chǔ)的入門,知道了基本的使用技能,很多的使用技巧和高級(jí)的使用方法在以后項(xiàng)目的實(shí)踐中還需要自己慢慢的積累和摸索。
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)總結(jié)
以上是生活随笔為你收集整理的mybatis自己学习的一些总结的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 洛谷 P1219 ---- 八皇后
- 下一篇: 实现 tomcat 热加载证书