『壹』 SpringBoot集成Mybatis 找不到Mapper里的介面
mybatis 的springboot 集成項目已猛巧拆經發寬配布了
maven
12345<dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>1.0.0</version></dependency>枝棗
properties 配置
123456mybatis.config= # mybatis config filemybatis.mapperLocations= # mappers filemybatis.typeAliasesPackage= # domain object's package mybatis.typeHandlersPackage= # handler's packagemybatis.check-config-location= # check the mybatis configuration existsmybatis.executorType= # mode of execution. Default is SIMPLE
『貳』 如何通過介面查找對應的mapper.xml及方
在使用mybatis的時候,有一種方式是
BookMapper bookMapper = SqlSession().getMapper(BookMapper.class)
獲取介面,然後茄森爛調用介面的方法。只要方法名和對應的mapper.xml中的id名字相同,就可以執行sql。
那麼介面是如何與mapper.xml對應的呢?
首先看下,在getMapper()方法是如何操作的。
在DefaultSqlSession.java中調用了configuration.getMapper()
public <T> T getMapper(Class<T> type) {
return configuration.<T>getMapper(type, this);
}
在Configuration.java中調用了mapperRegistry.getMapper(type, sqlSession);
public <T> T getMapper(Class<T> type, SqlSession sqlSession) {
return mapperRegistry.getMapper(type, sqlSession);
}
下面重點來了,在MapperRegistry.java中實現了動態代理
public <T> T getMapper(Class<T> type, SqlSession sqlSession) {
final MapperProxyFactory<T> mapperProxyFactory = (MapperProxyFactory<T>) knownMappers.get(type);
if (mapperProxyFactory == null)
throw new BindingException("Type " + type + " is not known to the MapperRegistry.");
try {
return mapperProxyFactory.newInstance(sqlSession);
} catch (Exception e) {
throw new BindingException("Error getting mapper instance. Cause: " + e, e);
}
}
這個函數分兩部分來看,首先是從map集合中獲取介面代理,map集合的來源,第二部分獲取代理後實例春雹化,獲取介面的方法,執行sql。
對於第一部分:集合的來源。
這顫漏個MapperRegistry.java中有個方法是addMappers();共有兩個重載。
public void addMappers(String packageName, Class<?> superType) {
ResolverUtil<Class<?>> resolverUtil = new ResolverUtil<Class<?>>();
//通過包名,查找該包下所有的介面進行遍歷,放入集合中
resolverUtil.find(new ResolverUtil.IsA(superType), packageName);
Set<Class<? extends Class<?>>> mapperSet = resolverUtil.getClasses();
for (Class<?> mapperClass : mapperSet) {
addMapper(mapperClass);
}
}
//解析包名下的介面
public void addMappers(String packageName) {
addMappers(packageName, Object.class);
}
往上追溯該方法的調用是在SqlSessionFactory.build();時對配置文件的解析,其中對節點mappers的解析,這里先不贅述,
mapperElement(root.evalNode("mappers"));
private void mapperElement(XNode parent) throws Exception {
if (parent != null) {
for (XNode child : parent.getChildren()) {
//使用package節點進行解析配置
if ("package".equals(child.getName())) {
String mapperPackage = child.getStringAttribute("name");
//注冊包下的介面
configuration.addMappers(mapperPackage);
} else {
//使用mapper節點
String resource = child.getStringAttribute("resource");
String url = child.getStringAttribute("url");
String mapperClass = child.getStringAttribute("class");
if (resource != null && url == null && mapperClass == null) {
ErrorContext.instance().resource(resource);
InputStream inputStream = Resources.getResourceAsStream(resource);
XMLMapperBuilder mapperParser = new XMLMapperBuilder(inputStream, configuration, resource, configuration.getSqlFragments());
mapperParser.parse();
} else if (resource == null && url != null && mapperClass == null) {
ErrorContext.instance().resource(url);
InputStream inputStream = Resources.getUrlAsStream(url);
XMLMapperBuilder mapperParser = new XMLMapperBuilder(inputStream, configuration, url, configuration.getSqlFragments());
mapperParser.parse();
} else if (resource == null && url == null && mapperClass != null) {
Class<?> mapperInterface = Resources.classForName(mapperClass);
configuration.addMapper(mapperInterface);
} else {
throw new BuilderException("A mapper element may only specify a url, resource or class, but not more than one.");
}
}
}
}
}
這是調用addMapper()的順序。
同時在改方法中還有一個方法很重要
public <T> void addMapper(Class<T> type) {
if (type.isInterface()) {
if (hasMapper(type)) {
throw new BindingException("Type " + type + " is already known to the MapperRegistry.");
}
boolean loadCompleted = false;
try {
knownMappers.put(type, new MapperProxyFactory<T>(type));
//根據介面名尋找同包下同名的xml或者mapper的namespace是該介面的xml
//找到對用的xml後進行解析mapper節點裡面的節點
MapperAnnotationBuilder parser = new MapperAnnotationBuilder(config, type);
parser.parse();
loadCompleted = true;
} finally {
if (!loadCompleted) {
knownMappers.remove(type);
}
}
}
}
這是通過介面的全路徑來查找對應的xml。這里有兩種方式解析,也就是我們平常xml文件放置位置的兩種寫法。
第一種是不加namespace,把xml文件放在和介面相同的路徑下,同時xml的名字與介面名字相同,如介面名為Student.java,xml文件為Student.xml。在相同的包下。這種當時可以不加namespace.
第二種是加namespace,通過namespace來查找對應的xml.
到這就是介面名和xml的全部注冊流程。
下面再說下第二部分就是通過動態代理獲取介面名字來對應xml中的id。
主要有兩個類MapperProxyFactory.java和MapperProxy.java
對於MapperProxyFactory.java
public class MapperProxyFactory<T> {
private final Class<T> mapperInterface;
private Map<Method, MapperMethod> methodCache = new ConcurrentHashMap<Method, MapperMethod>();
//構造函數,獲取介面類
public MapperProxyFactory(Class<T> mapperInterface) {
this.mapperInterface = mapperInterface;
}
public Class<T> getMapperInterface() {
return mapperInterface;
}
public Map<Method, MapperMethod> getMethodCache() {
return methodCache;
}
@SuppressWarnings("unchecked")
protected T newInstance(MapperProxy<T> mapperProxy) {
return (T) Proxy.newProxyInstance(mapperInterface.getClassLoader(), new Class[] { mapperInterface }, mapperProxy);
}
//供外部調用
public T newInstance(SqlSession sqlSession) {
final MapperProxy<T> mapperProxy = new MapperProxy<T>(sqlSession, mapperInterface, methodCache);
return newInstance(mapperProxy);
}
}
在MapperProxy.java中進行方法的執行
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { if (Object.class.equals(method.getDeclaringClass())) { try { return method.invoke(this, args); } catch (Throwable t) { throw ExceptionUtil.unwrapThrowable(t); } } final MapperMethod mapperMethod = cachedMapperMethod(method);
//方法的執行
return mapperMethod.execute(sqlSession, args);
}
private MapperMethod cachedMapperMethod(Method method) { MapperMethod mapperMethod = methodCache.get(method); if (mapperMethod == null) { mapperMethod = new MapperMethod(mapperInterface, method, sqlSession.getConfiguration()); methodCache.put(method, mapperMethod); } return mapperMethod;
}
至此,就是mybatis所有介面和xml的載入,以及通過動態代理來進行介面的執行的過程。
『叄』 如何配置mybatis開發環境
1、打開MyEclipse或者Eclipse,新建一個JavaProject項目mybatis
謝謝採納
『肆』 mybatis怎麼做聯合查詢
MyBatis之多表聯合查詢
在這篇文章裡面主要講解如何在mybatis裡面使用一對一、一對多、多表聯合查詢(類似視圖)操作的例子。
註:閱讀本文前請先大概看一下之前兩篇文章。
一、表結構
班級表class,學生表student,班級學生關系表ClassStudent。
這里一個學生只會在一個班級裡面,也就是一對一的關系;一個班級有多個學生,也就是一對多的關系。
結構如下:
CREATE TABLE [dbo].[Class](
[class_id] [int] NOT NULL,
[class_name] [varchar](50) NOT NULL,
CONSTRAINT [PK_Class] PRIMARY KEY CLUSTERED
(
[class_id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
CREATE TABLE [dbo].[ClassStudent](
[class_id] [int] NOT NULL,
[student_id] [int] NOT NULL
) ON [PRIMARY]
CREATE TABLE [dbo].[Student](
[s_id] [int] NOT NULL,
[s_name] [varchar](50) NOT NULL,
CONSTRAINT [PK_Student] PRIMARY KEY CLUSTERED
(
[s_id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
3張表的數據如下:
insert into Class values(1,'三(1)班')
insert into Class values(2,'三(2)班')
insert into Class values(3,'三(3)班')
insert into Class values(4,'三(4)班')
insert into Student values(1001,'張三')
insert into Student values(1002,'李四')
insert into Student values(1003,'趙五')
insert into Student values(1004,'王二麻子')
insert into ClassStudent values(1,1001)
insert into ClassStudent values(1,1003)
insert into ClassStudent values(4,1002)
insert into ClassStudent values(3,1004)
二、在原項目下新建一個包com.mybatis.sqljoinrelation,在包裡面新建一個sqlMapper.xml的映射文件,在項目的mybatis的配置文件conf.xml中對這個sqlMapper.xml進行注冊,注冊片段如下:
<!-- 注冊映射文件 -->
<mappers>
<mapper resource="com/mybatis/sqljoinrelation/sqlMapper.xml" />
</mappers>
緊接著在原項目下再新建一個包com.mybatis.bean,在裡面新建實體類
學生:
package com.mybatis.bean;
/**
* 學生(臨時)
*/
public class StudentTemp {
private int studentid;
private String studentname;
private Class tempClass;
public Class getTempClass() {
return tempClass;
}
public void setTempClass(Class tempClass) {
this.tempClass = tempClass;
}
public int getStudentid() {
return studentid;
}
public void setStudentid(int studentid) {
this.studentid = studentid;
}
public String getStudentname() {
return studentname;
}
public void setStudentname(String studentname) {
this.studentname = studentname;
}
@Override
public String toString() {
return "StudentTemp [studentid=" + studentid + ", studentname="
+ studentname + ", tempClass=" + tempClass + "]";
}
}
班級:
package com.mybatis.bean;
/**
* 班級
*/
public class Class {
private int classid;
private String classname;
public int getClassid() {
return classid;
}
public void setClassid(int classid) {
this.classid = classid;
}
public String getClassname() {
return classname;
}
public void setClassname(String classname) {
this.classname = classname;
}
@Override
public String toString() {
return "Class [classid=" + classid + ", classname=" + classname + "]";
}
}
學生班級視圖類:
package com.mybatis.bean;
public class studentclass {
private int s_id;
private String s_name;
private int class_id;
private String class_name;
public int getS_id() {
return s_id;
}
public void setS_id(int s_id) {
this.s_id = s_id;
}
public String getS_name() {
return s_name;
}
public void setS_name(String s_name) {
this.s_name = s_name;
}
public int getClass_id() {
return class_id;
}
public void setClass_id(int class_id) {
this.class_id = class_id;
}
public String getClass_name() {
return class_name;
}
public void setClass_name(String class_name) {
this.class_name = class_name;
}
@Override
public String toString() {
return "studentclass [s_id=" + s_id + ", s_name=" + s_name
+ ", class_id=" + class_id + ", class_name=" + class_name + "]";
}
}
三、查詢操作
1、 一對一,查詢學生編號等於1001且他所在班級信息
2、一對多,查詢班級編號等於1且包含所有學生信息
3、類似視圖查詢學生編號等於1001且他所在班級信息
sqlMapper.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="com.mybatis.sqljoinrelation.sqlMapper">
<!-- 1、 獲取某學生以及該學生所在班級的信息 -->
<!-- 可以顯示指出c.class_id,c.class_name,s.s_id,s.s_name列明,
如果用"*"代替,則mybatis會自動匹配resultMap中提供的列名 -->
<select id="getStudentAndClass" parameterType="int" resultMap="studentClassMap">
select c.class_id,c.class_name,s.s_id,s.s_name
from Class c left join ClassStudent cs
on c.class_id = cs.class_id
left join Student s
on cs.student_id = s.s_id
where s.s_id = #{id}
</select>
<!-- resultMap中的type表示返回什麼類型的對象 -->
<resultMap type="com.mybatis.bean.StudentTemp" id="studentClassMap">
<!-- property 表示com.mybatis.bean.StudentTemp中的屬性; column 表示表中的列名 -->
<id property="studentid" column="s_id" />
<result property="studentname" column="s_name" />
<!-- association字面意思關聯,這里只專門做一對一關聯; property表示是com.mybatis.bean.StudentTemp中的屬性名稱;
javaType表示該屬性是什麼類型對象 -->
<association property="tempClass" javaType="com.mybatis.bean.Class">
<!-- property 表示com.mybatis.bean.Class中的屬性; column 表示表中的列名 -->
<id property="classid" column="class_id" />
<result property="classname" column="class_name" />
</association>
</resultMap>
<!-- 2、獲取某學生以及該學生所在班級的信息,類似視圖實現方式 -->
<!-- resultType 對應簡單類型,也就是實體中的屬性名稱與資料庫表欄位名稱一模一樣;
resultMap 對應復雜類型,屬性名稱與欄位名稱不一樣可以通過resultMap中property,column進行映射 -->
<select id="getStudentAndClassView" parameterType="int" resultType="com.mybatis.bean.studentclass">
select c.class_id,c.class_name,s.s_id,s.s_name
from Class c left join ClassStudent cs
on c.class_id = cs.class_id
left join Student s
on cs.student_id = s.s_id
where s.s_id = #{id}
</select>
<!-- 3、獲取某班級以及班級裡面所有學生的信息 -->
<select id="getClassStudents" parameterType="int" resultMap="classStudentsMap">
select *
from Class c left join ClassStudent cs
on c.class_id = cs.class_id
left join Student s
on cs.student_id = s.s_id
where c.class_id = #{id}
</select>
<resultMap type="com.mybatis.bean.ClassTemp" id="classStudentsMap">
<id property="classid" column="class_id"/>
<result property="classname" column="class_name"/>
<!-- property表示集合類型屬性名稱,ofType表示集合中的對象是什麼類型 -->
<collection property="students" ofType="com.mybatis.bean.Student">
<id property="studentid" column="s_id"/>
<result property="studentname" column="s_name"/>
</collection>
</resultMap>
</mapper>
測試代碼如下:
一對一與類似視圖查詢的代碼在一起,如下:
package com.mybatis.sqljoinrelation;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import com.mybatis.util.MybatisUtils;
/**
* 一對一
*/
public class testonetoone {
public static void main(String[] args) {
SqlSessionFactory factory = MybatisUtils.getFactory();
SqlSession session = null;
try {
session = factory.openSession(true);
//1、StudentTemp
String statement1 = "com.mybatis.sqljoinrelation.sqlMapper.getStudentAndClass";
System.out.println(session.selectOne(statement1, 1001));
//2、用model類型接收數據
String statement2 = "com.mybatis.sqljoinrelation.sqlMapper.getStudentAndClassView";
System.out.println(session.selectOne(statement2, 1001));
} catch (Exception e) {
e.printStackTrace();
}finally{
session.close();
}
}
}
一對多測試代碼如下:
package com.mybatis.sqljoinrelation;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import com.mybatis.util.MybatisUtils;
/**
* 一對多
*/
public class testonetomany {
public static void main(String[] args) {
SqlSessionFactory factory = MybatisUtils.getFactory();
SqlSession session = null;
try {
session = factory.openSession(true);
//1、StudentTemp
String statement = "com.mybatis.sqljoinrelation.sqlMapper.getClassStudents";
System.out.println(session.selectOne(statement, 1));
} catch (Exception e) {
e.printStackTrace();
}finally{
session.close();
}
}
}
四、sqlMapper.xml需要說明的問題
1、一對一:<association property="tempClass" javaType="com.mybatis.bean.Class">
association字面意思關聯,這里只專門做一對一關聯; property表示是com.mybatis.bean.StudentTemp中的屬性名稱; javaType表示該屬性是什麼類型對象
2、類似視圖查詢: <select id="getStudentAndClassView" parameterType="int" resultType="com.mybatis.bean.studentclass">
resultType 對應簡單類型,也就是實體中的屬性名稱與資料庫表欄位名稱一模一樣;
resultMap 對應復雜類型,屬性名稱與欄位名稱不一樣可以通過resultMap中property,column進行映射,其中一對一與一對多都是用resultMap來映射
3、一對多:<collection property="students" ofType="com.mybatis.bean.Student">
collection字面意思是集合,這里專門做一對多關聯,property表示集合類型屬性名稱,ofType表示集合中的對象是什麼類型
4、<select>select * from ...</student>與<select>select 欄位1,欄位2,欄位3... from ...</student>
可以顯示指出c.class_id,c.class_name,s.s_id,s.s_name列明,如果用"*"代替,則mybatis會自動匹配resultMap或者resultType中提供的列名,
如果某對象存在列映射的屬性,但是在select 後面找不到這個列,則在返回結果中,該列多映射的值為null。
至此,對於一對一、一對多、視圖查詢都能很好的解決,主要還是要重點關注第四點說明。
------------------SB要封便封
『伍』 mybatis mapper介面,不同包下怎麼配置
<mappers>
<磨改!-- 通過mapper元素的resource屬性可以指定相對於祥游肢類路徑的Mapper.xml文件 -->
<mapper resource="com/springmybatis/system//謹世TestUserDao.xml" />
<!-- 通過mapper元素的class屬性可以指定Mapper介面進行注冊 -->
<mapper class="com.springmybatis.system..UserDao" />
<!-- 通過package元素將會把指定包下面的所有Mapper介面進行注冊 -->
<package name="com.springmybatis.system..transaction" />
</mappers>
『陸』 mybatis報Mapper配置文件出錯
最近學習mybatis框架時,遇到一坑,記錄一下debug過程。
操作表一對一查詢時,運行junit測試類時報錯如下:
根據錯誤提示,第一時間檢查了mapper的xml文件名稱以及對應的包名是否跟介面類的一致,確認沒有問題後,初步判定原因是 mapper映射文件問題 ,mapper內容如下:
隨後檢查mapper文件中返回類型以及實判升體類屬性、數據表對掘尺老應欄位,發現應該是由於resultMap定義的返回類型有問題,於是檢查mybatis主配困譽置文件
果不其然,調試後明確問題:
由於主配置文件只配置了<mappers>標簽下的<package>指定了介面所在包, 沒有配置<typeAliases>下的<package>指定實體類的別名,因此mapper文件中返回的實體類名稱不能使用簡寫,需要寫完整全限定類名
主配置文件指定實體類別名後測試,測試類正常返回一對一查詢的數據
『柒』 mybatis mapper.xml中怎麼設置主鍵自動生成
一個配置完整的 settings 元素的示例如下:
<settings>
<setting name="cacheEnabled" value="true"/>
<setting name="lazyLoadingEnabled" value="true"/>
<setting name="multipleResultSetsEnabled" value="true"/>
<setting name="useColumnLabel" value="true"/>
<setting name="useGeneratedKeys" value="false"/>
<setting name="autoMappingBehavior" value="PARTIAL"/>
<setting name="defaultExecutorType" value="SIMPLE"/>
<setting name="defaultStatementTimeout" value="25"/>
<setting name="safeRowBoundsEnabled" value="false"/>
<setting name="mapUnderscoreToCamelCase" value="false"/>
<setting name="localCacheScope" value="SESSION"/>
<setting name="jdbcTypeForNull" value="OTHER"/>
<setting name="lazyLoadTriggerMethods" value="equals,clone,hashCode,toString"/>
</settings>
配置環境(environments)
MyBatis 可以配置成適應多種環境,這種機制有助於將 SQL 映射應用於多種資料庫之中,現實情況下有多種理由需要這么做。例如,開發、測試和生產環境需要有不同的配置;或者共享相同 Schema 的多個生產資料庫,想使用相同的 SQL 映射。許多類似的用例。
不過要記住:盡管可以配置多個環境,每個 SqlSessionFactory 實例只能選擇其一。
所以,如果你想連接兩個資料庫,就需要創建兩個 SqlSessionFactory 實例,每個資料庫對應一個。而如果是三個資料庫閉殲,就需要三個實例,依此類推,記起來很簡單:
每個資料庫對應一個 SqlSessionFactory 實例
為了指定創建哪種環境,只要將它作為可選的參數傳遞給 SqlSessionFactoryBuilder 即可。可以接受環境配置的兩個方法簽名是:
SqlSessionFactory factory = sqlSessionFactoryBuilder.build(reader, environment);
SqlSessionFactory factory = sqlSessionFactoryBuilder.build(reader, environment,properties);
如果忽略了環境參數,那麼默認環境將會被載入,如謹滑下所示祥態臘:
SqlSessionFactory factory = sqlSessionFactoryBuilder.build(reader);
SqlSessionFactory factory = sqlSessionFactoryBuilder.build(reader,properties);
Environments配置示例
<environments default="development">
<environment id="development">
<transactionManager type="JDBC">
<property name="..." value="..."/>
</transactionManager>
<dataSource type="POOLED">
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
</environments>
<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:3306/wifi?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull" />
<property name="username" value="root" />
<property name="password" value="123456" />
</dataSource>
</environment>
</environments>
注意這里的關鍵點:
默認的環境 ID(比如:default=」development」)。
每個 environment 元素定義的環境 ID(比如:id=」development」)。
事務管理器的配置(比如:type=」JDBC」)。
數據源的配置(比如:type=」POOLED」)。
默認的環境和環境 ID 是自我解釋的。你可以使用你喜歡的名稱來命名,只要確定默認的要匹配其中之一。
映射器(mappers)
既然 MyBatis 的行為已經由上述元素配置完了,我們現在就要定義 SQL 映射語句了。但是首先我們需要告訴 MyBatis 到哪裡去找到這些語句。Java 在自動查找這方面沒有提供一個很好的方法,所以最佳的方式是告訴 MyBatis 到哪裡去找映射文件。你可以使用相對於類路徑的資源引用,或完全限定資源定位符(包括 file:/// 的 URL),或類名和包名等。例如:
<!-- Using classpath relative resources -->
<mappers>
<mapper resource="org/mybatis/builder/AuthorMapper.xml"/>
<mapper resource="org/mybatis/builder/BlogMapper.xml"/>
<mapper resource="org/mybatis/builder/PostMapper.xml"/>
</mappers>
<!-- Using url fully qualified paths -->
<mappers>
<mapper url="file:///var/mappers/AuthorMapper.xml"/>
<mapper url="file:///var/mappers/BlogMapper.xml"/>
<mapper url="file:///var/mappers/PostMapper.xml"/>
</mappers>
<!-- Using mapper interface classes -->
<mappers>
<mapper class="org.mybatis.builder.AuthorMapper"/>
<mapper class="org.mybatis.builder.BlogMapper"/>
<mapper class="org.mybatis.builder.PostMapper"/>
</mappers>
<!-- Register all interfaces in a package as mappers -->
<mappers>
<package name="org.mybatis.builder"/>
</mappers>
『捌』 spring 整合mybatis後 若mapper.java與mapper.xml不在同一文件夾,該怎麼配置
原因如下:
1、在mybatis的配置中,有些地方是可以省略的,如果你的mapper.xml文件和mapper.java文件,如果放到同一個文件夾中,就可以省略很多配置。
4、通過這個級別關系可以看出,resources和java是同一級別,而且,編譯後的文件(見上圖),都是同一個路徑,所以,就可以把他拆分出來,所以,這樣,即美觀,又實用,配置又少。
『玖』 basepackage 怎麼配置多個 目錄
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="mapperLocations">
<array>
<value>classpath:mapper/*.xml</value>
</array>
</property>
<property name="typeAliasesPackage" value="com.isea533.mybatis.model"/>
<property name="plugins">
<array>
<bean class="com.github.pagehelper.PageHelper">
<property name="properties">
<value>
dialect=hsqldb
reasonable=true
</value>
</property>
</bean>
<bean class="com.github.abel533.mapperhelper.MapperInterceptor">
<property name="properties">
<value>
mappers=com.github.abel533.mapper.Mapper
IDENTITY=MYSQL
notEmpty=true
</value>
</property>並盯棗
</bean>
</array>
</property>
</bean>
dataSource屬性
該屬性必須配置,多數據源時會有多個dataSource,同時也需要配置多個sqlSessionFactory來對應。
mapperLocations屬性
配置該屬性後,絕拆sqlSessionFactory會自動掃描該路徑下的所有文件並解析。
該路徑支持多個,可以用,;\t\n進行分割。
每一個路徑都可以用直接的包路徑,或者Ant風格的表達式。
configLocation屬則昌性
上面例子中並沒有使用該屬性,當SqlSessionFactoryBean提供的配置不能滿足使用時,你可以使用mybatis-config.xml配置文件配置其他屬性,然後通過configLocation屬性指定該配置的路徑,SqlSessionFactoryBean會使用該配置文件創建Configuration。
typeAliasesPackage屬性
該屬性可以給包中的類注冊別名,注冊後可以直接使用類名,而不用使用全限定的類名(就是不用包含包名)。
該屬性可以配置多個,可以用,;\t\n進行分割。但是不支持Ant風格的路徑。
plugins屬性
該屬性可以配置MyBatis的攔截器,攔截器的配置順序會影響攔截器的執行順序。
從上往下的攔截器,實際的執行順序是這樣,第一個攔截器會最後執行,最後一個會首先執行。
然後出攔截器的順序和配置的順序一致,第一個最先返回,最後一個最後返回。
『拾』 MyBatis 的mapper.xml配置的問題
我們知道在Mybatis中定義Mapper信息有兩種方式,一種是利用xml寫一個對應的包含Mapper信息的配置文件;另一種就是定義一個Mapper介面,然後定義一些相應的操作方法,再輔以相應的操作註解。
現假設我有這樣一個實體類:
Java代碼 收藏代碼
package com.tiantian.mybatis.model;
public class User {
private int id;
private String name;
private int age;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
它對應的資料庫表結構是這樣的:
然後我要利用Mybatis對它做一個簡單的增刪改查操作,那麼如果利用xml配置Mapper的方式來定義的話,我對應的UserMapper.xml文件會是這樣:
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="com.tiantian.mybatis.mapper.UserMapper">
<insert id="insertUser" parameterType="User" useGeneratedKeys="true" keyColumn="id">
insert into t_user(name, age) values(#{name}, #{age})
</insert>
<update id="updateUser" parameterType="User">
update t_user set name=#{name}, age=#{age} where id=#{id}
</update>
<select id="findById" parameterType="int" resultType="User">
select * from t_user where id=#{id}
</select>
<delete id="deleteUser" parameterType="int">
delete from t_user where id=#{id}
</delete>
</mapper>
如果使用介面加註解的方式,那麼我們的UserMapper介面應該這樣定義:
Java代碼 收藏代碼
package com.tiantian.mybatis.mapperinterface;
import org.apache.ibatis.annotations.Delete;
import or www.hbbz08.com g.apac he.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;
import com.tiantian.mybatis.model.User;
public interface UserMapper {
@Insert("insert into t_user(name, age) values(#{name}, #{age})")
public void insertUser(User user);
@Update("update t_user set name=#{name}, age=#{age} where id=#{id}")
public void updateUser(User user);
@Select("select * from t_user where id=#{id}")
public User findById(int id);
@Delete("delete from t_user where id=#{id}")
public void deleteUser(int id);
}
注意看這里我故意把UserMapper介面的namespace也就是它的包名置為與UserMapper.xml的namespace屬性不一樣。這主要是為了要更好的講以下的內容。
接下來要做的就是把Mapper信息注冊到Mybatis的配置中,告訴Mybatis我們定義了哪些Mapper信息。這主要是在Mybatis的配置文件中通過mappers元素來進行的。在以前版本的Mybatis中我們在Mybatis的配置文件中需要這樣定義Mapper信息資源的位置。
Xml代碼 收藏代碼
<mappers>
<mapper resource="com/tiantian/mybatis/mapper/UserMapper1.xml"/>
<mapper url="file:///E:/UserMapper.xml"/>
</mappers>
這主要是通過mapper元素的resource和url屬性來指定的,resource屬性指定的是相對於跟類路徑下的資源,url屬性指定的是通過URL可以獲取到的資源。這有一點不好的地方,當我們使用Mapper介面加註解來定義當前Mapper的操作信息時,我們還需要定義一個與它對應的Mapper.xml文件。如:
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="com.tiantian.mybatis.mapperinterface.UserMapper">
</mapper>