mybatis는 무엇입니까?
MyBatis는 일반 SQL 쿼리, 저장 프로 시저 및 고급 매핑을 지원하는 우수한 지속성 계층 프레임 워크입니다. MyBatis는 거의 모든 JDBC 코드 및 매개 변수의 수동 설정과 결과 세트의 검색을 제거합니다. MyBatis는 구성 및 원래 매핑, 맵핑 인터페이스 및 Java의 Pojos (오래된 Java 개체, 일반 Java 개체)를 데이터베이스의 레코드로 사용하는 간단한 XML 또는 주석을 사용합니다.
ORM 도구의 기본 아이디어
최대 절전 모드 또는 Mybatis를 사용하든 Dharma와 공통점을 가질 수 있습니다.
1. 구성 파일에서 세션 변형을 얻습니다 (일반적으로 XML 구성 파일).
2. SessionFactory에서 세션을 생성합니다
3. 세션에서 데이터 추가, 삭제, 수정 및 쿼리, 트랜잭션 제출 등을 완료합니다.
4. 사용 후 세션을 닫습니다.
5. Java 객체와 데이터베이스, 일반적으로 XML 파일간에 매핑을위한 구성 파일이 있습니다.
Mybatis 실제 튜토리얼 중 하나 (Mybatis in Action) : 개발 환경 구성
MyBatis 개발 환경이 구축되었습니다 : Eclipse J2EE 버전, MySQL 5.1, JDK 1.7, MyBatis3.2.0.jar 패키지. 이 소프트웨어 도구는 해당 공식 웹 사이트에서 다운로드 할 수 있습니다.
먼저 Mybaits라는 역동적 인 웹 프로젝트를 만듭니다
1.이 단계에서는 Java 프로젝트를 직접 구축 할 수 있지만 일반적으로 웹 프로젝트를 개발할 수 있습니다. 이 일련의 튜토리얼은 마지막에 웹이므로 처음부터 웹 프로젝트를 구축 할 수 있습니다.
2. MyBatis-3.2.0-snapshot.jar, MySQL-Connector-Java-5.1.22-Bin.jar를 웹 프로젝트의 LIB 디렉토리로 복사하십시오.
3. MySQL 테스트 데이터베이스 및 사용자 테이블을 만듭니다. UTF-8 인코딩이 여기에서 사용됩니다.
사용자 테이블을 만들고 테스트 데이터를 삽입하십시오
프로그램 코드
테이블`user '(`id` int (11) not null auto_increment,`username` varchar (50) 기본 null,`userage` int (11) default null,`userAddress` varchar (200) 기본 널 (id`)) 1 차 키 (indenodb auto_increment = utf8; '여름', '100', '상하이, 푸동');
지금까지 예비 준비가 완료되었습니다. Mybatis 프로젝트를 구성하겠습니다.
1. MyBatis에서 SRC_USER, TEST_SRC와 같은 두 개의 소스 코드 디렉토리를 작성하고 다음 방식으로 작성하여 Javaresource를 마우스 오른쪽 단추로 클릭하십시오.
2. myBatis configuration 파일 설정 : configuration.xml, src_user 디렉토리 에서이 파일을 만듭니다. 내용은 다음과 같습니다.
프로그램 코드
<? 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> <typealias ="user "" type = "com.yihaomen.mybatis.model.user"/> </indecealiases> <환경 기본값 = "개발"> <환경 ID = "Development"> <transactionManager type = "jdbc"/> <dataSource type = "property name ="driver "value ="com.mysql.jdbc. value = "jdbc : mysql : //127.0.0.1 : 3306/mybatis"/> <property name = "value"value = "root"/> <property name = "valess ="valess "/> <property name ="password "/> </dataSource> </환경> <mappers> <Mapper Resource = "com/yihaomen/mybatis/model/user.xml"/> </mappers> </configuration>
3. 데이터베이스에 해당하는 Java 클래스 및 매핑 파일을 만듭니다.
패키지 만들기 : com.yihaomen.mybatis.model에서 src_user 아래에서 사용자 클래스를 만듭니다.
프로그램 코드
package com.yihaomen.mybatis.model; public class user {private int id; private string username; private string userage; private string userAddress; public int getId () {return id;} public void setId (int id) {id = id;} public void setusern (string username; username;} public string getUserage () {return userage;} public void setUserage (String userage) {this.userage = userage;} public String getUserAddress () {return userAddress;} public void setUserAddress (String userAddress) {this.userAddress = userAddress;}}동시에 사용자 매핑 파일 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"> Namespace = "com.yhaomen.mybatis.models.usermapper"> <select id = "selectUserById"parameterType = "int"resultType = "user"> select *에서`us id = #{id} < /select> < /mapper>이러한 구성 파일에는 다음과 같은 설명이 제공됩니다.
1. configuration.xml은 mybatis에 의해 세션 기능을 설정하는 데 사용됩니다. 주로 데이터베이스 연결 관련 사항과 Java 클래스에 해당하는 별칭이 포함됩니다. 예를 들어, 별칭 별칭 = "사용자"유형 = "com.yihaomen.mybatis.model.user"/>이 별칭은 매우 중요합니다. user.xml의 resulttype와 같은 특정 클래스의 매핑에서 여기에 해당합니다. 물론 일관되게하기 위해, 여기에는 결과 유형의 또 다른 별도의 정의가 있으며, 나중에 논의 될 것입니다.
2. configuration.xml의 <mapper resource = "com/yihaomen/mybatis/model/user.xml"/>는 매핑 될 클래스를 포함하는 XML 구성 파일입니다.
3. user.xml 파일에서 주로 다양한 SQL 문과 이러한 문의 매개 변수뿐만 아니라 반환 할 유형 등을 정의합니다.
테스트를 시작하십시오
test_src 소스 코드 디렉토리에서 com.yihaomen.test 패키지를 만들고 테스트 클래스 테스트를 만듭니다.
프로그램 코드
패키지 com.yihaomen.test; import java.io.reader; import org.apache.ibatis.io.resources; import org.apache.ibatis.ssession.sqlsession; import org.apache.ibatis.session.sqlsession actory; import org.apache.ibatis.sclession.sqlsactory; import; org.apache.ibatis.session.sqlsessionfactorybuilder; import com.yihaomen.mybatis.model.user; public class test {private static sqlsessionfactory sqlsessionfactory; 개인 정적 리더 리더; static {try {reader = resources.getresourceasreader ( "configuration.xml"); sqlsessionFactory = new sqlSessionFactoryBuilder (). 빌드 (reader);} catch (예외 e) {e.printstacktrace ();}} public static sqlsession factory getsession () sqlsession actatic getsession () main (string [] args) {sqlsession session = sqlsessionfactory.opensession (); try {user user = (user) session.selectone ( "com.yihaomen.mybatis.models.usermapper.selectuserbyid", 1); system.out.println (user.getUserAddress ()); System.out.println (user.getusername ());} 최종적으로 {session.close ();}}} 이제이 프로그램을 실행하면 쿼리 결과를 얻을 수 있습니다. 축하합니다. 환경은 성공적으로 구축되고 구성됩니다. 다음으로 두 번째 장에서는 인터페이스 기반 작동 방법에 대해 이야기하고 추가, 삭제, 수정 및 확인에 대해 이야기합니다.
전체 프로젝트 디렉토리 구조는 다음과 같습니다.
Mybatis Practice Tutorial (Mybatis in Action) 2 : 인터페이스의 프로그래밍
이전 장에서는 Eclipse, Mybatis, MySQL의 환경이 구축되었으며 간단한 쿼리가 구현되었습니다. 이 방법은 sqlsession 인스턴스를 사용하여 매핑 된 SQL 문을 직접 실행하는 것입니다.
session.selectone ( "com.yihaomen.mybatis.models.usermapper.selectuserByid", 1)
실제로, 매개 변수 및 SQL 문 반환 값 (예 : iuseroperation.class)을 합리적으로 설명하는 인터페이스를 사용하여 더 간단한 방법과 더 나은 방법이 있으므로 이제 쉬운 문자 리터럴 및 변환 오류 없이이 간단하고 안전한 코드로 이동할 수 있습니다. 다음은 자세한 과정입니다.
src_user 소스 코드 디렉토리에 com.yihaomen.mybatis.inter 패키지를 만들고 인터페이스 클래스 iuseroperation을 만듭니다. 내용은 다음과 같습니다.
프로그램 코드
패키지 com.yihaomen.mybatis.inter; import com.yihaomen.mybatis.model.user; public interface iuseroperation {public user selectUserByid (int);}여기에 method name selectUserById가 있습니다. 여기에는 user.xml에서 구성된 선택한 선택의 ID에 해당해야합니다 (<select id = "selectUserByid").
테스트 코드를 다시 작성하십시오
public static void main (string [] args) {sqlsession session = sqlsessionfactory.opensession (); try {iuseroperation userOperation = session.getMapper (iuseroperation.class); user user = userOperation.SelectUserById (1); System.out.println (user.getUserAddress ()); System.out.println (user.getUername ());} 최종 {session.close ();}}전체 엔지니어링 구조 다이어그램은 이제 다음과 같습니다.
이 테스트 프로그램을 실행하면 결과가 표시됩니다.
Mybatis 실제 튜토리얼 (Mybatis in Action) 3 : 데이터 추가, 삭제, 수정 및 검색 구현
이미 인터페이스를 사용하여 프로그래밍에 대해 이야기했습니다. 이런 식으로주의를 기울여야 할 것은 한 가지. user.xml configuration 파일, mapper 네임 스페이스 = "com.yihaomen.mybatis.inter.iuseroperation"네임 스페이스는 매우 중요합니다. 오류가 없어야합니다. 패키지 및 인터페이스와 일치해야합니다. 불일치가 있으면 오류가 발생합니다. 이 장은 주로 이전 강의에서 인터페이스 프로그래밍을 기반으로 다음을 완료합니다.
1. MyBatis를 사용하여 목록을 포함하여 데이터를 쿼리하십시오
2. mybatis를 사용하여 데이터를 늘리십시오
3. mybatis로 데이터를 업데이트하십시오.
4. mybatis를 사용하여 데이터를 삭제하십시오.
데이터 쿼리 데이터, 위에서 언급 한 바와 같이, 우리는 주로 목록 쿼리를 살펴 봅니다.
목록을 쿼리하십시오. 이런 식으로 user.xml에서 반환 된 유형 resultmap을 구성해야합니다. 결과 유형이 아니며 해당 resultmap은 스스로 구성해야합니다.
프로그램 코드
<!-리턴 목록 유형으로 정의 된 returnMap-> <resultmap type = "user"id = "resultListuser"> <id column = "id"property = "id" /> <result column = "username"property = "username" /> <result column = "userage"속성 = "userage" /> <result column = "userAddress" /<userAddress ".
명령문 쿼리 목록은 user.xml에 있습니다
프로그램 코드
<!-목록의 선정 명령문을 반환하고 결과 맵의 값은 이전에 정의 된 이전에 가리킨다-> <selectUsers "parameterType ="string "resultMap ="resultListuser "> select * #{username} </select>iuseroperation 인터페이스에 메소드 추가 : 공개 목록 <user> selectusers (String username);
이제 테스트 클래스에서 테스트를 수행하십시오
프로그램 코드
public void getUserList (String username) {sqlsession session = sqlsessionfactory.opensession (); try {iuseroperation userOperation = session.getMapper (iuserOperation.class); List <user> user = userOperation.SelectUsers (사용자 이름); for (user user : user) {system.out.println (user.getId ()+":"+user.getUername ()+":"+user.getUserAddress ());}} 최종 {session.close ();}}이제 주요 방법에서는 다음을 테스트 할 수 있습니다.
프로그램 코드
public static void main (String [] args) {test testuser = new test (); testuser.getuserlist ( "%");}결과가 성공적으로 쿼리되었음을 알 수 있습니다. 단일 데이터를 쿼리하는 경우 두 번째 강의에 사용 된 방법 만 사용하십시오.
mybatis를 사용하여 데이터를 늘리십시오
iuseroperation 인터페이스에 메소드 추가 : public void adduser (사용자);
user.xml에서 구성하십시오
프로그램 코드
<!-증가 작업을 수행하는 SQL 문. ID 및 PARAMETERTYPE는 IUSEROPERATION 인터페이스에서 ADDUSER 메소드의 이름 및 매개 변수 유형과 동일합니다. 참조 #{name} 형식으로 학생 매개 변수의 이름 속성을 참조하고 MyBatis는 반사를 사용하여 학생 매개 변수 의이 속성을 읽습니다. #{name}의 이름 사례에 민감합니다. 성별과 같은 다른 속성을 참조하는 것은 이것과 일치합니다. "true"로 설정된 segeneratedkeys는 Mybatis가 데이터베이스에 의해 자동으로 생성 된 기본 키를 얻기를 원한다는 것을 나타냅니다. keyProperty = "id"는 학생의 ID 속성에 획득 된 1 차 키 값을 주입합니다 -> <insert id = "adduser"parameterType = "user"usegeneratedKeys = "true"keyProperty = "id"> user in user (username, userAds, userAddress) 값 (#userAname},#{userAde},#{{{userAname}) </삽입>그런 다음 테스트 방법을 작성하십시오.
프로그램 코드
/*** 테스트가 증가합니다. 증가 후 트랜잭션을 제출해야합니다. 그렇지 않으면 데이터베이스에 기록되지 않아야합니다.*/public void addUser () {user user = new user (); user.setuserAddress ( "People 's Square"); user.setusername ( "Flying Bird"); user.setuserage (80); sqlsession session = sqlsessionsession.opensession (iUseropensession); userOperation = session.getMapper (iuseroperation.class); userOperation.adduser (user); session.commit (); System.out.println ( "현재 증가 된 사용자 ID는 :"+user.getId ());} 최종 {session.close ();}}입니다.mybatis로 데이터를 업데이트하십시오
이 방법은 비슷합니다. 먼저 iuseroperation에 메소드를 추가하십시오 : public void adduser (사용자);
그런 다음 user.xml을 구성하십시오
프로그램 코드
<업데이트 id = "updateUser"ParameterType = "User"> Usude Usude user set username =#{username}, userage =#{userage}, userAddress =#{userAddress} 여기서 id =#{id} </update>테스트 클래스의 총 테스트 방법은 다음과 같습니다.
프로그램 코드
public void updateUser () {// 사용자를 먼저 얻은 다음 수정하고 제출하십시오. sqlsession session = sqlsessionfactory.opensession (); try {iuseroperation useroperation = session.getMapper (iuseroperation.class); user user = userOperation.SelectUserById (4); user.setuserAddress ( "매직 시티의 Pudong Innovation Park로 밝혀졌습니다"); userOperation.upDateUser (user); session.commit ();} 최종 {session.close ();}}mybatis를 사용하여 데이터를 삭제하십시오
유사하게, iuseroperation 첨가 방법 : public void deleteuser (int id);
user.xml을 구성하십시오
프로그램 코드
<delete id = "deleteuser"parametertype = "int"> id =#{id} </delete> us here에서 삭제합니다그런 다음 테스트 클래스에 테스트 방법을 작성하십시오.
프로그램 코드
/*** 데이터를 삭제하려면 커밋해야합니다.*@param id*/public void deleteuser (int id) {sqlsession session = sqlsessionfactory.opensession (); iuseroperation userOperation = session.getMapper (iuserOperation.class); userOperation.deleteUser (id); session.commit (); } 마침내 {session.close ();}}이러한 방식으로 모든 추가, 삭제, 수정 및 점검이 완료됩니다. 데이터베이스가 실시간으로 작동되도록 추가, 변경 및 삭제할 때 Session.Commit ()를 호출해야합니다. 그렇지 않으면 제출되지 않습니다.
지금까지 간단한 단일 테이블 작업을 수행 할 수 있어야합니다. 다음에 다중 테이블 조인트 쿼리와 결과 세트 선택에 대해 이야기하겠습니다.
Mybatis 실제 튜토리얼 (Mybatis in Action) 4 : 관련 데이터 쿼리 구현
이전 장의 기초를 사용하면 일부 간단한 응용 프로그램이 처리 될 수 있지만 실제 프로젝트에서는 종종 가장 일반적인 다중, 일대일 등과 같은 연관성 테이블에 대해 쿼리됩니다. 이러한 쿼리는 어떻게 처리됩니까? 이 대화는이 문제에 대해 이야기 할 것입니다. 먼저 기사 테이블을 만들고 데이터를 초기화합니다.
프로그램 코드
드롭 테이블이 존재하는 경우`article`; chreate`article` (`id` int (11) NOL NOT AUTO_INCREMENT,`userID` int (11) NOT NULL,`title` varchar (100) NULL NOT NULL, 'Content'텍스트가 NULL, 기본 키 (`ID`))) 엔진 = innodb auto_increment = 5 Default Charset = utf8; ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- INTO `article` VALUES ('1', '1', 'test_title', 'test_content');`article` 값 ( '2', '1', 'test_title_2', 'test_content_2')에 삽입;`article` 값 ( '3', '1', 'test_title_3', 'test_content_3')에 삽입; '4', '4', '1', '1' 'test_content_4');이 기사에 해당하는 userID가 1이므로 사용자 테이블 사용자에 ID = 1이있는 데이터가 있어야합니다. 자신의 조건을 충족하는 데이터로 수정할 수 있습니다. ORM 규칙에 따라 테이블이 생성되었으므로 객체가 해당해야하므로 기사 클래스를 추가합니다.
프로그램 코드
package com.yihaomen.mybatis.model; public class article {private int id; private user user; private string title; private string 컨텐츠; public int getId () {return id;} public void setid (int id) {this.id = id;} public user getUser () {return void setUser (user void setUser) {user gettit (retrit)} title;} public void settitle (문자열 제목) {this.title = title;} public String getContent () {return content;} public void setContent (문자열 내용) {this.content = content;}}기사 사용자가 어떻게 정의하는지, 직접 정의 된 사용자 객체입니다. int 유형이 아닙니다.
다국적 구현
시나리오 : 특정 사용자가 게시 한 모든 기사를 읽으십시오. 물론 여전히 user.xml에서 select 문을 구성해야하지만 핵심 사항은이 SELECT의 결과 메이프가 다음과 같은 데이터의 종류를 수행하는 것입니다. 이것이 핵심 요점입니다. 여기서 우리는 연관성을 소개하고 다음과 같이 정의를 볼 필요가 있습니다.
프로그램 코드
<!-사용자는 공동 기사에 대한 쿼리 메소드 중 하나를 구성합니다 (leccond-one)-> <resultmap id = "resultSerarticlelist"type = "article"> <id property = "id"column = "aid" /> <result property = "witch"column = "witch" /<result property = "contment" "content" /> <sociation = "us us use" "us" "id us" "id in id id ind. /> <result property = "username"column = "username" /> <result property = "userAddress"column = "userAddress" /> < /resident id = "getUserArticles"ParameterType = "int"resultmap = "resultuserArticLelist"> selectuser.id, userername, user.useraddress, article.id. AID, article.title, article. user, articlewhere user.id = article.userid 및 user.id = {id} </select>의 대륙이 구성 후에는 괜찮습니다. SELECT 문과 결과 맵에 해당하는 매핑을 결합하면 이해할 수 있습니다. 관련 사용자를 확보하기 위해 협회를 사용하십시오. 모든 기사는 동일한 사용자에게 속하기 때문에 이것은 다중의 상황입니다.
이를 처리하는 또 다른 방법이 있습니다.이 방법은 이전에 정의한 결과를 재사용 할 수 있습니다. 우리는이 두 번째 방법이 어떻게 구현되는지 확인하기 전에 결과 리스토셔를 정의했습니다.
프로그램 코드
<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> <! <resultmap id = "resultuserarticlelist-2"type = "article"> <id property = "id"column = "aid" /> <result property = "title"column = "title" /> <result property = "content"column = "content" /<anspoction property = "user"javatype = "user"resultmap = "resultlistuser"select id = "getuserarticle" parametertype = "int"resultmap = "resultuserarticlelist"> user.id, user.username, user.useraddress, artic.id, article.title, article.content, articwhere user.id = article.id =#{id} </select>를 선택하십시오다중화의 목적을 달성하기 위해 연관의 해당 맵을 독립적으로 추출하십시오.
자, 이제 테스트 클래스에 테스트 코드를 작성하십시오.
프로그램 코드
public void getUserArticles (int userId) {sqlsession session = sqlsessionFactory.Opensession (); try {iuserOperation userOperation = session.getMapper (iuserOperation.class); 목록 <article> articles = userOperation.getUserArticles (userId); for (기사 : 기사) {system.out.println (article.getTitle ()+":"+article.getContent ()+":"+article.getUser (). getUserName ()+":"+article.getUser (). getUserAddress ()); 약간 놓치면 iuseroperation 인터페이스에 해당하는 선택과 동일한 ID 이름으로 동일한 메소드를 추가해야합니다.
공개 목록 <Article> getuserarticles (int id);
그런 다음 실행하고 테스트하십시오.
Mybatis Explication Tutorial (Mybatis in Action) 5 : Spring3와 통합
이 일련의 기사에서는 순수하게 mybatis를 사용하여 데이터베이스에 연결 한 다음 추가, 삭제, 수정 및 쿼리 및 다중 테이블 조인트 쿼리를 수행하는 예입니다. 그러나 실제 프로젝트에서 Spring은 일반적으로 DataSources 등을 관리하는 데 사용됩니다. Spring 인터페이스 기반 프로그래밍과 AOP 및 IOC가 제공하는 편의를 최대한 활용합니다. MyBatis를 관리하기 위해 Spring을 사용하면 최대 절전 모드 관리와 많은 유사점이 있습니다. 오늘의 초점은 데이터 소스 관리 및 Bean 구성입니다.
소스 코드를 다운로드하여 비교할 수 있습니다. 소스 코드에는 JAR 패키지가없고 너무 커서 공간이 제한되어 있습니다. 스크린 샷이 있으며 사용되는 JAR 패키지를 볼 수 있습니다. 소스 코드는이 기사의 끝에 있습니다.
첫째, 이전 엔지니어링 구조를 변경하고 SRC_USER 소스 코드 디렉토리에서 폴더 구성을 작성하고 원래 MyBatis 구성 파일 Configuration.xml을이 폴더로 이동하고 구성 파일 폴더에서 Spring Configuration 파일을 작성하고 Spring Configuration 파일을 작성하십시오. 이 구성 파일에서 가장 중요한 구성 :
프로그램 코드
<!-이 예제는 DBCP 연결 풀을 사용하며 DBCP JAR 패키지는 프로젝트의 LIB 디렉토리에 미리 복사해야합니다. -> <bean id = "dataSource"> <property name = "driver className"value = "com.mysql.jdbc.driver"/> <속성 이름 = "url"value = "jdbc : mysql : //127.0.1 : 3306/mybatis? characterEncoding = utf8"/> <속성 = "username" "username 이름 = "비밀번호"value = "password"/> </bean> <bean id = "sqlsessionFactory"> <!-DataSource 속성 사용할 연결 풀을 지정합니다-> <property name = "dataSource"ref = "dataSource"/> <!-구성 속성 MyBatis의 핵심 구성 파일을 지정합니다. value = "config/configuration.xml"/> </bean> <bean id = "usermapper"> <!-sqlsessionFactory 속성 사용하기 위해 sqlsessionFactory의 인스턴스를 지정합니다-> <property name = "sqlsessionfactory"ref = "sqlsessionFactory"/> <!-Mapperferfer 특성을 구현하는 데 사용됩니다. -> <property name = "mapperinterface"value = "com.yihaomen.mybatis.inter.iuseroperation" /> < /bean>
[b] 여기서 핵심 요점은 org.mybatis.spring.sqlsessionfactorybean 및 org.mybatis.spring.mapper.mapperfactorybean [b] 스프링 인터페이스를 구현하고 개체를 생성하는 것입니다. 자세한 내용은 mybatis-spring 코드를 볼 수 있습니다. (http://code.google.com/p/mybatis/), 만 사용하면 구성이 양호하도록 모드를 수정하십시오.
그런 다음 테스트 프로그램을 작성하십시오
패키지 com.yihaomen.test; import java.util.list; import org.springframework.context.applicationcontext; import org.sprameframework.support.support.classpathcontext; import com.yhaomen.mybatis.in com.yihaomen.mybatis.model.article; import com.yihaomen.mybatis.model.user; public class mybatissprinttest {private static applicationcontext ctx; static {ctx = new ClassPathXmlApplicationContext ( "config/applicationcontext.xml"); } public static void main (string [] args) {iuseroperation mapper = (iuseroperation) ctx.getBean ( "usermapper"); // id = 1으로 사용자 쿼리를 테스트합니다. 데이터베이스의 상황에 따르면, 그것은 자신 의.system.out.println ( "getUserAddress ()")로 변경할 수 있습니다. 사용자 user = mapper.selectuserByid (1); System.out.println (user.getUserAddress ()); // 기사 목록 테스트 System.out.println ( "사용자 ID 1이있는 모든 기사 목록 가져 오기"); 목록 <article> articles = mapper.getuserarticles (1); for (기사 기사 : articles) {System.out.println (article.getContent ()+"-"+article.getTitle ());}}}해당 결과를 얻으려면 실행하십시오.
엔지니어링 도면 :
사용 된 JAR 패키지는 아래 그림과 같습니다.
Mybatis Practice Tutorial (Mybatis in Action) 6 : Spring MVC와의 통합
이전 기사는 이미 Mybatis와 Spring의 통합에 대해 이야기했습니다. 그러나 현재 모든 프로젝트는 웹 프로젝트가 아니지만 항상 웹 프로젝트를 만들었습니다. 오늘은 Mybatis 및 Spring MVC를 직접 통합 할 것이며이 기사의 끝에서 소스 코드가 다운로드됩니다. 주로 다음 구성이 있습니다
1. web.xml Spring DispatchServlet 구성 (예 : MVC-Dispatcher)
2. MVC-Dispatcher-Servlet.xml 파일 구성
3. Spring ApplicationContext.xml 파일 구성 (MyBatis SQLSessionFaction과 통합, 모든 MyBatis Mapper 파일 등을 스캔하는 데이터베이스 관련 파일 구성
4. 컨트롤러 클래스를 작성하십시오
5. 페이지 코드를 쓰십시오.
먼저 거친 이미지가 있으며 전체 프로젝트 도면은 다음과 같습니다.
1. web.xml Spring DispatchServlet 구성 (예 : MVC-Dispatcher)
프로그램 코드 프로그램 코드
<CERLXT-PARAM> <Param-Name> ContextConfigLocation </param-name> <Param-value> classPath*: config/applicationcontext.xml </param- value> </context-param> <layer> <liste ner-class> org.springframework.web.context.contextloaderListener </Learter-Class> </Lister> <layer> <layer-class> org.springframework.web.context.contextclean Uplistener </Leater-Class> </Listener> <Servlet> <Servlet-name> MVC-Dispatcher </servlet-name> <servlet-class> org.springframework.web.servlet.dispatcherervlet </servl et-class> <load-on-startup> 1 </load-on-startup> </servlet> <servlet-mapping> <servlet-name> mvc-dispatcher </servlet-name> <url-pattern>/</url-pattern> </servlet-mapping>
2. Web.xml과 동일한 디렉토리에서 MVC-Dispatcher-Servlet.xml 파일을 구성하십시오. 이 파일 이름의 이전 부분은 web.xml에서 구성한 Dispatcherservlet의 서블릿 이름에 해당해야합니다. 내용은 다음과 같습니다.
프로그램 코드
<beans xmlns = "http://www.springframework.org/schema/beans"xmlns : context = "http://www.springframework.org/schema/context"xmlns : mvc = "http://wwww.spramfram.org/mlns. xmlns : xsi = "http://www.w3.org/2001/xmlschema-instance"xsi : schemalocation = "http://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.or g/schema/mvchttp : //www.springframework.org/schema/mvc/spring-mvc-3.0.xsd "> <context : component-scan BASE-PACKAGE = "COM.YIHAOMEN.CONTROLLER"/> <MVC : 주석 구동/> <MVC : 리소스 매핑 = "/static/**"location = "/web-inf/static/"/> <mvc : 기본 수면 핸들러 //> <beanclass = "org.springframework.web.servlet.view.internalresourceviewresolver"> <property name = "prefix"> <value>/web-inf/pages/</value> </property> </property> </beans>
3. 소스 코드 디렉토리 구성 디렉토리에서 스프링 구성 파일 ApplicationContext.xml 구성
프로그램 코드
<!-이 예제는 DBCP 연결 풀을 사용하며 DBCP JAR 패키지는 프로젝트의 LIB 디렉토리에 미리 복사해야합니다. -> <Context : Property-Placeholder Location = "ClassPath : /config/database.properties"/> <Bean id = "DataSource"Destrous-Method = "Close" P : DriveSclassName = "com.mysql.jdbc.driver"p : url = "jdbc : mysql : //127.0.0.1 : 3306/mybatis? char id = "transactionManager"> <property name = "dataSource"ref = "dataSource"/> </bean> <bean id = "sqlsessionfactory"> <! <! <! <! <! <property name = "dataSource"ref = "dataSource"/> <!-특성 특성의 MyBatis ~ myBatis ~ myBatis indepigation Prile. 이름 = "configlocation"value = "classpath : config/configuration.xml"/> <!-모든 구성된 맵퍼 파일-> <속성 이름 = "mapperlocations"value = "classpath*: com/yihaomen/mapper/*.
어떤 이유로 든 MapperscannerConfigurer를 사용하여 모든 맵퍼 인터페이스를 스캔하면 데이터베이스 구성 데이터 소스는 데이터베이스를 사용할 수 없습니다. Properties 파일을 읽을 수 없습니다. 오류 : JDBC 드라이버 클래스 '$ {jdbc.driverClassName}'을로드 할 수 없습니다. 인터넷의 일부 사람들은 봄 3.1.1에서 SQLSESSIONFACTIONBEAN 주입을 사용하면 해결할 수 있지만 Spring 3.1.3을 사용하는 데 여전히 문제가 있으므로 XML 파일에서 데이터베이스 연결 정보를 직접 구성해야한다고 말합니다.
4. 컨트롤러 계층을 작성하십시오
프로그램 코드
패키지 com.yihaomen.controller; import java.util.list; import javax.servlet.http.htttp.httpservletrequest; import javax.servlet.http.httpervletresponse; import org.spramework.beans.annotation.autowired; org.springframework.stereotype.controller; import org.springframework.web.bind.annotation.requestmapping; import org.sprameframework.web.servlet.modelandview; import com.yihaomen.inter.iuseroperation; import com.yihaomen.model.tricticle;@controller@"/"/"" usercontroller {@autowirediuseroperation usermapper; @requestmapping ( "/list") public modelandview list (httpservletrequest request, httpservletreponse 응답) {list <article> articles = usermapper.getuserarticles (1); ModelAndView mav = new ModelAndView ( "List"); Mav.AdDoBject ( "Articles", Articles); return Mav;}}5. 페이지 파일 :
<c : foreach items = "$ {articles}"var = "item"> $ {item.id}-$ {item.title}-$ {item.content} <br /> < /c : foreach>실행 결과 :
물론 mybatis의 configure.xml configuration 파일도 있습니다. 유일한 차이점은 더 이상 다음을 구성 할 필요가 없다는 것입니다. <mapper resource = "com/yihaomen/mapper/user.xml"/>, <property name = "mapperlocations"value = "classpath*: com/yihaomen/mapper/.
데이터베이스 다운로드 :
파일 스프링 MVC 데이터베이스 테스트 파일을 다운로드하십시오
Mybatis Explication Tutorial (Mybatis in Action) 7 : Mybatis 페이징 구현 (소스 코드 다운로드)
이전 기사는 이미 Mybatis와 Spring MVC의 통합에 대해 이야기했으며 모든 기사 목록을 표시하기위한 목록 디스플레이를 만들었지 만 페이지 매김은 사용되지 않았습니다. 실제 프로젝트에서는 페이지 매김이 반드시 필요합니다. 그리고 그것은 메모리 페이징이 아니라 물리적 페이징입니다. 물리적 페이징 체계의 경우 다른 데이터베이스마다 구현 방법이 다릅니다. MySQL의 경우 Limit Offset 및 Pagesize를 사용하여 구현됩니다. Oracle은 Rownum을 통해 구현됩니다. 관련 데이터베이스의 작동에 익숙하다면 확장하는 것이 매우 좋습니다. 이 기사는 MySQL을 예로 들어 설명합니다. 먼저 렌더링을 살펴 보겠습니다 (소스 코드는 기사 끝에서 다운로드 할 수 있습니다) :
MyBatis Physical Pating을 구현하는 가장 쉬운 방법 중 하나는 Mapper SQL 문에 다음 방법을 직접 작성하는 것입니다.
프로그램 코드
< "getUserArticles"parametertype = "your_params"resultmap = "resultuserarticlelist"> user.id, user.us.user.userame, user.useraddress, article, article.title, article.content, article user.id = article.user.id =} {id} limes. #{오프셋}, #{pagesize} </select>여기의 ParameterType는 귀하가 전달한 매개 변수 클래스 또는 맵에 오프셋, 페이지 규모 및 필요한 기타 매개 변수를 포함하는 맵입니다. 이런 식으로, 당신은 분명히 페이지 매김을 구현할 수 있습니다. 이것은 쉬운 방법입니다. 그러나보다 일반적인 방법은 mybatis 플러그인을 사용하는 것입니다. Mybatis 플러그인을 포함하여 인터넷에서 많은 정보를 참조했습니다. 나만의 플러그인을 작성하십시오.
프로그램 코드
패키지 com.yhaomen.util; import java.lang.reflect.field; import java.sql.connection; import java.sql.preparedstatement; import java.sql.resultset; import java.sql.sqlexception; import java.util.list; java.util.map; java.util.properties; import javax.xml.bind.bind.propertyexception; import org.apache.ibatis.builder.xml.dynamic.foreachsqlnode; import org.apache.ibatis.executor.errorcontext; import org.apache.ibator.executor; org.apache.ibatis.executor.ExecutorException;import org.apache.ibatis.executor.statement.BaseStatementHandler;import org.apache.ibatis.executor.statement.RoutingStatementHandler;import org.apache.ibatis.executor.statement.StatementHandler;import org.apache.ibatis.mapping.BoundSql;import org.apache.ibatis.mapping.MappedStatement;import org.apache.ibatis.mapping.ParameterMapping;import org.apache.ibatis.mapping.ParameterMode;import org.apache.ibatis.plugin.Interceptor;import org.apache.ibatis.plugin.Intercepts;import org.apache.ibatis.plugin.Invocation;import org.apache.ibatis.plugin.Plugin;import org.apache.ibatis.plugin.Signature;import org.apache.ibatis.reflection.MetaObject;import org.apache.ibatis.reflection.property.PropertyTokenizer;import org.apache.ibatis.session.Configuration;import org.apache.ibatis.session.ResultHandler;import org.apache.ibatis.session.RowBounds;import org.apache.ibatis.type.TypeHandler;import org.apache.ibatis.type.TypeHandlerRegistry;@Intercepts({ @Signature(type = StatementHandler.class, method = "prepare", args = { Connection.class }) }) public class PagePlugin implements Intercept {private static String dialect = "";private static String pageSqlId = "";@SuppressWarnings("unchecked")public Object intercept(Invocation ivk) throws Throwable {if (ivk.getTarget() instanceof RoutingStatementHandler) {RoutingStatementHandler statementHandler = (RoutingStatementHandler) ivk.getTarget();BaseStatementHandler delegate = (BaseStatementHandler) ReflectHelper.getValueByFieldName(statementHandler, "delegate");MappedStatement mappedStatement = (MappedStatement) ReflectHelper.getValueByFieldName(delegate, "mappedStatement");if (mappedStatement.getId().matches(pageSqlId)) {BoundSql boundSql = delegate.getBoundSql();Object parameterObject = boundSql.getParameterObject();if (parameterObject == null) {throw new NullPointerException("parameterObject error");} else {Connection connection = (Connection) ivk.getArgs()[0];String sql = boundSql.getSql();String countSql = "select count(0) from (" + sql + ") myCount";System.out.println("Total number of sql statement:"+countSql);PreparedStatement countStmt = connection.prepareStatement(countSql);BoundSql countBS = new BoundSql(mappedStatement.getConfiguration(), countSql,boundSql.getParameterMappings(), parameterObject);setParameters(countStmt, mappedStatement, countBS, parameterObject);ResultSet rs = countStmt.executeQuery();int count = 0;if (rs.next()) {count = rs.getInt(1);}rs.close();countStmt.close();PageInfo page = null;if (parameterObject instanceof PageInfo) {page = (PageInfo) parameterObject;page.setTotalResult(count);} else if(parameterObject instanceof Map){Map<String, Object> map = (Map<String, Object>)parameterObject;page = (PageInfo)map.get("page");if(page == null)page = new PageInfo();page.setTotalResult(count);}else {Field pageField = ReflectHelper.getFieldByFieldName(parameterObject, "page");if (pageField != null) {page = (PageInfo) ReflectHelper.getValueByFieldName(parameterObject, "page");if (page == null)page = new PageInfo();page.setTotalResult(count);ReflectHelper.setValueByFieldName(parameterObject,"page", page);} else {throw new NoSuchFieldException(parameterObject.getClass().getName());}}String pageSql = generatePageSql(sql, page);System.out.println("page sql:"+pageSql);ReflectHelper.setValueByFieldName(boundSql, "sql", pageSql);}}} return ivk.proceed();}private void setParameters(PreparedStatement ps,MappedStatement mappedStatement, BoundSql boundSql,Object parameterObject) throws SQLException {ErrorContext.instance().activity("setting parameters").object(mappedStatement.getParameterMap().getId());List<ParameterMapping> parameterMappings = boundSql.getParameterMappings();if (parameterMappings != null) {Configuration configuration = mappedStatement.getConfiguration();TypeHandlerRegistry typeHandlerRegistry = configuration.getTypeHandlerRegistry();MetaObject metaObject = parameterObject == null ? null: configuration.newMetaObject(parameterObject);for (int i = 0; i < parameterMappings.size(); i++) {ParameterMapping parameterMapping = parameterMappings.get(i);if (parameterMapping.getMode() != ParameterMode.OUT) {Object value;String propertyName = parameterMapping.getProperty();PropertyTokenizer prop = new PropertyTokenizer(propertyName);if (parameterObject == null) {value = null;} else if (typeHandlerRegistry.hasTypeHandler(parameterObject.getClass())) {value = parameterObject;} else if (boundSql.hasAdditionalParameter(propertyName)) {value = boundSql.getAdditionalParameter(propertyName);} else if (propertyName.startsWith(ForEachSqlNode.ITEM_PREFIX)&& boundSql.hasAdditionalParameter(prop.getName())) {value = boundSql.getAdditionalParameter(prop.getName());if (value != null) {value = configuration.newMetaObject(value).getValue(propertyName.substring(prop.getName().length()));}} else {value = metaObject == null ? null : metaObject.getValue(propertyName);}TypeHandler typeHandler = parameterMapping.getTypeHandler();if (typeHandler == null) {throw new ExecutorException("There was no TypeHandler found for parameter "+ propertyName + " of statement "+ mappedStatement.getId());}typeHandler.setParameter(ps, i + 1, value,parameterMapping.getJdbcType());}}}} private String generatePageSql(String sql, PageInfo page) {if (page != null && (dialect !=null || !dialect.equals(""))) {StringBuffer pageSql = new StringBuffer();if ("mysql".equals(dialect)) {pageSql.append(sql);pageSql.append("limit " + page.getCurrentResult() + ","+ page.getShowCount());} else if ("oracle".equals(dialect)) {pageSql.append("select * from (select tmp_tb.*,ROWNUM row_id from (");pageSql.append(sql);pageSql.append(") tmp_tb where ROWNUM<=");pageSql.append(page.getCurrentResult() + page.getShowCount());pageSql.append(") where row_id>");pageSql.append(page.getCurrentResult());} return pageSql.toString();} else { return sql;}}public Object plugin(Object arg0) {// TODO Auto-generated method stubreturn Plugin.wrap(arg0, this);}public void setProperties(Properties p) {dialect = p.getProperty("dialect");if (dialect ==null || dialect.equals("")) {try {throw new PropertyException("dialect property is not found!");} catch (PropertyException e) {// TODO Auto-generated catch blocke.printStackTrace();}}pageSqlId = p.getProperty("pageSqlId");if (dialect ==null || dialect.equals("")) {try {throw new PropertyException("pageSqlId property is not found!");} catch (PropertyException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}}}此插件有两个辅助类:PageInfo,ReflectHelper,你可以下载源代码参考。
写了插件之后,当然需要在mybatis 的配置文件Configuration.xml 里配置这个插件
程序代码
<plugins><plugin interceptor="com.yihaomen.util.PagePlugin"><property name="dialect" value="mysql" /><property name="pageSqlId" value=".*ListPage.*" /></plugin></plugins>
请注意,这个插件定义了一个规则,也就是在mapper中sql语句的id 必须包含ListPage才能被拦截。否则将不会分页处理.
插件写好了,现在就可以在spring mvc 中的controller 层中写一个方法来测试这个分页:
程序代码
@RequestMapping("/pagelist")public ModelAndView pageList(HttpServletRequest request,HttpServletResponse response){int currentPage = request.getParameter("page")==null?1:Integer.parseInt(request.getParameter("page"));int pageSize = 3;if (currentPage<=0){currentPage =1;}int currentResult = (currentPage-1) * pageSize;System.out.println(request.getRequestURI());System.out.println(request.getQueryString());PageInfo page = new PageInfo();page.setShowCount(pageSize);page.setCurrentResult(currentResult);List<Article> articles=iUserOperation.selectArticleListPage(page,1);System.out.println(page);int totalCount = page.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) );//制定视图,也就是list.jspModelAndView mav=new ModelAndView("list");mav.addObject("articles",articles);mav.addObject("pageStr",pageStr);return mav;}然后运行程序,进入分页页面,你就可以看到结果了:
相关jar 包下载,请到下载这里例子中的jar
http://www.yihaomen.com/article/java/318.htm (文章最后有源代码下载,里面有jar 包,拷贝到上面源代码里面所需要的lib 目录下.)
另外,你还得在前面提到的数据库artilce表里面,多插入一些记录,分页效果就更好。
mybatis实战教程(mybatis in action)之八:mybatis 动态sql语句
mybatis 的动态sql语句是基于OGNL表达式的。可以方便的在sql 语句中实现某些逻辑. 总体说来mybatis 动态SQL 语句主要有以下几类:
1. if 语句(简单的条件判断)
2. choose (when,otherwize) ,相当于java 语言中的switch ,与jstl 中的choose 很类似.
3. trim (对包含的内容加上prefix,或者suffix 等,前缀,后缀)
4. where (主要是用来简化sql语句中where条件判断的,能智能的处理and or ,不必担心多余导致语法错误)
5. set (主要用于更新时)
6. foreach (在实现mybatis in 语句查询时特别有用)
下面分别介绍这几种处理方式
1. mybaits if 语句处理
程序代码
<select id="dynamicIfTest" parameterType="Blog" resultType="Blog">select * from t_blog where 1 = 1<if test="title != null">and title = #{title}</if><if test="content != null">and content = #{content}</if><if test="owner != null">and owner = #{owner}</if></select>这条语句的意思非常简单,如果你提供了title参数,那么就要满足title=#{title},同样如果你提供了Content和Owner的时候,它们也需要满足相应的条件,之后就是返回满足这些条件的所有Blog,这是非常有用的一个功能,以往我们使用其他类型框架或者直接使用JDBC的时候, 如果我们要达到同样的选择效果的时候,我们就需要拼SQL语句,这是极其麻烦的,比起来,上述的动态SQL就要简单多了
2.2. choose (when,otherwize) , equivalent to switch in java language, very similar to choice in jstl
程序代码
<select id="dyamicChooseTest" parameterType="Blog" resultType="Blog">select * from t_blog where 1 = 1 <choose><when test="title != null">and title = #{title}</when><when test="content != null">and content = #{content}</when><otherwise>and owner = "owner1"</otherwise></choose></select>when元素表示当when中的条件满足的时候就输出其中的内容,跟JAVA中的switch效果差不多的是按照条件的顺序,当when中有条件满足的时候,就会跳出choose,即所有的when和otherwise条件中,只有一个会输出,当所有的我很条件都不满足的时候就输出otherwise中的内容。所以上述语句的意思非常简单, 当title!=null的时候就输出and titlte = #{title},不再往下判断条件,当title为空且content!=null的时候就输出and content = #{content},当所有条件都不满足的时候就输出otherwise中的内容。
3.trim (对包含的内容加上prefix,或者suffix 等,前缀,后缀)
程序代码
<select id="dynamicTrimTest" parameterType="Blog" resultType="Blog">select * from t_blog <trim prefix="where" prefixOverrides="and |or"><if test="title != null">title = #{title}</if><if test="content != null">and content = #{content}</if><if test="owner != null">or owner = #{owner}</if></trim></select>trim元素的主要功能是可以在自己包含的内容前加上某些前缀,也可以在其后加上某些后缀,与之对应的属性是prefix和suffix;可以把包含内容的首部某些内容覆盖,即忽略,也可以把尾部的某些内容覆盖,对应的属性是prefixOverrides和suffixOverrides;正因为trim有这样的功能,所以我们也可以非常简单的利用trim来代替where元素的功能
4. where (主要是用来简化sql语句中where条件判断的,能智能的处理and or 条件
程序代码
<select id="dynamicWhereTest" parameterType="Blog" resultType="Blog">select * from t_blog <where><if test="title != null">title = #{title}</if><if test="content != null">and content = #{content}</if><if test="owner != null">and owner = #{owner}</if></where></select>where元素的作用是会在写入where元素的地方输出一个where,另外一个好处是你不需要考虑where元素里面的条件输出是什么样子的,MyBatis会智能的帮你处理,如果所有的条件都不满足那么MyBatis就会查出所有的记录,如果输出后是and 开头的,MyBatis会把第一个and忽略,当然如果是or开头的,MyBatis也会把它忽略;此外,在where元素中你不需要考虑空格的问题,MyBatis会智能的帮你加上。像上述例子中,如果title=null, 而content != null,那么输出的整个语句会是select * from t_blog where content = #{content},而不是select * from t_blog where and content = #{content},因为MyBatis会智能的把首个and 或or 给忽略。
5.set (主要用于更新时)
程序代码
<update id="dynamicSetTest" parameterType="Blog">update t_blog<set><if test="title != null">title = #{title},</if><if test="content != null">content = #{content},</if><if test="owner != null">owner = #{owner}</if></set>where id = #{id}</update>set元素主要是用在更新操作的时候,它的主要功能和where元素其实是差不多的,主要是在包含的语句前输出一个set,然后如果包含的语句是以逗号结束的话将会把该逗号忽略,如果set包含的内容为空的话则会出错。有了set元素我们就可以动态的更新那些修改了的字段
6. foreach (在实现mybatis in 语句查询时特别有用)
foreach的主要用在构建in条件中,它可以在SQL语句中进行迭代一个集合。foreach元素的属性主要有item,index,collection,open,separator,close。item表示集合中每一个元素进行迭代时的别名,index指定一个名字,用于表示在迭代过程中,每次迭代到的位置,open表示该语句以什么开始,separator表示在每次进行迭代之间以什么符号作为分隔符,close表示以什么结束,在使用foreach的时候最关键的也是最容易出错的就是collection属性,该属性是必须指定的,但是在不同情况下,该属性的值是不一样的,主要有一下3种情况:
如果传入的是单参数且参数类型是一个List的时候,collection属性值为list
如果传入的是单参数且参数类型是一个array数组的时候,collection的属性值为array
如果传入的参数是多个的时候,我们就需要把它们封装成一个Map了,当然单参数也可以封装成map,实际上如果你在传入参数的时候,在MyBatis里面也是会把它封装成一个Map的,map的key就是参数名,所以这个时候collection属性值就是传入的List或array对象在自己封装的map里面的key
1.1. Type of single parameter List
程序代码
<select id="dynamicForeachTest" resultType="Blog">select * from t_blog where id in<foreach collection="list" index="index" item="item" open="(" separator="," close=")">#{item}</foreach></select>上述collection的值为list,对应的Mapper是这样的
程序代码
public List<Blog> dynamicForeachTest(List<Integer> ids);
测试代码
@Testpublic void dynamicForeachTest() {SqlSession session = Util.getSqlSessionFactory().openSession();BlogMapper blogMapper = session.getMapper(BlogMapper.class);List<Integer> ids = new ArrayList<Integer>();ids.add(1);ids.add(3);ids.add(6);List<Blog> blogs = blogMapper.dynamicForeachTest(ids);for (Blog blog : blogs)System.out.println(blog);session.close();}2.数组类型的参数
程序代码
<select id="dynamicForeach2Test" resultType="Blog">select * from t_blog where id in<foreach collection="array" index="index" item="item" open="(" separator="," close=")">#{item}</foreach></select>对应mapper
程序代码
public List<Blog> dynamicForeach2Test(int[] ids);
3. Map 类型的参数
程序代码
<select id="dynamicForeach3Test" resultType="Blog">select * from t_blog where title like "%"#{title}"%" and id in<foreach collection="ids" index="index" item="item" open="(" separator="," close=")">#{item}</foreach></select>mapper 应该是这样的接口:
程序代码
public List<Blog> dynamicForeach3Test(Map<String, Object> params);
通过以上方法,就能完成一般的mybatis 的动态SQL 语句.最常用的就是if where foreach这几个,一定要重点掌握.
mybatis实战教程(mybatis in action)之九:mybatis 代码生成工具的使用
mybatis 应用程序,需要大量的配置文件,对于一个成百上千的数据库表来说,完全手工配置,这是一个很恐怖的工作量. 所以mybatis 官方也推出了一个mybatis代码生成工具的jar包. 今天花了一点时间,按照mybatis generator 的doc 文档参考,初步配置出了一个可以使用的版本,我把源代码也提供下载,mybatis 代码生成工具,主要有一下功能:
1.生成pojo 与数据库结构对应
2.如果有主键,能匹配主键
3.如果没有主键,可以用其他字段去匹配
4.动态select,update,delete 方法
5.自动生成接口(也就是以前的dao层)
6.自动生成sql mapper,增删改查各种语句配置,包括动态where语句配置
7.生成Example 例子供参考
下面介绍下详细过程
1. 创建测试工程,并配置mybatis代码生成jar包下载地址:http://code.google.com/p/mybatis/downloads/list?can=3&q=Product%3DGenerator
mysql 驱动下载:http://dev.mysql.com/downloads/connector/j/
这些jar包,我也会包含在源代码里面,可以在文章末尾处,下载源代码,参考。
用eclipse 建立一个dynamic web project。
解压下载后的mybatis-generator-core-1.3.2-bundle.zip 文件,其中有两个目录:一个目录是文档目录docs,主要介绍这个代码生成工具如何使用,另一个是lib目录,里面的内容主要是jar 包,这里我们需要mybatis-generator-core-1.3.2.jar,这个jar 包. 将它拷贝到我们刚刚创建的web工程的WebContent/WEB-INF/lib 目录下.在这个目录下也放入mysql 驱动jar包.因为用mysql 做测试的.
2.在数据库中创建测试表
在mybatis数据库中创建用来测试的category表(如果没有mybatis这个数据库,要创建,这是基于前面这个系列文章而写的,已经有了mybatis 这个数据库)
程序代码
Drop TABLE IF EXISTS `category`;Create TABLE `category` (`id` int(11) NOT NULL AUTO_INCREMENT,`catname` varchar(50) NOT NULL,`catdescription` varchar(200) DEFAULT NULL,PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;
3. 配置mybatis 代码生成工具的配置文件
在创建的web工程中,创建相应的package 比如:
com.yihaomen.inter 用来存放mybatis 接口对象.
com.yihaomen.mapper用来存放sql mapper对应的映射,sql语句等.
com.yihaomen.model 用来存放与数据库对应的model 。
在用mybatis 代码生成工具之前,这些目录必须先创建好,作为一个好的应用程序,这些目录的创建也是有规律的。
根据mybatis代码生成工具文档,需要一个配置文件,这里命名为:mbgConfiguration.xml 放在src 目录下. 配置文件内容如下:
程序代码
< ?xml version="1.0" encoding="UTF-8"?>< !DOCTYPE generatorConfigurationPUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN""http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">< generatorConfiguration><!-- 配置mysql 驱动jar包路径.用了绝对路径--><classPathEntry location="D:/Work/Java/eclipse/workspace/myBatisGenerator/WebContent/WEB-INF/lib/mysql-connector-java-5.1.22-bin.jar" /><context id="yihaomen_mysql_tables" targetRuntime="MyBatis3"><!-- 为了防止生成的代码中有很多注释,比较难看,加入下面的配置控制--><commentGenerator><property name="suppressAllComments" value="true" /><property name="suppressDate" value="true" /></commentGenerator><!-- 注释控制完毕--><!-- 数据库连接--><jdbcConnection driverClass="com.mysql.jdbc.Driver"connectionURL="jdbc:mysql://127.0.0.1:3306/mybatis?characterEncoding=utf8"userId="root"password="password"></jdbcConnection><javaTypeResolver ><property name="forceBigDecimals" value="false" /></javaTypeResolver><!-- 数据表对应的model 层--><javaModelGenerator targetPackage="com.yihaomen.model" targetProject="src"><property name="enableSubPackages" value="true" /><property name="trimStrings" value="true" /></javaModelGenerator><!-- sql mapper 隐射配置文件--><sqlMapGenerator targetPackage="com.yihaomen.mapper" targetProject="src"><property name="enableSubPackages" value="true" /></sqlMapGenerator><!-- 在ibatis2 中是dao层,但在mybatis3中,其实就是mapper接口--><javaClientGenerator type="XMLMAPPER" targetPackage="com.yihaomen.inter" targetProject="src"><property name="enableSubPackages" value="true" /></javaClientGenerator><!-- 要对那些数据表进行生成操作,必须要有一个. --><table schema="mybatis" tableName="category" domainObjectName="Category" enableCountByExample="false" enableUpdateByExample="false"enableDeleteByExample="false" enableSelectByExample="false"selectByExampleQueryId="false"> </table></context>< /generatorConfiguration>
用一个main 方法来测试能否用mybatis 成生成刚刚创建的`category`表对应的model,sql mapper等内容.
创建一个com.yihaomen.test 的package ,并在此package 下面建立一个测试的类GenMain:
程序代码
package com.yihaomen.test;import java.io.File;import java.io.IOException;import java.sql.SQLException;import java.util.ArrayList;import java.util.List;import org.mybatis.generator.api.MyBatisGenerator;import org.mybatis.generator.config.Configuration;import org.mybatis.generator.config.xml.ConfigurationParser;import org.mybatis.generator.exception.InvalidConfigurationException;import org.mybatis.generator.exception.XMLParserException;import org.mybatis.generator.internal.DefaultShellCallback;public class GenMain {public static void main(String[] args) {List<String> warnings = new ArrayList<String>();boolean overwrite = true;String genCfg = "/mbgConfiguration.xml";File configFile = new File(GenMain.class.getResource(genCfg).getFile());ConfigurationParser cp = new ConfigurationParser(warnings);Configuration config = null;try {config = cp.parseConfiguration(configFile);} catch (IOException e) {e.printStackTrace();} catch (XMLParserException e) {e.printStackTrace();}DefaultShellCallback callback = new DefaultShellCallback(overwrite);MyBatisGenerator myBatisGenerator = null;try {myBatisGenerator = new MyBatisGenerator(config, callback, warnings);} catch (InvalidConfigurationException e) {e.printStackTrace();}try {myBatisGenerator.generate(null);} catch (SQLException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} catch (InterruptedException e) {e.printStackTrace();}}}到此为止,eclipse项目工程图应该如下:
4.运行测试的main 方法,生成mybatis 相关代码
运行GenMain类里的main方法,并刷新工程,你会发现各自package 目录下已经响应生成了对应的文件,完全符合mybatis 规则,效果图如下:
5.注意事项
如果你想生成example 之类的东西,需要在<table></table>里面去掉
程序代码
enableCountByExample="false" enableUpdateByExample="false"enableDeleteByExample="false" enableSelectByExample="false"selectByExampleQueryId="false"
这部分配置,这是生成Example而用的,一般来说对项目没有用.
另外生成的sql mapper 等,只是对单表的增删改查,如果你有多表join操作,你就可以手动配置,如果调用存储过程,你也需要手工配置. 这时工作量已经少很多了。
如果你想用命令行方式处理,也是可以的.
程序代码
예를 들어:
java -jar mybatis-generator-core-1.3.2.jar -mbgConfiguration.xm -overwrite
这时,要用绝对路径才行. 另外mbgConfiguration.xml 配置文件中targetProject 的配置也必须是绝对路径了。
mybatis SqlSessionDaoSupport的使用
前面的系列mybatis 文章,已经基本讲到了mybatis的操作,但都是基于mapper隐射操作的,在mybatis 3中这个mapper 接口貌似充当了以前在ibatis 2中的DAO 层的作用。但事实上,如果有这个mapper接口不能完成的工作,或者需要更复杂的扩展的时候,你就需要自己的DAO 层. 事实上mybatis 3 也是支持DAO 层设计的,类似于ibatis 2 .下面介绍下.
首先创建一个com.yihaomen.dao的package.然后在里面分别创建接口UserDAO,以及实现该接口的UserDAOImpl
程序代码
package com.yihaomen.dao;import java.util.List;import com.yihaomen.model.Article;public interface UserDAO {public List<Article> getUserArticles(int userid);}程序代码
package com.yihaomen.dao;import java.util.List;import org.mybatis.spring.support.SqlSessionDaoSupport;import org.springframework.stereotype.Repository;import com.yihaomen.model.Article;@Repositorypublic class UserDAOImpl extends SqlSessionDaoSupport implements UserDAO {@Overridepublic List<Article> getUserArticles(int userid) { return this.getSqlSession().selectList("com.yihaomen.inter.IUserOperation.getUserArticles",userid);}}执行的SQL 语句采用了命名空间+sql 语句id的方式,后面是参数.
注意继承了"SqlSessionDaoSupport" ,利用方法getSqlSession() 可以得到SqlSessionTemplate ,从而可以执行各种sql语句,类似于hibernatetemplate一样,至少思路一样.
如果与spring 3 mvc 集成要用autowire的话,在daoimpl 类上加上注解“@Repository” ,另外还需要在spring 配置文件中加入<context:component-scan base-package="com.yihaomen.dao" /> 这样在需要调用的地方,就可以使用autowire自动注入了。
当然,你也可以按一般程序的思路,创建一个service 的package, 用service 去调用dao层,我这里就没有做了,因为比较简单,用类似的方法,也机注意自动注入时,也要配置<context:component-scan base-package="com.yihaomen.service" /> 等这样的。
在controller层中测试,直接调用dao层方法在controller中加入方法:
程序代码
@AutowiredUserDAO userDAO;.......@RequestMapping("/daolist")public ModelAndView listalldao(HttpServletRequest request,HttpServletResponse response){List<Article> articles=userDAO.getUserArticles(1);//制定视图,也就是list.jspModelAndView mav=new ModelAndView("list");mav.addObject("articles",articles);return mav;}这样可以得到同样的结果,而且满足了一般程序的设计方法.代码结构如下:
以上所述是本文给大家介绍的Mybatis实战教程之入门到精通(经典)的相关知识,希望对大家有所帮助。