MyBatis的参数
3.1 parameterType 配置 参数
我们在上一章节中已经介绍了 SQL 语句传参,使用标签的 parameterType 属性来设定。该属性的取值可以是基本类型,引用类型(例如:String 类型),还可以是实体类类型(POJO 类)。同时也可以使用实体类的包装类,本章节将介绍如何使用实体类的包装类作为参数传递。
基 本类 型和 String 我 们可 以直接 写类型 名称 ,也 可以 使用包 名 . 类名的 方式 ,例如 :java.lang.String。
实体类类型,目前我们只能使用全限定类名。
究其原因,是 mybaits 在加载时已经把常用的数据类型注册了别名,从而我们在使用时可以不写包名,而我们的是实体类并没有注册别名,所以必须写全限定类名。在后面将讲解如何注册实体类的别名。
3.1.1pojo 包装类作为参数:
开发中通过 pojo 传递查询条件 ,查询条件是综合的查询条件,不仅包括图书查询条件还包括其它的查询条件(比如将图书类型也作为查询条件),这时可以使用包装对象传递输入参数。
Pojo 类中包含 pojo。
需求:根据图书名查询图书信息,查询条件放到 QueryVo 的 book 属性中
编写 QueryVo
public class QueryVo {
private Book book;
public Book getBook() {
return book;
}
public void setBook(Book book) {
this.book = book;
}
}
在持久层接口BookDao中添加方法:
List<Book> findBookByName3(QueryVo vo);
在持久层映射文件中配置;
<select id="findBookByName3" parameterType="cn.space.pojo.QueryVo" resultType="cn.yihao.pojo.Book">
select * from book where bname like #{book.bname}
</select>
测试:
@Test
public void test09(){
QueryVo vo = new QueryVo();
Book book = new Book();
book.setBname("%Hok%");
vo.setBook(book);
List<Book> list = bookDao.findBookByName3(vo);
for (Book book1 : list) {
System.out.println(book1.toString());
}
}
3.2 Mybatis的输出结果封装
resultType 配置结果类型
resultType 属性可以指定结果集的类型,它支持基本类型和实体类类型。
我们在前面的 CRUD 案例中已经对此属性进行过应用了。
需要注意的是,它和 parameterType 一样,如果注册过类型别名的,可以直接使用别名。没有注册过的必须使用全限定类名。例如:我们的实体类此时必须是全限定类名
同时,当是实体类名称是,还有一个要求,实体类中的属性名称必须和查询语句中的列名保持一致,否则无法实现封装。
前面学习过通过图书名查询图书,返回的是一个pojo类型,当实体类中的属性名和数据表中的字段名不一样时应该如何做呢?
修改实体类BookInfo
package cn.space.pojo;
import java.util.Date;
public class BookInfo {
private Integer bookid;
private String bookname;
private Integer bookprice;
private String bookauthor;
private Date bookpdate;
public BookInfo() {
}
public BookInfo(Integer bookid, String bookname, Integer bookprice, String bookauthor, Date bookpdate) {
this.bookid = bookid;
this.bookname = bookname;
this.bookprice = bookprice;
this.bookauthor = bookauthor;
this.bookpdate = bookpdate;
}
/**
* 获取
* @return bookid
*/
public Integer getBookid() {
return bookid;
}
/**
* 设置
* @param bookid
*/
public void setBookid(Integer bookid) {
this.bookid = bookid;
}
/**
* 获取
* @return bookname
*/
public String getBookname() {
return bookname;
}
/**
* 设置
* @param bookname
*/
public void setBookname(String bookname) {
this.bookname = bookname;
}
/**
* 获取
* @return bookprice
*/
public Integer getBookprice() {
return bookprice;
}
/**
* 设置
* @param bookprice
*/
public void setBookprice(Integer bookprice) {
this.bookprice = bookprice;
}
/**
* 获取
* @return bookauthor
*/
public String getBookauthor() {
return bookauthor;
}
/**
* 设置
* @param bookauthor
*/
public void setBookauthor(String bookauthor) {
this.bookauthor = bookauthor;
}
/**
* 获取
* @return bookpdate
*/
public Date getBookpdate() {
return bookpdate;
}
/**
* 设置
* @param bookpdate
*/
public void setBookpdate(Date bookpdate) {
this.bookpdate = bookpdate;
}
public String toString() {
return "BookInfo{bookid = " + bookid + ", bookname = " + bookname + ", bookprice = " + bookprice + ", bookauthor = " + bookauthor + ", bookpdate = " + bookpdate + "}";
}
}
BookDao中添加方法:
List<BookInfo> findBookByName4(String name);
修改映射配置:
使用别名查询
<select id="findBookByName4" parameterType="String" resultType="cn.space.pojo.BookInfo">
select bid as bookid,bname as bookname,price as bookprice,author as bookauthor,pdate as bookpdate from book where bname like #{bname}
</select>
测试:
@Test
public void test10(){
List<BookInfo> list = bookDao.findBookByName4("%Hok%");
for (BookInfo bookInfo : list) {
System.out.println(bookInfo.toString());
}
}
思考:
如果我们的查询字段很多,都使用别名的话写起来岂不是很麻烦,有没有别的解决办法呢?可以使用resultMap
3.2.2 resultMap结果类型
resultMap 标签可以建立查询的列名和实体类的属性名称不一致时建立对应关系。从而实现封装。
在 select 标签中使用 resultMap 属性指定引用即可。同时 resultMap 可以实现将查询结果映射为复杂类型的 pojo,比如在查询结果映射对象中包括 pojo 和 list 实现一对一查询和一对多查询。
再来实现根据书名查询图书:
在BookDao中添加方法:
List<BookInfo> findBookByName5(String name);
定义 resultMap
<resultMap id="bookMap" type="cn.yihao.pojo.BookInfo">
<id column="bid" property="bookid"></id>
<result column="bname" property="bookname"></result>
<result column="price" property="bookprice"></result>
<result column="author" property="bookauthor"></result>
<result column="pdate" property="bookpdate"></result>
</resultMap>
id 标签:用于指定主键字段
result 标签:用于指定非主键字段
column 属性:用于指定数据库列名
property 属性:用于指定实体类属性名称
映射配置
<select id="findBookByName5" parameterType="String" resultMap="bookMap">
select * from book where bname like #{bname}
</select>
测试:
@Test
public void test11(){
List<BookInfo> list = bookDao.findBookByName5("%Hok%");
for (BookInfo bookInfo : list) {
System.out.println(bookInfo.toString());
}
}
加入log4j日志
将log4j的配置文件拷贝到resources下
3.3SqlMapConfig.xml 配置文件
配置内容
SqlMapConfig.xml 中配置的内容和顺序
-properties (属性)
–property
-settings(全局配置参数)
–setting
-typeAliases (类型别名)
–typeAliase
–package
-typeHandlers(类型处理器)
-objectFactory(对象工厂)
-plugins(插件)
-environments(环境集合属性对象)
–environment(环境子属性对象)
—transactionManager(事务管理)
—dataSource(数据源)
-mappers (映射器)
–mapper
–package
properties (属性)
在使用 properties 标签配置时,我们可以采用两种方式指定属性配置。
第一种
<properties>
<property name="jdbc.driver" value="com.mysql.jdbc.Driver"/>
<property name="jdbc.url" value="jdbc:mysql://localhost:3306/mybatis"/>
<property name="jdbc.username" value="root"/>
<property name="jdbc.password" value="123456"/>
</properties>
这里最好是如下所示(否则很容易出现上传到数据库的数据乱码)
<property name="url" value="jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf8" />
第二种
在 resources 下定义 db.properties 文件
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis
jdbc.username=root
jdbc.password=123456
properties 标签配置:
<!-- 配置连接数据库的信息
resource 属性:用于指定 properties 配置文件的位置,要求配置文件必须在类路径下
resource="db.properties"
-->
<properties resource="db.properties"></properties>
此时我们的 dataSource 标签就变成了引用上面的配置
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>
typeAliases (类型别名)
在前面我们讲的 Mybatis 支持的默认别名,我们也可以采用自定义别名方式来开发。
自定义别名:
在 SqlMapConfig.xml 中配置:
<typeAliases>
<!-- 单个别名定义 -->
<typeAlias alias="Book" type="cn.space.pojo.Book"/>
<!-- 批量别名定义,扫描整个包下的类,别名为类名(首字母大写或小写都可以) -->
<package name="cn.space.pojo"/>
<package name=" 其它包 "/>
</typeAliases>
mappers (映射器)
使用相对于类路径的资源
如:
<mapper resource="cn/space/dao/BookDao.xml" />
<mapper resource=" " />
使用相对于类路径的资源
如:
<mapper resource="cn/space/dao/BookDao.xml" />
<package name=""/>
注册指定包下的所有 mapper 接口
如:
<package name="cn.space.dao"/>
注意:此种方法要求 marpper 接口名称和 mapper 映射文件名称相同,且放在同一个目录中.