JFinal的ActiveRecordPlugin插件很棒,感觉吊打Mybatis,分享下。
Maven pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.haojie</groupId>
<artifactId>teacher</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>service-teacher</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.0.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<mybatis-generator.version>1.3.2</mybatis-generator.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Finchley.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-ribbon -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-ribbon</artifactId>
<version>1.4.6.RELEASE</version>
</dependency>
<!-- 包含支持UI模版(Velocity,FreeMarker,JasperReports), 邮件服务, 脚本服务(JRuby), 缓存Cache(EHCache),
任务计划Scheduling(uartz)。 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.2</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-core</artifactId>
<version>${mybatis-generator.version}</version>
</dependency>
<!-- tomcat 的支持. -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.2.2</version>
</dependency>
<!-- shiro ehcache -->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-ehcache</artifactId>
<version>1.2.2</version>
</dependency>
<!-- servlet 依赖. -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
</dependency>
<!--集成druid,使用连接池。 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.0</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.6</version>
</dependency>
<!-- 引入freemarker包 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
<!--json-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.52</version>
</dependency>
<dependency>
<groupId>com.jfinal</groupId>
<artifactId>jfinal</artifactId>
<version>3.5</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<fork>true</fork>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<compilerVersion>1.8</compilerVersion>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-maven-plugin</artifactId>
<version>1.3.0</version>
<configuration>
<verbose>true</verbose>
<overwrite>true</overwrite>
</configuration>
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.6</version>
</dependency>
<dependency>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-core</artifactId>
<version>1.3.2</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
</dependencies>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.12.4</version>
<configuration>
<forkMode>once</forkMode>
<argLine>-Dfile.encoding=UTF-8</argLine>
</configuration>
</plugin>
</plugins>
</build>
</project>
ActiveRecord.java 用于启动activerecord,spring boot启动时,会自动加载此类。
import com.haojie.teacher.common.model._MappingKit;
import com.jfinal.plugin.activerecord.ActiveRecordPlugin;
import com.jfinal.plugin.activerecord.DbKit;
import com.jfinal.plugin.druid.DruidPlugin;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;
@Component
public class ActiveRecord implements ApplicationRunner {
@Autowired
ActiveRecordConfig arc;
@Override
public void run(ApplicationArguments args) throws Exception {
db2=arc.getDatabase2();
if(DbKit.getConfig()!=null){
DbKit.removeConfig("main");
}
DruidPlugin dp = new DruidPlugin(arc.getUrl(), arc.getUsername(), arc.getPassword());
ActiveRecordPlugin arp = new ActiveRecordPlugin(dp);
SqlManager.putsql("sql",arp);
_MappingKit.mapping(arp);
arp.setShowSql(true);
dp.start();
arp.start();
}
}
SqlManager.java 用于加载sql模板,并解决spring boot打成jar包运行时,找不到sql模板问题,可同时在开发和jar使用。
import com.jfinal.kit.PathKit;
import com.jfinal.plugin.activerecord.ActiveRecordPlugin;
import com.jfinal.template.source.ClassPathSourceFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.system.ApplicationHome;
import java.io.*;
import java.util.Enumeration;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
/** 用于加载jfinal的sql模板,Spring boot 打成jar包运行时,会有异常,用此类便可 **/
public class SqlManager {
static Logger logger = LoggerFactory.getLogger(SqlManager.class);
public static void putsql(String dir, ActiveRecordPlugin arp) {
try {
String path = PathKit.class.getResource("/" + dir).getPath() + "/";
File file = new File(path);
File[] tempList = file.listFiles();
for (int i = 0; i < tempList.length; i++) {
if (tempList[i].isFile()) {
arp.addSqlTemplate(path + tempList[i].getName());
logger.info("Loaded SQL Templates :" + dir + "/" + tempList[i].getName());
}
if (tempList[i].isDirectory()) {
logger.error("Dir '" + dir + "/" + tempList[i] + "' not load! System does not support subfolders,if you want load this dir,please use class 'SqlManager' to configure.");
}
}
} catch (Exception e) {
logger.error("Fail : Load location sql file");
try {
jarput(dir, arp);
}catch (Exception e1){
logger.error("Fail : Load jar sql file");
}
}
}
private static void jarput(String dir, ActiveRecordPlugin arp) throws IOException {
arp.getEngine().setSourceFactory(new ClassPathSourceFactory());
ApplicationHome home = new ApplicationHome(SqlManager.class);
File jarFile = home.getSource();
JarFile localJarFile = new JarFile(jarFile);
Enumeration<JarEntry> entries = localJarFile.entries();
while (entries.hasMoreElements()) {
JarEntry jarEntry = entries.nextElement();
String innerPath = jarEntry.getName();
if (innerPath.startsWith("BOOT-INF/classes/"+dir) && innerPath.endsWith(".sql")) {
String path = innerPath.replace("BOOT-INF/classes/", "");
logger.info("Loaded SQL Templates :" + path);
arp.addSqlTemplate(path);
}
}
}
}
ActiveRecordConfig.java 用于加载spring boot的配置文件。
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Service;
@Service
@ConfigurationProperties(prefix = "spring.datasource")
public class ActiveRecordConfig {
private String url;
private String username;
private String password;
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
user.sql 放置resources文件夹下。
#namespace("user")
#sql("find")
select * from user
#if(w!=null)
#for(x : w)
#(for.first ? "where": "and") #(x.key) #para(x.value)
#end
#end
#end
#sql("findbywhere")
select * from user
where 1=1
#if(username)
and username = #para(username)
#end
#if(password)
and password = #para(password)
#end
#if(phone)
and phone = #para(phone)
#end
#if(guid)
and guid = #para(guid)
#end
#if(token)
and token=#para(token)
#end
#if(wx_token)
and wx_token=#para(wx_token)
#end
#if(name)
and name=#para(name)
#end
#if(email)
and email=#para(email)
#end
#end
#end
BaseUser.java和User.java由_JFinalDemoGenerator.java生成器生成。
import com.jfinal.plugin.activerecord.Model;
import com.jfinal.plugin.activerecord.IBean;
/**
* Generated by JFinal, do not modify this file.
*/
@SuppressWarnings("serial")
public abstract class BaseUser<M extends BaseUser<M>> extends Model<M> implements IBean {
public void setUserId(java.lang.Integer userId) {
set("user_id", userId);
}
public java.lang.Integer getUserId() {
return getInt("user_id");
}
public void setUsername(java.lang.String username) {
set("username", username);
}
public java.lang.String getUsername() {
return getStr("username");
}
public void setPassword(java.lang.String password) {
set("password", password);
}
public java.lang.String getPassword() {
return getStr("password");
}
public void setPhone(java.lang.String phone) {
set("phone", phone);
}
public java.lang.String getPhone() {
return getStr("phone");
}
public void setGuid(java.lang.String guid) {
set("guid", guid);
}
public java.lang.String getGuid() {
return getStr("guid");
}
public void setToken(java.lang.String token) {
set("token", token);
}
public java.lang.String getToken() {
return getStr("token");
}
public void setWxToken(java.lang.String wxToken) {
set("wx_token", wxToken);
}
public java.lang.String getWxToken() {
return getStr("wx_token");
}
public void setRole(java.lang.String role) {
set("role", role);
}
public java.lang.String getRole() {
return getStr("role");
}
public void setHeadImg(java.lang.String headImg) {
set("head_img", headImg);
}
public java.lang.String getHeadImg() {
return getStr("head_img");
}
public void setName(java.lang.String name) {
set("name", name);
}
public java.lang.String getName() {
return getStr("name");
}
public void setEmail(java.lang.String email) {
set("email", email);
}
public java.lang.String getEmail() {
return getStr("email");
}
public void setSchoolId(java.lang.Integer schoolId) {
set("school_id", schoolId);
}
public java.lang.Integer getSchoolId() {
return getInt("school_id");
}
public void setUserRole(java.lang.Integer userRole) {
set("user_role", userRole);
}
public java.lang.Integer getUserRole() {
return getInt("user_role");
}
}
import com.haojie.teacher.common.model.base.BaseUser;
/**
* Generated by JFinal.
*/
@SuppressWarnings("serial")
public class User extends BaseUser<User> {
}
_JFinalDemoGenerator.java
import com.haojie.teacher.common.activeRecord.ActiveRecordConfig;
import com.jfinal.kit.PathKit;
import com.jfinal.plugin.activerecord.dialect.MysqlDialect;
import com.jfinal.plugin.activerecord.generator.Generator;
import com.jfinal.plugin.druid.DruidPlugin;
import org.springframework.beans.factory.annotation.Autowired;
import javax.sql.DataSource;
public class _JFinalDemoGenerator {
public static DataSource getDataSource() {
DruidPlugin druidPlugin = new DruidPlugin("jdbc:mysql://localhost/edu_cloud?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8&useSSL=false", "root", "root");
druidPlugin.start();
return druidPlugin.getDataSource();
}
public static void main(String[] args) {
// base model 所使用的包名
String baseModelPackageName = "com.haojie.teacher.common.model.base";
// base model 文件保存路径
String baseModelOutputDir = PathKit.getWebRootPath() + "/src/main/java/com/haojie/teacher/common/model/base";
// model 所使用的包名 (MappingKit 默认使用的包名)
String modelPackageName = "com.haojie.teacher.common.model";
// model 文件保存路径 (MappingKit 与 DataDictionary 文件默认保存路径)
String modelOutputDir = baseModelOutputDir + "/..";
// 创建生成器
Generator generator = new Generator(getDataSource(), baseModelPackageName, baseModelOutputDir, modelPackageName, modelOutputDir);
// 设置数据库方言
generator.setDialect(new MysqlDialect());
// 设置是否生成链式 setter 方法
generator.setGenerateChainSetter(false);
// 添加不需要生成的表名
generator.addExcludedTable("adv");
// 设置是否在 Model 中生成 dao 对象
generator.setGenerateDaoInModel(false);
// 设置是否生成字典文件
generator.setGenerateDataDictionary(false);
// 生成
generator.generate();
}
}
UserService.java
import com.haojie.teacher.common.model.User;
import com.jfinal.plugin.activerecord.Db;
import org.springframework.stereotype.Service;
import javax.servlet.http.HttpSession;
import java.util.HashMap;
import java.util.Map;
@Service
public class UserService {
private User dao = new User();
public User SelectUserByUsernameAndPassword(String Username,String Password){
Map<String,String> map = new HashMap<String,String>();
map.put("username",Username);
map.put("password",Password);
return dao.findFirst(Db.getSqlPara("user.findbywhere",map));
}
}
Controller中在class中只需要@Autowired自动装箱,然后执行相应方法即可:
//controller中service装箱
@Autowired
private UserService userService;
//方法中执行
userService.SelectUserByUsernameAndPassword(username,password);
附freemaker的配置:applacation.properties,修改模板拓展名为.html
spring.freemarker.cache=false
spring.freemarker.suffix=.html
spring.freemarker.enabled=true
spring.freemarker.charset=utf-8
freemaker在controller中使用:
@RequestMapping(value = "/test")
public String test(Map<String, Object> map) {
User user = userService.SelectUserBySession(session);
map.put("login_user", user);
return "test"; //模板文件名去掉.html
}
end