在上一篇文章中已经将MyBatis的环境搭建完成。
本节将简单介绍MyBatis的文件配置及通过MyBatis完成一个简单的查询。
首先需要简单介绍两个基础类:
1、User模型类:
package com.wp.model;
import java.util.Date;
public class User {
private int id;
private String userName;
private int sex;
private int age;
private Date birthDay;
private String address;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public int getSex() {
return sex;
}
public void setSex(int sex) {
this.sex = sex;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Date getBirthDay() {
return birthDay;
}
public void setBirthDay(Date birthDay) {
this.birthDay = birthDay;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public User() {
super();
}
public User(int id, String userName, int sex, int age, Date birthDay,
String address) {
super();
this.id = id;
this.userName = userName;
this.sex = sex;
this.age = age;
this.birthDay = birthDay;
this.address = address;
}
public User(String userName, int sex, int age, Date birthDay, String address) {
super();
this.userName = userName;
this.sex = sex;
this.age = age;
this.birthDay = birthDay;
this.address = address;
}
public String toString() {
return "User [address=" + address + ", age=" + age + ", birthDay="
+ birthDay + ", id=" + id + ", sex=" + sex + ", userName="
+ userName + "]";
}
}
2、日期工具类(在commons项目中有相应的类,本工具类是自己写的用来测试的)
package com.wp.util;
import java.io.Serializable;
import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import org.apache.commons.lang3.StringUtils;
/**
* 日期工具类
*
*
*/
public class DateUtil implements Serializable {
private static final long serialVersionUID = 8321747583406350420L;
/**
* 全日期格式<br>
* yyyy-MM-dd
*/
public static final String FULL_DAY_FORMAT = "yyyy-MM-dd";
/**
* 日期格式<br>
* yyyy-MM
*/
public static final String DAY_FORMAT = "yyyy-MM";
/**
* 全日期带时间格式<br>
* yyyy-MM-dd HH:mm:ss
*/
public static final String FULL_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
/**
* 时间格式<br>
* HH:mm:ss
*/
public static final String TIME_FORMAT = "HH:mm:ss";
/**
* 将指定的字符串按指定类型转换为日期<br>
* 转换异常时返回null
*
* @param str
* 需要转换的字符串
* @param pattern
* 转换格式
* @return
*/
public static Date parseStrToFullDate(String str, String pattern) {
if (StringUtils.isBlank(str)) {
return null;
}
if (StringUtils.isBlank(pattern)) {
return null;
}
Date returnDate = null;
SimpleDateFormat format = new SimpleDateFormat(pattern);
try {
returnDate = format.parse(str);
} catch (ParseException e) {
e.printStackTrace();
return null;
}
return returnDate;
}
/**
* 将指定的字符串按指定类型转换为时间戳<br>
* 转换异常时返回null
*
* @param str
* 需要转换的字符串
* @param pattern
* 转换格式
* @return
*/
public static Timestamp parseStrToFullTimestamp(String str, String pattern) {
if (StringUtils.isBlank(str)) {
return null;
}
if (StringUtils.isBlank(pattern)) {
return null;
}
SimpleDateFormat format = new SimpleDateFormat(pattern);
try {
Date tempDate = format.parse(str);
Timestamp timestamp = new Timestamp(tempDate.getTime());
return timestamp;
} catch (ParseException e) {
e.printStackTrace();
}
return null;
}
/**
* 将当前时间转换成指定格式的字符串<br>
* 参数为空,返回空
*
* @param pattern
* 转换格式
* @return
*/
public static String changeCurrentToStr(String pattern) {
return changeDateToStr(new Date(), pattern);
}
/**
* 将指定的日期按给定的格式转换
*
* @param date
* 日期对象
* @param pattern
* 格式。如:yyyy-MM-dd
* @return
*/
public static String changeDateToStr(Date date, String pattern) {
if (null == date) {
return "";
}
if (StringUtils.isBlank(pattern)) {
return "";
}
SimpleDateFormat format = new SimpleDateFormat(pattern);
String result = format.format(new Timestamp(date.getTime()));
return result;
}
/**
* 获取指定日期所在月份的第一天
*
* @param date
* 指定日期
* @return
*/
@SuppressWarnings("deprecation")
public static String getFirstDay(Date date) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
int firstDayPersent = calendar.getActualMinimum(Calendar.DAY_OF_MONTH);
Date firstDate = calendar.getTime();
firstDate.setDate(firstDayPersent);
String firstDay = new SimpleDateFormat(FULL_DAY_FORMAT)
.format(firstDate);
return firstDay;
}
/**
* 获取指定日期所在月份的最后一天
*
* @param date
* 指定日期
* @return
*/
@SuppressWarnings("deprecation")
public static String getLastDay(Date date) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
int lastDayPersent = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
Date lastDate = calendar.getTime();
lastDate.setDate(lastDayPersent);
String lastDay = new SimpleDateFormat(FULL_DAY_FORMAT).format(lastDate);
return lastDay;
}
/**
* 获取指定日期所在月份的上个月的第一天
*
* @param date
* 指定日期
* @return
*/
public static String getFirstDayOfLastMonth(Date date) {
SimpleDateFormat df = new SimpleDateFormat(FULL_DAY_FORMAT);
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
calendar.add(Calendar.MONTH, -1);
Date theDate = calendar.getTime();
// 上个月第一天
GregorianCalendar gcLast = (GregorianCalendar) Calendar.getInstance();
gcLast.setTime(theDate);
gcLast.set(Calendar.DAY_OF_MONTH, 1);
String firstDay = df.format(gcLast.getTime());
return firstDay;
}
/**
* 获取指定日期所在月份的上个月的最后一天
*
* @param date
* 指定日期
* @return
*/
public static String getLastDayOfLastMonth(Date date) {
SimpleDateFormat df = new SimpleDateFormat(FULL_DAY_FORMAT);
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
calendar.add(Calendar.MONTH, -1);
// 上个月最后一天
calendar.add(Calendar.MONTH, 1); // 加一个月
calendar.set(Calendar.DATE, 1); // 设置为该月第一天
calendar.add(Calendar.DATE, -1); // 再减一天即为上个月最后一天
String lastDay = df.format(calendar.getTime());
return lastDay;
}
/**
* 获取指定日期所在月份的下个月的第一天
*
* @param date
* 指定日期
* @return
*/
public static String getFirstDayOfNextMonth(Date date) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
calendar.set(Calendar.DAY_OF_MONTH, 1);
calendar.add(Calendar.MONTH, 1);
SimpleDateFormat df = new SimpleDateFormat(FULL_DAY_FORMAT);
String firstDay = df.format(calendar.getTime());
return firstDay;
}
/**
* 获取指定日期所在月份的下个月的最后一天
*
* @param date
* 指定日期
* @return
*/
public static String getLastDayOfNextMonth(Date date) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
calendar.add(Calendar.MONTH, +1);
// 上个月最后一天
calendar.add(Calendar.MONTH, 1); // 加一个月
calendar.set(Calendar.DATE, 1); // 设置为该月第一天
calendar.add(Calendar.DATE, -1); // 再减一天即为上个月最后一天
SimpleDateFormat df = new SimpleDateFormat(FULL_DAY_FORMAT);
String lastDay = df.format(calendar.getTime());
return lastDay;
}
/**
* 获取指定日期的前一天
*
* @param date
* 指定日期
* @return 返回格式:yyyy-MM-dd
*/
public static String getDayOfBefore(Date date) {
if (null == date) {
return "";
}
String beforeDay = "";
Calendar c = Calendar.getInstance();
c.setTime(date);
int day = c.get(Calendar.DATE);
c.set(Calendar.DATE, day - 1);
beforeDay = new SimpleDateFormat("yyyy-MM-dd").format(c.getTime());
return beforeDay;
}
/**
* 获取指定日期的前一天
*
* @param day
* 指定日期.格式:yyyy-MM-dd
* @return 返回格式:yyyy-MM-dd
*/
public static String getDayOfBefore(String day) {
if (StringUtils.isBlank(day)) {
return "";
}
String beforeDay = "";
Date date = null;
try {
date = new SimpleDateFormat("yyyy-MM-dd").parse(day);
beforeDay = getDayOfBefore(date);
} catch (ParseException e) {
e.printStackTrace();
}
return beforeDay;
}
/**
* 获取指定日期的后一天
*
* @param date
* 指定日期
* @return 返回格式:yyyy-MM-dd
*/
public static String getDayOfNext(Date date) {
if (null == date) {
return "";
}
String nextDay = "";
Calendar c = Calendar.getInstance();
c.setTime(date);
int day = c.get(Calendar.DATE);
c.set(Calendar.DATE, day + 1);
nextDay = new SimpleDateFormat("yyyy-MM-dd").format(c.getTime());
return nextDay;
}
/**
* 获取指定日期的后一天
*
* @param day
* 指定日期.格式:yyyy-MM-dd
* @return 返回格式:yyyy-MM-dd
*/
public static String getDayOfNext(String day) {
if (StringUtils.isBlank(day)) {
return "";
}
String nextDay = "";
Date date = null;
try {
date = new SimpleDateFormat("yyyy-MM-dd").parse(day);
nextDay = getDayOfNext(date);
} catch (ParseException e) {
e.printStackTrace();
}
return nextDay;
}
/**
* 获取指定日期所在星期的第一天
* @param day
* @return
*/
public static String getFirstDayOfWeek(String day) {
String firstDay = "";
Calendar calendar = Calendar.getInstance();
try {
calendar.setTime(new SimpleDateFormat("yyyy-MM-dd").parse(day));
int d = 0;
if(calendar.get(Calendar.DAY_OF_WEEK)==1){
d = -6;
}else{
d = 2 - calendar.get(Calendar.DAY_OF_WEEK);
}
calendar.add(Calendar.DAY_OF_WEEK, d);
//所在周开始日期
firstDay = new SimpleDateFormat("yyyy-MM-dd").format(calendar.getTime());
} catch (ParseException e) {
e.printStackTrace();
}
return firstDay;
}
/**
* 获取指定日期所在星期的最后一天
* @param day
* @return
*/
public static String getLastDayOfWeek(String day) {
String lastDay = "";
Calendar calendar = Calendar.getInstance();
try {
calendar.setTime(new SimpleDateFormat("yyyy-MM-dd").parse(day));
int d = 0;
if(calendar.get(Calendar.DAY_OF_WEEK)==1){
d = -6;
}else{
d = 2 - calendar.get(Calendar.DAY_OF_WEEK);
}
calendar.add(Calendar.DAY_OF_WEEK, d);
calendar.add(Calendar.DAY_OF_WEEK, 6);
//所在周结束日期
lastDay = new SimpleDateFormat("yyyy-MM-dd").format(calendar.getTime());
} catch (ParseException e) {
e.printStackTrace();
}
return lastDay;
}
}
一、MyBatis全局配置文件配置:
在上节中MyBatis的配置文件为:mybatis-config.xml。下面再来看下项目的基本情况:
需要主要的是MyBatis的全局配置文件名是自己可以随意定义的,当然我们给文件命名的通用规则都是见名思意。
mybatis-config.xml文件中主要用来配置MyBatis的运行时环境与映射文件。
<?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> <!-- 加载数据库配置文件 --> <properties resource="db.properties"/> <environments default="development"> <environment id="development"> <transactionManager type="JDBC"/> <!-- 配置数据源信息 --> <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> </environment> </environments> <!-- 加载映射文件 --> <mappers> <mapper resource="mapper/User.xml"/> </mappers> </configuration>
由于本例中数据库信息已经由单独的数据库配置文件配置完成,因此在mybatis-config.xml文件中引用此文件并用来配置数据源信息。数据库配置文件db.properties文件内容如下:
# 配置数据库相关参数 jdbc.driver=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8 jdbc.username=root jdbc.password=111111
在mybatis-config.xml中通过${}的形式引用db.properties的配置信息。
【environments】标签用来配置MyBatis的环境,此处不错过多解释,因为在最后与Spring整合之后将全部交由Spring管理。
【mappers】标签用来加载映射文件。
【mapper】标签的“resource”属性值来指定映射文件的位置和文件名。位置是从classpath开始的。
二、映射文件配置:
映射文件主要用来配置具体的SQL语句和对应的输入参数、输出参数。在mybatis-config.xml文件中引用了“mapper/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="UserSpace"> <!-- 根据用户ID查询用户 --> <select id="selectById" parameterType="java.lang.Integer" resultType="com.wp.model.User"> select * from user where id=#{id} </select> <!-- 根据用户名称模糊查询用户 --> <select id="selectByVagueName" parameterType="java.lang.String" resultType="com.wp.model.User"> select * from user where username like #{username} </select> <!-- 根据用户名称模糊查询用户2 --> <select id="selectByVagueName2" parameterType="java.lang.String" resultType="com.wp.model.User"> select * from user where username like ${value} </select> <!-- 添加用户 --> <insert id="addUser" parameterType="com.wp.model.User"> insert into user(username, sex, age, birthday, address) values(#{userName}, #{sex}, #{age}, #{birthDay}, #{address}) </insert> </mapper>
1、【mapper】标签的“namespace”属性用来标识映射文件的唯一性,在一个项目中namespace不可重复,是唯一的。目前采用普通定义的方式自定义名称即可,以后在使用mapper代理方式进行开发时再进行相应的讲解说明。
2、MyBatis的映射文件主要用来配置SQL语句及相应的输入输出参数,因为有了输入映射和输出映射,但是同时又需要自己书写SQL语句,因此本人认为MyBatis是一个半自动化的ORM框架。
3、在SQL语句中可以使用 #{} 和 ${} 来替代最后要输入的参数。需要注意的是:
#{} : 是占位符。用来为输入参数占据位置。当参数类型为普通类型时,占位符中的名称可随意填写。
${} : 是连接字符标志,会将输入参数原封不动的拼接到SQL语句中,此方式不安全,容易引起SQL注入,不建议使用。
4、【parameterType】为输入参数的类型,可以是基本类型、也可以是POJO类型。
如果输入参数是基本类型的情况下既可以使用MyBatis的数据类型,也可以使用JAVA类型。但是本人比较喜欢使用JAVA类型。
5、【resultType】为输出参数的类型。需要注意的是【resultType】表示的是返回的单条记录的类型。
比如:如果一个查询结果返回多条记录(List),那么【resultType】不能是List,实际上应该是List
内的具体对象类型。
三、以根据用户id查询用户为例说明一下具体的操作步骤:
1、在映射文件(User.xml)中配置相应的查询语句:
2、编写测试类(UserTest):
package com.wp.test;
import java.io.IOException;
import java.io.InputStream;
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.wp.model.User;
public class UserTest {
/**
* 根据ID查询用户测试
*/
@Test
public void testSelectById() {
// 设置MyBtis配置文件的路径和名称
String resource = "mybatis-config.xml";
try {
// 加载配置文件
InputStream is = Resources.getResourceAsStream(resource);
// 获取SqlSessionFactory
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);
// 获取SqlSession
SqlSession session = factory.openSession();
// 参数1:映射文件的namespace+statementID
// 参数2:参数值
User user = session.selectOne("UserSpace.selectById", 2);
System.out.println(user);
// SqlSession关闭
session.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
注意:SqlSessionFactory全局可使用一个,因此最好通过单例模式实现。
SqlSession在使用完成后一定要关闭。
selectOne:表示查询一个,其中的第一个参数是映射文件的namespace+配置语句的ID,第二个参数为参数值。 因为我们知道具体返回的是User对象,因此直接用User对象接收即可。
基本配置与最简单的查询到此结束。