【myblog】1.为自己写的blog

在工作之后,自己的想法也有了很大的变化,比如,学android,做blog,微信开发等等,但这些事情还是一步步的实现为好,不然就和我以前一样,想了一遍之后就放着了,所以,为了记录我的目标达成的过程,这里我将一步步的实现我的第一个想法,自己写的blog。每一个阶段,我都将自己在开发过程中遇到的问题,和解决的问题记录在这里,和大家交流,提高自己的能力。

我工作之后就一直用的java,也没有学php,也没有接触类似CMS的系统,现在用java写起来感觉怪怪的,不过一步步的来。

对于项目的架构,我打算用ssh,本来打算用springmvc+iBATIS的,后来考虑到hibernate好久没有用了,就拿来当做复习,然后页面前端的话用的是easyui(也是边学边用),数据库用的mysql 服务器tomcat6,后来又买了一个域名,目前正在备案,又买了一个云主机,一旦备案完成,就一步步的迁移到云主机上面部署。

对于blog的结构,我在自己思考一下,做了一个简单的物理模型和功能结构图:


不是很专业,不过也能够理解。

为了能够简化开发的重复性工作,自己通过制定表结构的字段等规范,然后通过工具类,根据sql文件自动生成dao,service,domain,等相关代码。


自动生成的util工具类:

