Skip to main content

快速开始

Step 1: 开发环境#

  • 要求JDK 11以上
  • Maven 3,后续会增加对Gradle的支持
  • IntelliJ IDEA 或者 Eclipse IDE

Step 2: 创建项目#

以下以IntelliJ IDEA创建Maven项目为例说明:

第一步:打开 IntelliJ IDEA 创建 maven 项目,如下图: alt 步骤一

第二步:填写项目存储路径,及项目的 GroupId、ArtifactId 和 Version,如下图: alt 步骤二

第三步:Maven 依赖,项目创建完成后,需要在pom.xml中加入对ready.work框架的依赖项:

<dependency>
<groupId>work.ready</groupId>
<artifactId>ready-work-core</artifactId>
<version>0.6.6.rc6</version>
</dependency>

如下图: alt 步骤三

需要注意的是,pom中的编译设置和项目设置里面的Java版本号必须一致,见下图: alt 注意JAVA版本 alt 注意JAVA版本 alt 注意JAVA版本

Step 3: Hello World#

第一步,构建一个app类,继承自Application,并加入main方法用于启动应用。

public class HelloWorld extends Application {
public static void main(String[] args) {
Ready.For(HelloWorld.class).Work(args);
}
}

第二步,构建一个FirstController继承自Controller类,并加入一个默认的index方法绑定在默认的URL路径/。

@RequestMapping(value = "/")
public class FirstController extends Controller {
@RequestMapping
public Result<String> index() {
return Success.of("hello world !");
}
}

通过运行 HelloWorld 的 main() 方法,即可启动应用,应用默认工作在当前主机本地IP的8080端口,可以直接http://127.0.0.1:8080/进行访问。

第三步,连接数据库。

  1. 请先建立一个test数据库,并运行demo.sql初始化测试数据。文件在examples\quickstart示例包中的resources下,也可以从数据库基础应用-演示数据复制。
  2. 常规方法是通过配置文件,这里我们先不涉及到配置文件,采用直接代码进行设置的方式连接数据库
public class HelloWorld extends Application {
@Override
protected void globalConfig(ApplicationConfig config) {
config.getDatabase().setDataSource("test", new DataSourceConfig()
.setJdbcUrl("jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&useSSL=false&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull")
.setUsername("root").setPassword("12345678").setSqlTemplate("sql/test.sql")
);
}
public static void main(String[] args) {
Ready.For(HelloWorld.class).Work(args);
//支持多个Application
//Ready.For(Main.class, AnotherApp.class).Work(args);
}
}

在我们的FirstController中访问数据库

@RequestMapping(value = "/")
public class FirstController extends Controller {
@RequestMapping
public Result<List> db() {
var data = Ready.dbManager().getDb().find("select * from demo");
return Success.of(data);
}
@RequestMapping
public Result<String> index() {
return Success.of("hello world !");
}
}

启动应用后,通过本机IP或者http://127.0.0.1:8080/db就可以访问。

Step 4: 服务注入与高级数据库操作#

第一步,首先建立数据表的base model,该工作可以手工建立,也可以由代码生成器生成(数据库-基础应用-代码生成器)。

import work.ready.core.database.Bean;
import work.ready.core.database.Model;
/**
* Generated by Ready.Work
*/
@SuppressWarnings("serial")
public abstract class BaseDemo<M extends BaseDemo<M>> extends Model<M> implements Bean {
public void setId(Integer id) {
set("id", id);
}
public Integer getId() {
return getInt("id");
}
public void setName(String name) {
set("name", name);
}
public String getName() {
return getStr("name");
}
public void setGender(Integer gender) {
set("gender", gender);
}
public Integer getGender() {
return getInt("gender");
}
public void setAge(Integer age) {
set("age", age);
}
public Integer getAge() {
return getInt("age");
}
public void setHeight(Integer height) {
set("height", height);
}
public Integer getHeight() {
return getInt("height");
}
public void setWeight(Integer weight) {
set("weight", weight);
}
public Integer getWeight() {
return getInt("weight");
}
public void setHobbies(String hobbies) {
set("hobbies", hobbies);
}
public String getHobbies() {
return getStr("hobbies");
}
public void setCreated(java.util.Date created) {
set("created", created);
}
public java.util.Date getCreated() {
return get("created");
}
public void setModified(java.util.Date modified) {
set("modified", modified);
}
public java.util.Date getModified() {
return get("modified");
}
public void setStatus(Integer status) {
set("status", status);
}
public Integer getStatus() {
return getInt("status");
}
public void setIsDeleted(Boolean isDeleted) {
set("isDeleted", isDeleted);
}
public Boolean getIsDeleted() {
return get("isDeleted");
}
public void setVersion(Integer version) {
set("version", version);
}
public Integer getVersion() {
return getInt("version");
}
}

