基于springboot集成mybatis——单表简单配置使用
1.新建一个students表
CREATE TABLE `students` (
`stud_id`
INT
(11) NOT NULL,
`name` VARCHAR(50) NOT NULL,
`email` VARCHAR(50),
`phone` VARCHAR(15),
`dob` DATE,
`addr_id`
INT
(11),
PRIMARY KEY (`stud_id`)
)
COLLATE=
'utf8_general_ci'
ENGINE=InnoDB
;
|
2.创建Student实体类 别名设为为student 如果不设置别名 映射时需要写完全权限类名
@Data
@Alias(
"student"
)
public
class
Student implements Serializable{
private
static
final Long serialVersionUID=1L;
private
Integer stuId;
private
String name;
private
String email;
private
Date dob;
private
PhoneNumber phone;
private
Address address;
}
|
注意:字段phone为PhoneNumber类型
3.创建类PhoneNumber
@Data
public
class
PhoneNumber {
private
String countryCode;
private
String stateCode;
private
String number;
public
PhoneNumber(String countryCode, String stateCode, String number) {
this
.countryCode = countryCode;
this
.stateCode = stateCode;
this
.number = number;
}
public
PhoneNumber() {
}
public
static
PhoneNumber getPhoneNumber(String s) {
String countryCode=s.split(
"-"
)[0];
String stateCode=s.split(
"-"
)[1];
String number=s.split(
"-"
)[2];
return
new
PhoneNumber(countryCode,stateCode,number);
}
@Override
public
String toString() {
return
countryCode +
'-'
+stateCode +
'-'
+number;
}
}
|
MyBatis对于以下的类型使用内建的类型处理器:所有的基本数据类型、基本类型的包裹类型、 byte[]、java.util.Date、java.sql.Date、java,sql.Time、java.sql.Timestamp、java枚举类型等。所以当MyBatis发现属性的类型属于上述类型,他会使用对应的类型处理器将值设置到PreparedStatement中,同样地,当SQL结果集封装成java类对象的时候,也有类似的过程。
public
class
PhoneTypeHandler extends BaseTypeHandler<PhoneNumber> {
//遇到PhoneNumber参数的时候应该如何在ps中设置值
@Override
public
void
setNonNullParameter(PreparedStatement preparedStatement,
int
i, PhoneNumber phoneNumber, JdbcType jdbcType) throws SQLException {
preparedStatement.setString(i,phoneNumber.toString());
}
//查询中遇到PhoneNumber类型的应该如何封装(使用列名封装)
@Override
public
PhoneNumber getNullableResult(ResultSet resultSet, String s) throws SQLException {
return
PhoneNumber.getPhoneNumber(resultSet.getString(s));
}
//查询中遇到PhoneNumber类型的应该如何封装(使用列的下标)
@Override
public
PhoneNumber getNullableResult(ResultSet resultSet,
int
i) throws SQLException {
return
PhoneNumber.getPhoneNumber(resultSet.getString(i));
}
//CallableStatement使用中遇到了PhoneNumber类型的应该如何封装
@Override
public
PhoneNumber getNullableResult(CallableStatement callableStatement,
int
i) throws SQLException {
return
null;
}
}
|
4.在application.yml注册类别处理器
mybatis.type-handlers-package: com.example.mybatis_test.typeHandlers
|
指定类型处理器所在包
5.映射文件OneToOneMapper.xml
<mapper
namespace
=
"com.example.mybatis_test.mapper.OneToOneMapper"
>
<resultMap id=
"AddressMap"
type=
"address"
>
<id column=
"addr_id"
property=
"addrId"
/>
<result column=
"city"
property=
"city"
/>
<result column=
"state"
property=
"state"
/>
<result column=
"street"
property=
"street"
/>
<result column=
"zip"
property=
"zip"
/>
<result column=
"country"
property=
"country"
/>
</resultMap>
<resultMap id=
"StudentMap"
type=
"student"
>
<id column=
"stud_id"
property=
"stuId"
/>
<result column=
"name"
property=
"name"
/>
<result column=
"email"
property=
"email"
/>
<result column=
"dob"
property=
"dob"
/>
<result column=
"phone"
property=
"phone"
/>
</resultMap>
<!-- 我们可以从从另外一个resultMap,拓展出一个新的resultMap,这样,原先的属性映射可以继承过来,以实现-->
<resultMap id=
"StudentWithAddress"
type=
"student"
extends=
"StudentMap"
>
<association property=
"address"
resultMap=
"AddressMap"
/>
</resultMap>
</mapper>
|
6.OneToOneMapper接口
@Select(
"select stud_id, name, email,phone,dob, a.addr_id, street, city, state,\n"
+
" zip, country\n"
+
" from students s left outer join addresses a on \n"
+
" s.addr_id=a.addr_id\n"
+
" where stud_id=#{id}\n"
)
@ResultMap(
"StudentWithAddress"
)
List<Student> findAllStudentById(@Param(
"id"
) Integer id);
|
用@ResultMap注解将返回结果用OneToOneMapper.xml中定义的id为StudentWithAddress的resultMap进行映射 返回带有address详细信息的student对象
7.分页——三种分页方式
利用mysql 语句 limit 进行物理分页
@Select(
"select stud_id, name, email,phone,dob, a.addr_id, street, city, state,\n"
+
" zip, country\n"
+
" from students s left outer join addresses a on \n"
+
" s.addr_id=a.addr_id limit #{offset},#{pagesize}"
)
@ResultMap(
"StudentWithAddress"
)
List<Student> findAllStudentPage(@Param(
"offset"
) Integer offset,@Param(
"pagesize"
) Integer pagesize);
虽然这里实现了按需查找,每次检索得到的是指定的数据。但是每次在分页的时候都需要去编写limit语句,很冗余。
mybatis rowbounds 逻辑分页
@Select(
"select stud_id, name, email,phone,dob, a.addr_id, street, city, state,\n"
+
" zip, country\n"
+
" from students s left outer join addresses a on \n"
+
" s.addr_id=a.addr_id order by stud_id asc "
)
@ResultMap(
"StudentWithAddress"
)
List<Student> findAllStudentRowBounds(RowBounds rowBounds);
调用时传入RowBounds对象 new RowBounds(offset,pagesize)
逻辑分页: 一次性从数据库获取的数据可能会很多,对内存的消耗很大,可能导致性能变差,甚至引发内存溢出。
利用pageHelper插件
在pom.xml文件中添加依赖
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.2.3</version>
</dependency>
在application.yml文件中进行配置
pagehelper:
auto-dialect: mysql
reasonable:
true
-
-
dialect属性:使用时可以指定该属性(不指定的情况下,分页插件会自动判断),可选值为oracle,mysql,mariadb,sqlite,hsqldb,postgresql,db2,sqlserver,informix,h2,sqlserver2012。
offsetAsPageNum属性:默认值为false,使用默认值时不需要增加该配置,需要设为true时,需要配置该参数。当该参数设置为true时,使用RowBounds分页时,会将offset参数当成pageNum使用,可以用页码和页面大小两个参数进行分页。
rowBoundsWithCount属性,默认值为false,使用默认值时不需要增加该配置,需要设为true时,需要配置该参数。当该参数设置为true时,使用RowBounds分页会进行count查询。
pageSizeZero属性,默认值为false,使用默认值时不需要增加该配置,需要设为true时,需要配置该参数。当该参数设置为true时,如果pageSize=0或者RowBounds.limit = 0就会查询出全部的结果(相当于没有执行分页查询,但是返回结果仍然是Page类型)。
reasonable属性,默认值为false,使用默认值时不需要增加该配置,需要设为true时,需要配置该参数。具体作用请看上面配置文件中的注释内容。
一个params参数来配置参数映射,用于从Map或ServletRequest中取值,可以配置pageNum,pageSize,count,pageSizeZero,reasonable,orderBy,不配置映射的用默认值。
supportMethodsArguments支持通过Mapper接口参数来传递分页参数,默认值false,具体用法参考com.github.pagehelper.test.basic包下的ArgumentsMapTest和ArgumentsObjTest测试类。
returnPageInfo用来支持直接返回PageInfo类型,默认值none,可选参数always总是返回PageInfo类型,check检查返回类型是否为PageInfo,none返回Page(List)类型。用法和配置参考com.github.pagehelper.test.basic包下的PageInfoTest,特别要注意接口的返回值和xml中的resultType类型。
closeConn属性,当使用动态数据源或没有设置dialect属性自动获取数据库类型时,会自动获取一个数据库连接,通过该属性来设置是否关闭获取的这个连接,默认true关闭。
-
-
mapper接口
@Select(
"select stud_id, name, email,phone,dob, a.addr_id, street, city, state,\n"
+
" zip, country\n"
+
" from students s left outer join addresses a on \n"
+
" s.addr_id=a.addr_id order by stud_id asc "
)
@ResultMap(
"StudentWithAddress"
)
Page<Student> findStudentsPageHelper();
-
使用时 pageHelper.startPage(page,size) 参数为第几页 (从1开始)和 每页条数 紧接着接口调用语句
PageHelper.startPage(page,size);
Page<Student> pages=studentMapper.findStudentsPageHelper();