public void gen() throws Exception {
		/*******************加载数据库对应类型*************************/
		Map<String,String> type= new HashMap<String, String>();
		type.put("varchar","java.lang.String");
		type.put("int","int");
		type.put("float","float");
		type.put("timestamp","java.util.Date");
		type.put("datetime","java.util.Date");
		type.put("bit","boolean");
		//存放类名和所有字段类型集合
		Map<String, Map<String,String>> domain = new HashMap<String, Map<String,String>>();
		//字段以及类型
		Map<String, String> fieldType=null;
		
		
		/*******************加载数据库对应类型*************************/
		File file = new File("sql/myblog.sql");
		FileWriter writer = null;
//		List<String> list = null ;
		String str=null;
		BufferedReader reader = new BufferedReader(new FileReader(file));
		String line;
		//没有开始读表
		boolean flag=false;
		//标记是否生成主键<id name="textID" type="string" column="textID"><generator class="uuid"></generator></id>
		boolean flagkey=false;
		File file2 = new File("src/com/fairyt/myblog/domain/");
		if(!file2.exists())file2.mkdirs();
		while((line=reader.readLine())!=null){
			//开始读表了
			if(flag){
				//如果SQL语句结束
				if(line.toCharArray()[0]==')'){
					writer.write("</class>\n");					
					writer.write("</hibernate-mapping>");
					writer.close();
					//初始化标记重新读表
					flag=false;
					domain.put(str, fieldType);					
				}
				else{
					if(line.trim().toCharArray()[0]=='`'){
						//开始建立类的属性
						//获取的字段名
						String field=line.split("`")[1].split("_")[1].toLowerCase();
						String ftype=line.split("`")[2].split(" ")[1].split("\\(")[0];
						fieldType.put(field, type.get(ftype));
						//如果主键ID没有设置
						if(!flagkey){
							writer.write("<id name='"+field+"' type='"+type.get(ftype)+"' column='"+line.split("`")[1]+"'>\n"+
												"<generator class='uuid'></generator>\n"+
											"</id>\n");
							flagkey=true;
						}
						else{
							if(field.charAt(0)=='c')
								writer.write("<many-to-one name=\""+field.substring(1)+"\" column=\""+field.substring(1)+"_id\"/>\n");
//							else if(field.charAt(0)=='L'){
//								writer.write("<set name=\""+field+"\" cascade=\"all\" outer-join=\"true\">\n");
//								writer.write("<key column=\"demoid\" not-null=\"false\"></key>\n");
//								writer.write("<one-to-many class=\"com.fairyt.myblog.demo.domain.DemoSet\"/>\n");
//								writer.write("</set>\n");
//								
//							}
							else
								writer.write("<property name='"+field+"' type='"+type.get(ftype)+"' column='"+line.split("`")[1]+"'></property>\n");
							
						}
					}
				}
			}
			else{
				//如果开始创建表
				if(line.contains("CREATE TABLE")){
					String[] strs=line.split("`");
					String[] strs1=strs[1].split("_");
					char c=Character.toUpperCase(strs1[1].charAt(0));
					str=strs1[1].replaceFirst(String.valueOf(strs1[1].charAt(0)),String.valueOf(c));
					writer= new FileWriter("src/com/fairyt/myblog/domain/"+str+".hbm.xml");
					writer.write("<?xml version='1.0' encoding='UTF-8'?>\n"+
									"<!DOCTYPE hibernate-mapping PUBLIC \n"+
									    "'-//Hibernate/Hibernate Mapping DTD 3.0//EN'\n"+
									    "'http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd'>\n"+
									"<hibernate-mapping>\n");
					writer.write("<class name='com.fairyt.myblog.domain."+str+"' table='"+strs[1]+"'>\n");
					fieldType = new HashMap<String, String>();
					flagkey=false;
					flag=true;

				}
			}
		}
		reader.close();
		
		for(Map.Entry<String, Map<String, String>> maps:domain.entrySet()){
			writer = new FileWriter("src/com/fairyt/myblog/domain/"+maps.getKey()+".java");
			/****导包****************************/
			writer.write("package com.fairyt.myblog.domain;\n");
			writer.write("import java.io.Serializable;\n");

			
			writer.write("public class "+maps.getKey()+" implements Serializable{");
			for(Map.Entry<String, String> map : maps.getValue().entrySet()){
				
				/****字段的定义声明****************************/
				//如果是类的类型
				if(map.getKey().charAt(0)=='c'){
					writer.write("private com.fairyt.myblog.domain."+map.getKey().substring(1).replaceFirst(String.valueOf(map.getKey().charAt(1)),
							String.valueOf(Character.toUpperCase(map.getKey().charAt(1))))+" "+map.getKey().substring(1)+";");
					writer.write("\n");
					/****set方法****************************/
					writer.write("public void set"+
					map.getKey().replaceFirst(String.valueOf(map.getKey().charAt(1)),
									String.valueOf(Character.toUpperCase(map.getKey().charAt(1)))).substring(1)+
									"(com.fairyt.myblog.domain."+map.getKey().substring(1).replaceFirst(String.valueOf(map.getKey().charAt(1)),
											String.valueOf(Character.toUpperCase(map.getKey().charAt(1))))+" "+map.getKey().substring(1)+"){\n" +
									"this."+map.getKey().substring(1)+"="+map.getKey().substring(1)+";\n"+
									"}\n");
					/****get方法****************************/
					writer.write("public com.fairyt.myblog.domain."+map.getKey().substring(1).replaceFirst(String.valueOf(map.getKey().charAt(1)),
							String.valueOf(Character.toUpperCase(map.getKey().charAt(1))))+" get"+
							map.getKey().substring(1).replaceFirst(String.valueOf(map.getKey().charAt(1)),
											String.valueOf(Character.toUpperCase(map.getKey().charAt(1))))+
											"(){\n" +
											"return "+map.getKey().substring(1)+";\n"+
											"}\n");
				}
				else{
					writer.write("private "+map.getValue()+" "+map.getKey()+";");
				writer.write("\n");
				/****set方法****************************/
				writer.write("public void set"+
				map.getKey().replaceFirst(String.valueOf(map.getKey().charAt(0)),
								String.valueOf(Character.toUpperCase(map.getKey().charAt(0))))+
								"("+map.getValue()+" "+map.getKey()+"){\n" +
								"this."+map.getKey()+"="+map.getKey()+";\n"+
								"}\n");
				/****get方法****************************/
				writer.write("public "+map.getValue()+" get"+
						map.getKey().replaceFirst(String.valueOf(map.getKey().charAt(0)),
										String.valueOf(Character.toUpperCase(map.getKey().charAt(0))))+
										"(){\n" +
										"return "+map.getKey()+";\n"+
										"}\n");
				}
			}
			writer.write("}");
			writer.close();
			/*******************生成Dao*************************/	
			writer = new FileWriter("src/com/fairyt/myblog/dao/I"+maps.getKey()+"Dao.java");
			writer.write("package com.fairyt.myblog.dao;\n"+
							"import com.fairyt.myblog.domain."+maps.getKey()+";\n"+
							"public interface I"+maps.getKey()+"Dao extends ICommonDao<"+maps.getKey()+"> {\n"+
							"	public static final String SERVICE_NAME ="+Character.toString('"')+"com.fairyt.myblog.dao.impl."+maps.getKey()+"DaoImpl"+Character.toString('"')+";\n"+
							"}\n");
			writer.close();
			/*******************生成DaoImpl*************************/	
			writer = new FileWriter("src/com/fairyt/myblog/dao/impl/"+maps.getKey()+"DaoImpl.java");
			writer.write("package com.fairyt.myblog.dao.impl;\n"+
						"import org.springframework.stereotype.Repository;\n"+							
						"import com.fairyt.myblog.dao.I"+maps.getKey()+"Dao;\n"+
						"import com.fairyt.myblog.domain."+maps.getKey()+";\n"+							
						"	@Repository(I"+maps.getKey()+"Dao.SERVICE_NAME)\n"+
						"	public class "+maps.getKey()+"DaoImpl extends CommonDaoImpl<"+maps.getKey()+"> implements I"+maps.getKey()+"Dao {\n"+
						"}\n");
			writer.close();
			/*******************生成Service*************************/	
			writer = new FileWriter("src/com/fairyt/myblog/service/I"+maps.getKey()+"Service.java");
			writer.write("package com.fairyt.myblog.service;\n"+
							"import java.util.List;\n"+
							"import com.fairyt.myblog.domain."+maps.getKey()+";\n"+
							"public interface I"+maps.getKey()+"Service {\n"+
							"	public static final String SERVICE_NAME =\"com.fairyt.myblog.service.impl."+maps.getKey()+"ServiceImpl\";\n"+							
							"	void save"+maps.getKey()+"("+maps.getKey()+" entity);\n"+							
							"   List<"+maps.getKey()+"> findAll();\n"+
							"}\n");
			writer.close();
			/*******************生成ServiceImpl*************************/	
			writer = new FileWriter("src/com/fairyt/myblog/service/impl/"+maps.getKey()+"ServiceImpl.java");
			writer.write("package com.fairyt.myblog.service.impl;\n"+
							"import java.util.List;\n"+
							"import javax.annotation.Resource;\n"+							
							"import org.springframework.stereotype.Service;\n"+
							"import org.springframework.transaction.annotation.Isolation;\n"+
							"import org.springframework.transaction.annotation.Propagation;\n"+
							"import org.springframework.transaction.annotation.Transactional;\n"+							
							"import com.fairyt.myblog.dao.I"+maps.getKey()+"Dao;\n"+
							"import com.fairyt.myblog.domain."+maps.getKey()+";\n"+
							"import com.fairyt.myblog.service.I"+maps.getKey()+"Service;\n"+							
							"@Service(I"+maps.getKey()+"Service.SERVICE_NAME)\n"+
							"@Transactional(readOnly=true)\n"+
							"public class "+maps.getKey()+"ServiceImpl implements I"+maps.getKey()+"Service {\n"+
							"    @Resource(name=I"+maps.getKey()+"Dao.SERVICE_NAME)\n"+
							"    private I"+maps.getKey()+"Dao dao;\n"+								
							"	@Transactional(isolation=Isolation.DEFAULT,propagation=Propagation.REQUIRED,readOnly=false)\n"+
							"	public void save"+maps.getKey()+"("+maps.getKey()+" entity) {\n"+
							"		dao.save(entity);\n"+
							"	}\n"+
							"   public List<"+maps.getKey()+"> findAll() {\n"+
							"		return dao.findCollectionByConditionNoPage(\"\", null, null);\n"+
							"	}\n"+
							"}\n");
			writer.close();
		}
	}
}