第二步,建立数据表的model,该工作可以手工建立,也可以由代码生成器生成。

import model.base.BaseDemo;
import work.ready.core.database.annotation.Table;
/**
* Generated by Ready.Work
*/
@Table(tableName = "demo", primaryKey = "id")
public class Demo extends BaseDemo<Demo> {
}

第三步,创建一个服务类接口DemoService,并添加一个方法。

public interface DemoService {
List<Record> getAll();
}

第四步,创建一个服务实现类DemoServiceImpl,并实现该方法。这里实现方法通过Auto注解自动实现,关于该注解后续会单独介绍。

@Service
public class DemoServiceImpl extends ModelService<Demo> implements DemoService {
@Override
@Auto
public List<Record> getAll(){
return IfFailure.get(null);
}
}

第五步,在我们的FirstController中注入该服务并访问数据库,注入注解兼容Spring风格。

@RequestMapping(value = "/")
public class FirstController extends Controller {
@Autowired
private DemoService demoService;
@RequestMapping
public Result<String> index() {
return Success.of("hello world !");
}
@RequestMapping
public Result<List> db() {
var data = Ready.dbManager().getDb().find("select * from demo");
return Success.of(data);
}
@RequestMapping
public Result<List> dbService() {
var data = demoService.getAll();
return Success.of(data);
}
}

启动应用后,通过本机IP或者http://127.0.0.1:8080/dbService就可以访问,结果和http://127.0.0.1:8080/db一致。

第六步,添加更多数据库访问实例

为接口添加更多数据访问方法

public interface DemoService {
List<Record> getAll();
Boolean addRecord(String name, int gender, int age);
int updateByName(String name, Map<String, Object> map);
Boolean deleteByName(String name);
Record getFirstByName(String name);
List<Record> getAllByName(String name);
Page<Record> getByAge(int page, int size, int age);
}

实现这些方法,这里大部分的方法都是通过AUTO注解自动实现的,关于AUTO注解请参阅专题介绍

@Service
public class DemoServiceImpl extends ModelService<Demo> implements DemoService {
@Override
@Auto
public List<Record> getAll(){
return IfFailure.get(null);
}
@Override
public Boolean addRecord(String name, int gender, int age) {
Demo record = new Demo();
record.setName(name);
record.setGender(gender);
record.setAge(age);
return record.save();
}
@Override
@Auto
public int updateByName(String name, Map<String, Object> map) {
return IfFailure.get(0);
}
@Override
@Auto
public Boolean deleteByName(String name) {
return IfFailure.get(false);
}
@Override
@Auto
public Record getFirstByName(String name) {
return IfFailure.get(null);
}
@Override
@Auto
public List<Record> getAllByName(String name) {
return IfFailure.get(null);
}
@Override
@Auto("select * from _TABLE_ where age > ?")
public Page<Record> getByAge(int page, int size, int age) {
return IfFailure.get(null);
}
}

在Controller中应用这些方法

