3.1、 引入Spring Boot与Mybatis依赖包
很多厂商都提供了与Spring Boot集成的包。Mybatis同样也提供了mybatis-spring-boot-starter 目前 1.3.x 是最新版本。
(如果你的业务不需要十分繁琐的SQL语句,那么我推荐使用JPA的方式来操作数据库会更加敏捷)
Maven方式引入:
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.1-SNAPSHOT</version>
</dependency>
3.2、 从属性文件中配置数据源
配置数据源我使用的是properties配置,代码如下:前四个是必配的,含义应该就不用解释了吧,大家都懂。之后的可选配置不全,如果需要全的可以去看官方文档。
spring.datasource.url = jdbc:mysql://localhost:3306/spring-boot?useUnicode=true&characterEncoding=utf-8
spring.datasource.username = root
spring.datasource.password = root
spring.datasource.driverClassName = com.mysql.jdbc.Driver
#可选配置
# 初始化大小,最小,最大
spring.datasource.initialSize=10
spring.datasource.minIdle=10
spring.datasource.maxActive=20
# 配置获取连接等待超时的时间
spring.datasource.maxWait=80000
# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
spring.datasource.timeBetweenEvictionRunsMillis=80000
# 配置一个连接在池中最小生存的时间,单位是毫秒
spring.datasource.minEvictableIdleTimeMillis=500000
# 通过connectProperties属性来打开mergeSql功能;慢SQL记录
spring.datasource.connectionProperties=druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
# 合并多个DruidDataSource的监控数据
spring.datasource.useGlobalDataSourceStat=true
#指定连接的事务的默认隔离级别.
spring.datasource.default-transaction-isolation
#指定driver的类名,默认从jdbc url中自动探测.
spring.datasource.driver-class-name
#是否采用FIFO返回连接.
spring.datasource.fair-queue
#使用Hikari connection pool时,在心跳检查时传递的属性
spring.datasource.health-check-properties.[key]
#指定连接多久没被使用时,被设置为空闲,默认为10ms
spring.datasource.idle-timeout
#当初始化连接池时,是否忽略异常.
spring.datasource.ignore-exception-on-pre-load
3.3、 使用注解方式写SQL语句
以上步骤做完,就可以写SQL语句了。
最简单的四个注解。分别对应查找,更新,删除,插入的SQL语句。
例子:
@Select("select * from admin")
@Update("update admin a set a.userName='二十岁以后'")
@Delete("delete from admin where userName='二十岁以后'")
@Insert("insert into admin (UserName,PassWord) values('二十岁以后','123')")
参数的引用 :@Param
例子: 将注解括号内的参数进行引用 ,SQL语句中使用#{} 或 ${} 的方式都可以 ,使用#时变量是占位符,可以防止sql注入。而$使用时,变量就是直接追加在sql中,一般会有sql注入问题。 还有就是通过#方式获取变量时,可能会出现与数据库的字段的类型不匹配错误 ,比如时间类型可以使用$。
@Select("select * from admin where User_Name=#{UserName} ")
public Admin selectUser(@param("UserName") String UM);
不使用@Param注解的情况,那么参数只能有一个,并且是Javabean。在SQL语句里可以引用JavaBean的属性,而且只能引用JavaBean的属性。 例子如下:
// 这里id是Admin的属性
@Select("SELECT * from admin where id = ${id}")
public Admin selectAdminById(Admin admin);
结果映射列表: @Results、 @Result
例子: @Results是结果映射列表,@Result中property是Admin类的属性名,colomn是数据库表的字段名 。将数据库结果集和我JAVA中POJO类的字段做绑定。(我记得Mybatis好像是有个功能,比如数据库字段名为User_Name,POJO的字段名为UserName。符合这种规则的会自动绑定,无需手动。可以用mybatis-generator工具来生成POJO类)
@Results({
@Result(property="Id",column="UserId"),
@Result(property="UserName",column="UserName")
})
@Select("select UserId, UserName from admin where a.RealName=#{RM}")
public Admin selectAdminByRM(@Param("RM") String RM);
声明Mapper接口 : @Mapper
例子: @Mapper将UserDao声明为一个Mapper接口。
package cn.yy.dao;
@Mapper
public interface UserDao {
@Results({
@Result(property="Id",column="UserId"),
@Result(property="UserName",column="UserName")
})
@Select("select UserId, UserName from admin where a.RealName=#{RM}")
public Admin selectAdminByRM(@Param("RM") String RM);
}
其实使用注解实现动态SQL有三种方法,我只写两种个人比较喜欢的方式。(第三种也确实不太好)
第一种方式(个人感觉就是拼接字符串,条件判断,然后返回拼接好的字符串)
在DAO层的接口中定义一个内部类,代码如下:
package cn.yy.dao;
@Mapper
public interface UserDao {
class Userdao{
public String findUserNumByInput(String Department,String RealName) {
String sql="SELECT COUNT(*) from users"+"" ;
if(Department != null && RealName != null){
sql += " where Department='"+Department+"' and RealName like '%"+RealName+"%';";
return sql;
}else if( Department != null ){
sql += " where Department = '"+Department;
return sql;
} else if( RealName != null){
sql += " where RealName like '%"+RealName+"%'";
return sql;
}
return sql;
}
}
以上这个叫Userdao的内部类的类名就是上一节Type对应的值,上节method中的方法就是次内部类中要调用的方法。
解释一下方法中参数和代码的含义:
方法中传入的参数就是从Service层传来的参数(可以理解为你要查询的全部条件)。
定义的String对象写的字符串内容是你SQL公用的部分(其实就是拼接SQL语句的字符串)。
if判断你的哪些条件为空,然后拼接成你想要的语句。
最后把拼接好的字符串return回去 。
这就是第一种实现方式,贴一个完整代码:
package cn.yy.dao;
@Mapper
public interface UserDao {
@SelectProvider(type=Userdao.class,method="findUserNumByInput")
public Integer selectUserNum(String Department,String RealName);
class Userdao{
public String findUserNumByInput(String Department,String RealName) {
String sql="SELECT COUNT(*) from users"+"" ;
if(Department != null && RealName != null){
sql += " where Department='"+Department+"' and RealName like '%"+RealName+"%';";
return sql;
}else if( Department != null ){
sql += " where Department = '"+Department;
return sql;
} else if( RealName != null){
sql += " where RealName like '%"+RealName+"%'";
return sql;
}
return sql;
}
}
注意:@SelectProvide中type参数指定的Class类,必须要能够通过无参的构造函数来初始化。
@SelectProvide中method参数指定的方法,必须是public的,返回值必须为String,可以为static。
第二种方式(推荐)
MyBatis 3提供了方便的工具类。使用SQL类创建一个实例来调用方法生成SQL语句。比起第一种方式来说减少了重复的SQL字符串的拼接。完整代码如下:
package cn.yy.dao;
public class UserDao {
@SelectProvider(type=Userdao .class,method="selectPersonLike")
public List<Person> selectPerson(String id,String firstName,String lastName);
clas Userdao{
public String selectPersonLike(final String id, final String firstName, final String lastName) {
return new SQL() {{
SELECT("P.ID, P.USERNAME, P.PASSWORD, P.FIRST_NAME, P.LAST_NAME");
FROM("PERSON P");
if (id != null) {
WHERE("P.ID like #{id}");
}
if (firstName != null) {
WHERE("P.FIRST_NAME like #{firstName}");
}
if (lastName != null) {
WHERE("P.LAST_NAME like #{lastName}");
}
ORDER_BY("P.LAST_NAME");
}}.toString();
}
}
}
注意:方法的返回值也必须为String
selectPersonLike方法中的“SELECT”“FROM”“WHERE”等,均为方法!!!具体解释如下:
方法 | 描述 |
---|---|
| 开始或插入到 SELECT子句。 可以被多次调用,参数也会添加到 SELECT子句。 参数通常使用逗号分隔的列名和别名列表,但也可以是数据库驱动程序接受的任意类型。 |
| 开始或插入到 SELECT子句, 也可以插入 DISTINCT关键字到生成的查询语句中。 可以被多次调用,参数也会添加到 SELECT子句。 参数通常使用逗号分隔的列名和别名列表,但也可以是数据库驱动程序接受的任意类型。 |
| 开始或插入到 FROM子句。 可以被多次调用,参数也会添加到 FROM子句。 参数通常是表名或别名,也可以是数据库驱动程序接受的任意类型。 |
| 基于调用的方法,添加新的合适类型的 JOIN子句。 参数可以包含由列命和join on条件组合成标准的join。 |
| 插入新的 WHERE子句条件, 由AND链接。可以多次被调用,每次都由AND来链接新条件。使用 OR() 来分隔OR。 |
| 使用OR来分隔当前的 WHERE子句条件。 可以被多次调用,但在一行中多次调用或生成不稳定的SQL。 |
| 使用AND来分隔当前的 WHERE子句条件。 可以被多次调用,但在一行中多次调用或生成不稳定的SQL。因为 WHERE 和 HAVING 二者都会自动链接 AND, 这是非常罕见的方法,只是为了完整性才被使用。 |
| 插入新的 GROUP BY子句元素,由逗号连接。 可以被多次调用,每次都由逗号连接新的条件。 |
| 插入新的 HAVING子句条件。 由AND连接。可以被多次调用,每次都由AND来连接新的条件。使用 OR() 来分隔OR. |
| 插入新的 ORDER BY子句元素, 由逗号连接。可以多次被调用,每次由逗号连接新的条件。 |
| 开始一个delete语句并指定需要从哪个表删除的表名。通常它后面都会跟着WHERE语句! |
| 开始一个insert语句并指定需要插入数据的表名。后面都会跟着一个或者多个VALUES() or INTO_COLUMNS() and INTO_VALUES()。 |
| 针对update语句,插入到"set"列表中 |
| 开始一个update语句并指定需要更新的表明。后面都会跟着一个或者多个SET(),通常也会有一个WHERE()。 |
| 插入到insert语句中。第一个参数是要插入的列名,第二个参数则是该列的值。 |