在有sql文件之后,直接运行这个,然后项目中各个层都自动生成了。

在ssh环境搭建完成,测试无误之后,下面就可以进行功能模块的开发了。



好的,以下是一个简单的博客页面示例,使用了 Vue.js 和 Bootstrap: index.html: ``` <!DOCTYPE html> <html> <head> <title>My Blog</title> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/4.0.0/css/bootstrap.min.css"> </head> <body> <div id="app"> <nav class="navbar navbar-expand-lg navbar-dark bg-dark"> <a class="navbar-brand" href="#">My Blog</a> <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation"> <span class="navbar-toggler-icon"></span> </button> <div class="collapse navbar-collapse" id="navbarNav"> <ul class="navbar-nav"> <li class="nav-item"> <a class="nav-link" href="#" v-on:click.prevent="showPage('home')">Home</a> </li> <li class="nav-item"> <a class="nav-link" href="#" v-on:click.prevent="showPage('about')">About</a> </li> <li class="nav-item"> <a class="nav-link" href="#" v-on:click.prevent="showPage('blog')">Blog</a> </li> <li class="nav-item"> <a class="nav-link" href="#" v-on:click.prevent="showPage('contact')">Contact</a> </li> </ul> </div> </nav> <div class="container mt-4"> <div v-if="currentPage === 'home'"> <h1>Home Page</h1> <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing nec, ultricies sed, dolor. Cras elementum ultrices diam. Maecenas ligula massa, varius a, semper congue, euismod non, mi.</p> </div> <div v-if="currentPage === 'about'"> <h1>About Page</h1> <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing nec, ultricies sed, dolor. Cras elementum ultrices diam. Maecenas ligula massa, varius a, semper congue, euismod non, mi.</p> </div> <div v-if="currentPage === 'blog'"> <h1>Blog Page</h1> <div v-for="post in posts" :key="post.id"> <h3>{{ post.title }}</h3> <p>{{ post.content }}</p> <a href="#" v-on:click.prevent="showPost(post.id)">Read More</a> </div> </div> <div v-if="currentPage === 'contact'"> <h1>Contact Page</h1> <form> <div class="form-group"> <label for="name">Name:</label> <input type="text" class="form-control" id="name" v-model="contactForm.name"> </div> <div class="form-group"> <label for="email">Email:</label> <input type="email" class="form-control" id="email" v-model="contactForm.email"> </div> <div class="form-group"> <label for="message">Message:</label> <textarea class="form-control" id="message" v-model="contactForm.message"></textarea> </div> <button type="submit" class="btn btn-primary" v-on:click.prevent="submitForm">Send</button> </form> </div> <div v-if="currentPage === 'post'"> <h1>{{ currentPost.title }}</h1> <p>{{ currentPost.content }}</p> <a href="#" v-on:click.prevent="showPage('blog')">Back to Blog</a> </div> </div> </div> <script src="https://cdn.bootcss.com/vue/2.6.10/vue.min.js"></script> <script src="script.js"></script> </body> </html> ``` script.js: ``` var app = new Vue({ el: '#app', data: { currentPage: 'home', posts: [ { id: 1, title: 'Post 1', content: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing nec, ultricies sed, dolor.' }, { id: 2, title: 'Post 2', content: 'Cras elementum ultrices diam. Maecenas ligula massa, varius a, semper congue, euismod non, mi.' }, { id: 3, title: 'Post 3', content: 'Praesent vestibulum dapibus nibh. Etiam iaculis nunc ac metus.' }, ], currentPost: {}, contactForm: { name: '', email: '', message: '', }, }, methods: { showPage: function(page) { this.currentPage = page; }, showPost: function(id) { this.currentPost = this.posts.find(post => post.id === id); this.showPage('post'); }, submitForm: function() { console.log(this.contactForm); // send form data to server // reset form data this.contactForm.name = ''; this.contactForm.email = ''; this.contactForm.message = ''; alert('Form submitted!'); }, }, }); ``` 以上代码中的 `currentPage` 变量表示当前显示的页面,可以通过点击导航栏中的链接来切换页面。在 `Blog` 页面中,使用了 `v-for` 指令来循环显示博客文章,并且通过点击文章标题的链接来显示完整的文章内容。在 `Contact` 页面中,使用了 `v-model` 指令来绑定表单输入框的值,并且通过点击 `Send` 按钮来提交表单。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值