@RequestMapping(value = "/")
public class FirstController extends Controller {
@Autowired
private DemoService demoService;
@RequestMapping
public Result<String> index() {
return Success.of("hello world !");
}
@RequestMapping
public Result<List> db() {
var data = Ready.dbManager().getDb().find("select * from demo");
return Success.of(data);
}
@RequestMapping
public Result<List> dbService() {
var data = demoService.getAll();
return Success.of(data);
}
@RequestMapping(value = "add", method = RequestMethod.POST)
public Result<Boolean> addRecord() {
String name = Assert.notEmpty(getParam("name"), "name is required");
Integer gender = Assert.notNull(getParamToInt("gender"), "gender is required");
Assert.greaterThan(gender, -1, "gender must be greater than or equal to 0");
Assert.lessThan(gender, 2, "gender must be less than 2");
int age = Assert.notNull(getParamToInt("age"), "age is required");
Assert.greaterThan(age, 0, "age must be greater than 0");
var data = demoService.addRecord(name, gender, age);
return Success.of(data);
}
@RequestMapping(value = "update", method = RequestMethod.PUT)
public Result<Integer> updateByName() {
String name = Assert.notEmpty(getParam("name"), "name is required");
Integer gender = Assert.notNull(getParamToInt("gender"), "gender is required");
Assert.greaterThan(gender, -1, "gender must be greater than or equal to 0");
Assert.lessThan(gender, 2, "gender must be less than 2");
int age = Assert.notNull(getParamToInt("age"), "age is required");
Assert.greaterThan(age, 0, "age must be greater than 0");
var data = demoService.updateByName(name, Map.of("gender",gender, "age", age));
return Success.of(data);
}
@RequestMapping(value = "delete", method = RequestMethod.DELETE)
public Result<Boolean> deleteByName() {
String name = Assert.notEmpty(getParam("name"), "name is required");
var data = demoService.deleteByName(name);
return Success.of(data);
}
@RequestMapping
public Result<Record> getFirstByName() {
String name = getParam("name");
var data = demoService.getFirstByName(name);
return Success.of(data);
}
@RequestMapping
public Result<List> getAllByName() {
String name = getParam("name");
var data = demoService.getAllByName(name);
return Success.of(data);
}
@RequestMapping
public Result<Page> getByAge() {
int page = getParamToInt("page", 1);
int size = getParamToInt("size", 5);
int age = getParamToInt("age");
var data = demoService.getByAge(page, size, age);
return Success.of(data);
}
}

启动应用即可访问。

Step 5: 使用缓存提高性能#

通过@Cacheable、@CachePut、@CacheEvict、@CachesEvict注解标签可以动态对内容进行缓存。 针对上述例子,通过对服务实现类DemoServiceImpl的增删改查方法进行改造

@Service
public class DemoServiceImpl extends ModelService<Demo> implements DemoService {
@Override
@Auto
public List<Record> getAll(){
return IfFailure.get(null);
}
@Override
@CacheEvict(name = "testCache", key = "*")
public Boolean addRecord(String name, int gender, int age) {
Demo record = new Demo();
record.setName(name);
record.setGender(gender);
record.setAge(age);
return record.save();
}
@Override
@Auto
@CacheEvict(name = "testCache", key = "*")
public int updateByName(String name, Map<String, Object> map) {
return IfFailure.get(0);
}
@Override
@Auto
@CacheEvict(name = "testCache", key = "*")
public Boolean deleteByName(String name) {
return IfFailure.get(false);
}
@Override
@Auto
public Record getFirstByName(String name) {
return IfFailure.get(null);
}
@Override
@Auto
public List<Record> getAllByName(String name) {
return IfFailure.get(null);
}
@Override
@Cacheable(name = "testCache", key = "page:#(page)-#(size)-#(age)")
@Auto("select * from _TABLE_ where age > ?")
public Page<Record> getByAge(int page, int size, int age) {
return IfFailure.get(null);
}
}

通过对服务类的getByAge方法添加@Cacheable注解实现数据缓存。在第一次访问该方法后,数据将被缓存,此后对该方法的访问都将直接返回缓存数据,而不会再从数据库读取。 缓存以page/size/age三个参数作为识别编码实现按参数缓存,当存在三个参数匹配的缓存时直接读取缓存。 为了让缓存在数据变更后自动更新,为addRecord、updateByName、deleteByName增删改方法分别加上了@CacheEvict注解,当有增删改数据变更操作后清除缓存,让getByAge方法获得最新的数据。

That's it!#

恭喜你,到这里,你已经了解了Ready.Work框架的基本应用。