一、环境与安装
tomcat 8.0+,jdk1.8+,根目录的数据库文件导入到mysql中,并修改资源包resource中的lcfms.properties保存相应的数据库名,用户名,密码即可启动。
QQ交流群:348455534
二、基础框架
底层是大家再熟悉不过的SSM,上手很容易,特别是如果你只需要使用“UI在线生成器”的时候,运行
http://localhost:8080/admin
可以看到顶部导航的右边就是“UI在线生成器”的链接。
三、老成FMS介绍
老成FMS是一个相对重量级的集成快速开发框架,前端后台数据库乃至业务都有一定的耦合度,后台使用大家再熟悉不过的JAVA SSM,前端有bootstrap,layui等。当然快速框架常用的功能都会有的,比如说栏目管理啦,用户管理啦,用户组及权限管理啦,CMS啦,生成静态页面啦等等。但这些都不是老成FMS与众不同的地方,下面我说说他的特别之处:
通用Service动态生成sql,其实就跟mybatis-plus类似,增删改查直接使用对象方法。但我觉得比mybatis-plus还更方便一些,0接口,0配置。具体类是cn.lcfms.bin.BaseService,功能保证强大,有兴趣的同学可以去看一看,支持直接传入sql语句,支持事务处理,下面有使用文档。
通用的增删改查页面,什么意思?你难道没有发现,项目每次增加一个业务,你就要复制几张jsp页面,大部分地方不变,少数几个地方修修改改,现在这些复制粘贴的地方你都可以不用写了,只需要后台传参数,有一个通用的页面,满足绝大多数功能。具体类都在cn.lcfms.bin.view这个包里。
当然万事无绝对,你的页面太复杂,通用页面满足不了,你只能老老实实写jsp,但FMS提供了前端代码生成功能,你不用再去下载调试demo,配置好参数,html代码自动生成。
四、关于路由
/WEB-INF/web.xml中可以配制你的默认路由,这里访问域名默认就跳转到/mobile/index/init,访问/admin就跳转到/admin/index/ace。很简单。
defaultPage
cn.lcfms.bin.DefaultPageFilter
/
/mobile/index/init
/admin
/admin/index/ace
五、关于调试
在lcfms.properties中设置,如果debug.on为true时,后台是不需要登录的,会默认使用下面配制的用户登录,还有很重要的,调试模式下,不能使用生成静态页面并获取缓存
debug.on=true
debug.aid=23
debug.aname=测试用户
debug.gid=1
六、使用教程
1、视频教程
2、BaseService操作手册(详见cn.lcfms.test.ServiceTest)
/* 执行添加操作,参数是按顺序传递,其中id为主键,如果有主键会自动在sql中生成并为它赋值,所以参数里不必要有主键
* sql:INSERT INTO `demo` (`id`,`s`,`i`,`t`) VALUES (?,?,?,?)
* param:9(Integer), abc(String), 1(Integer), a(String)
*/
public void t1(){
BaseService service = App.getService("demo");
service.setData("abc",1,'a').insert("s","i","t");
//最近一次插入操作的自增id
int insert_id = service.insert_id();
System.out.println(insert_id);
}
/* 执行添加操作,参数是按map的key进行匹配
* 这里注意了,javabean中存在且表中也存在的字段,但值为空或者为0,将一起被添加,如果不想被添加,可以使用service.insert(t, filter),其中filter为你不想修改的字段,多个字段用逗号隔开
* sql:INSERT INTO `demo` (`id`,`s`,`i`,`t`) VALUES (?,?,?,?)
* param:10(Integer), abcde(String), 1(Integer), s(String)
*/
public void t2(){
BaseService service = App.getService("demo");
HashMap map=new HashMap<>();
map.put("t", 's');
map.put("i", 1);
map.put("s", "abcde");
service.setData(map).insert("s","i","t");
//最近一次插入操作的自增id
int insert_id = service.insert_id();
System.out.println(insert_id);
}
/* 添加一个实体对象到数据库,参数自动匹配“表的字段名”与“实体的属性名”,匹配成功的属性将提交到数据库
* sql:INSERT INTO `demo` (`id`,`s`,`i`,`t`) VALUES (?,?,?,?)
* param:11(Integer), aaa(String), 5(Integer), n(String)
*/
public void t3(){
BaseService service = App.getService("demo");
DemoBean demo=new DemoBean();
demo.setI(5);
demo.setS("aaa");
demo.setT("n");
service.insert(demo);
//自增的主键id将自动映射到实体属性中
System.out.println(demo.getId());
}
/* 执行删除操作
* sql:DELETE FROM `demo` WHERE (`id`=?)
* param:1(Integer)
*/
public void t4(){
BaseService service = App.getService("demo");
//where("id=1")也可以,但如果1是变量的话不建议使用字符串拼接,不安全容易被注入
service.where("`id`=#{id}").setData(1).delete();
//最近一次sql操作影响的行数
int affected_rows = service.affected_rows();
System.out.println(affected_rows);
}
/* 根据主键id执行删除操作
* sql:DELETE FROM `demo` WHERE (`id`=?)
* param:27(Integer)
*/
public void t5(){
BaseService service = App.getService("demo");
//直接传主键id的值,程序会自动获取主键名并删除行
service.deleteById(27);
//最近一次sql操作影响的行数
int affected_rows = service.affected_rows();
System.out.println(affected_rows);
}
/* 执行修改操作,参数会按setData的顺序读取,条件参数要写在结尾,当然如果你用参数改用hashmap,可以自动匹配key的值,不需要考虑顺序
* sql:UPDATE `demo` SET `s`=?,`i`=?,`t`=? WHERE (`id`=?)
* param:abc(String), 123(Integer), m(String), 15(Integer)
*/
public void t6(){
BaseService service = App.getService("demo");
service.where("id=#{id}").setData("abc",123,'m',15).update("s","i","t");
}
/* 根据实体对象保存修改,系统会根据属性自动匹配主键以及被修改的字段名
* 这里注意了,javabean中存在且表中也存在的字段,但值为空或者为0,将一起被修改,如果不想被修改,可以使用service.update(t, filter),其中filter为你不想修改的字段,多个字段用逗号隔开
* sql:UPDATE `demo` SET `id`=?,`s`=?,`i`=?,`t`=? WHERE (`id`=?)
* param:13(Integer), aaa(String), 5(Integer), null, 13(Integer)
*/
public void t7(){
BaseService service = App.getService("demo");
DemoBean demo=new DemoBean();
demo.setI(5);
demo.setS("aaa");
demo.setId(13);
service.update(demo);
}
/*
* 执行各种查询方法,可以使用Vardump.print()方法打印结果
*/
public void t8(){
BaseService service = App.getService("demo");
//查询一张表,返回List结果集
List> list = service.selectList();
Vardump.print(list);
//查询一张表满足条件的第一行的某一个字段,返回该字段的值
int i=service.selectColumn("i");
System.out.println(i);
//查询满足条件的行数,返回行数int类型
int count=service.selectCount();
System.out.println(count);
//查询一个javabean,返回该javabean对象
DemoBean bean=service.selectOne(DemoBean.class, 15);
Vardump.print(bean);
//查询满足条件的第一个map,返回hashmap
HashMap map = service.selectMap();
Vardump.print(map);
//查询一个分页数据,返回List结果集,其中字段count表示满足该分页的总行数
List> pagedata = service.selectPage(15, 1);
Vardump.print(pagedata);
}
/*
* 复杂查询的sql组成
* sql:SELECT `s`,`i`,`t` FROM `demo` WHERE (`s`=?) AND (id>?) AND (i<>?) AND (t!='s' or t!='o') GROUP BY `id` ORDER BY `id` ASC LIMIT 0,10
* param:abc(String), 20, 15(Integer)
*/
public void t9(){
BaseService service = App.getService("demo");
//查询的字段,支持大小写的as或者空格的别名以及sql函数
service.column("s","i","t");
service.column("id as ID");
service.column("left(s,5) as ls");
//多条件拼装,支持in,between,like,or或者条件字符串
service.where("id>#{id}");
service.where("s", "abc");
service.where("i", "<>", 15);
service.where("t!='s' or t!='o'");
//设置动态参数
service.setData(20);
//limit拼装
service.limit(0, 10);
//order by拼装,默认是asc排序,使用desc可以service.order("id desc");
service.order("id");
//group by拼装
service.groupBy("id");
//执行查询,除了selectList()当然也支持其他的查询方法
service.selectList();
}
/*
* 多表查询,可以使用join方法
* 不支持多表连查(select * from table1,table2),如果要多表连查,推荐使用sql()方法
*/
public void t10() {
BaseService service = App.getService("demo");
//查询多张表的多个字段
service.column("demo.id as id","demo.s as s","admin.aid as aid");
service.leftJoin("admin").on("demo.id=admin.aid");
service.selectList();
//也可以给表添加别名,可以用setTable()方法,也可以用App.getService("demo d");
service.setTable("demo d");
service.column("d.id as id","d.s as s","a.aid as aid");
service.column("left(d.s,5) as ls");
service.leftJoin("admin a").on("d.id=a.aid");
service.selectList();
}
/*
* 支持函数式编程回调操作,不会用的的可以去看看java8.0的新特性lambda表达式
*/
public void t11() {
BaseService service = App.getService("demo");
//将id大于10的结果修改为id等于1,不大于的修改为id等于0
service.column("id",(Object obj)->{
int id=(int)obj;
if(id>10) {
return 1;
}
return 0;
});
service.selectList();
}
/*
* 支持事务处理,同样使用lambda表达式
*/
public void t12() {
BaseService service=App.getService("demo");
service.transaction(()->{
service.setData("abc666").insert("s");
service.setData("abc77777777777777777").insert("s");
});
}
/*
* 直接传入sql操作,支持使用setData()方法传入动态参数,动态参数必须使用#{参数名},不支持?
*/
public void t18(){
BaseService service = App.getService("demo");
service.setData(2).sql("select * from demo where id>#{id} limit 0,1");
//使用getResult()方法获取最近一次查询的结果集
List> result = service.getResult();
Vardump.print(result);
//也可以查看当前sql操作的所有信息,包括sql语句,参数,结果集等等
SqlBuild sqlBuild = service.getSqlBuild();
Vardump.print(sqlBuild);
}
/*
* 也可以多次使用sql操作,然后统一查看结果
*/
public void t19(){
BaseService service = App.getService("demo");
//这里如果有主键,且没有设置为自增,记得要给主键赋值,可以使用getKeyValue()方法来自动获取一个值
service.setData(service.getKeyValue(),"abc",15,'b').sql("INSERT INTO `demo` (`id`,`s`,`i`,`t`) VALUES (#{id},#{s},#{i},#{t})");
service.sql("DELETE FROM `demo` WHERE `id`=5");
service.setData(2).sql("select * from demo where id>#{id} limit 0,1");
SqlBuild[] list = service.getSqlBuildList();
Vardump.print(list);
}