基于 Spring boot + mvc + vue + Element ui + jpa + mysql + redis 的一个用户管理项目
最近在学习使用vuejs 然后结合之前学的知识来完成这么一个增删改查的小项目,页面预览1 初始化一个spring boot 项目 这里注意spring boot的版本要选1.X.X1 pom.xml 文件如下<?xml version="1.0" encoding="UTF-8"?><project xmlns=&q
最近在学习使用vuejs 然后结合之前学的知识来完成这么一个增删改查的小项目,页面预览
1 初始化一个spring boot 项目 这里注意spring boot的版本要选1.X.X
1 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.ryz.cn</groupId> <artifactId>springbootvuemvc</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>springbootvuemvc</name> <description>Demo project for Spring Boot</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.1.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> <thymeleaf.version>3.0.2.RELEASE</thymeleaf.version> <thymeleaf-layout-dialect.version>2.0.5</thymeleaf-layout-dialect.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</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-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> <version>1.5.9.RELEASE</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.44</version> </dependency> <dependency> <groupId>com.googlecode.log4jdbc</groupId> <artifactId>log4jdbc</artifactId> <version>1.2</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-redis</artifactId> <version>1.3.2.RELEASE</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
1.1主要依赖的是
spring-boot-starter-data-jpa 为了做持久化对象
mysql-connector-java MySQL驱动
spring-boot-starter-thymeleaf yml模板
spring-boot-starter-redis redis缓存
2 配置项目参数,具体的属性看注释吧
application.properties
spring.application.name=sh # server.servlet.context-path=/sh
server.context-path=/sh server.port=8081 # 数据源配置 spring.datasource.url=jdbc:log4jdbc:mysql://localhost:3306/test2 spring.datasource.username=root spring.datasource.password=157123 spring.datasource.driverClassName = net.sf.log4jdbc.DriverSpy spring.jpa.database = MYSQL spring.jpa.hibernate.ddl-auto=update spring.jpa.show-sql = true spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect # 定位模板的目录 spring.mvc.view.prefix=classpath:/templates/ # 给返回的页面添加后缀名 spring.mvc.view.suffix=.html spring.thymeleaf.cache=false #热部署生效 spring.devtools.restart.enabled: true # REDIS (RedisProperties) # Redis数据库索引(默认为0) spring.redis.database=0 # Redis服务器地址 spring.redis.host=127.0.0.1 # Redis服务器连接端口 spring.redis.port=6379 # Redis服务器连接密码(默认为空) spring.redis.password= # 连接池最大连接数(使用负值表示没有限制) spring.redis.pool.max-active=8 # 连接池最大阻塞等待时间(使用负值表示没有限制) spring.redis.pool.max-wait=-1 # 连接池中的最大空闲连接 spring.redis.pool.max-idle=8 # 连接池中的最小空闲连接 spring.redis.pool.min-idle=0 # 连接超时时间(毫秒) spring.redis.timeout=0 mode: LEGACYHTML5
2.1 这里 server.servlet.context-path 的配置根据spring boot版本的不同不一样,如果你在开发时发现不生效,随便百度一下就知道啦
3 controller 层代码
@Controller @RequestMapping("/user") public class UserController { @Autowired UserService userService; @RequestMapping(value="/getUserById",method = RequestMethod.GET) @ResponseBody public User getUserById(@RequestParam String id){ System.out.println("hello user"); User u = userService.findUserById(id); System.out.println(u); return u; } @RequestMapping(value="/foundAll",method = RequestMethod.GET) public String getUserById(Model model){ System.out.println("hello user"); List<User> users = userService.findAll(); System.out.println(users); model.addAttribute("Users", users ); return "index"; } @RequestMapping(value="/getUsers",method = RequestMethod.GET) @ResponseBody public Object getUserById(){ List<User> users = userService.findAll(); return users; } @RequestMapping(value="/getUserByOneId",method = RequestMethod.GET) @ResponseBody public Object getUserByOneId(@RequestParam String id){ User user = userService.findById(id); return user; } @RequestMapping(value="/deleteById",method = RequestMethod.GET) @ResponseBody public Object deleteById(@RequestParam String id){ int count = userService.deleteById(id); return count; } @RequestMapping(value="/init",method = RequestMethod.GET) @ResponseBody public String init(){ userService.init(); return "SUCCESS"; } @RequestMapping(value="/findMy",method = RequestMethod.GET) @ResponseBody public String findMy(String id){ return userService.findName(id); } @RequestMapping(value="/addOne",method = RequestMethod.POST) @ResponseBody public void addOne(@RequestBody User user){ userService.save(user); } }
4 实体对象 User
@Entity @Table(name = "user") public class User implements Serializable{ private String id; private String name; private Integer age; public User(){} public User(String id, String name, Integer age) { this.id = id; this.name = name; this.age = age; } @Id @Column(name = "id") public String getId() { return id; } public void setId(String id) { this.id = id; } @Column(name = "name") public String getName() { return name; } public void setName(String name) { this.name = name; } @Column(name = "age") public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } @Override public String toString() { return "User{" + "id='" + id + '\'' + ", name='" + name + '\'' + ", age=" + age + '}'; } } 4.1 注意这里的实体类一定要实现序列化接口,不然没有办法做缓存,否则可以不实现
5 Server层代码
@Service public class UserService { @Autowired private UserRepository userRepository; public List<User> findAll(){ return userRepository.findAll(); } @Transactional(rollbackFor = Exception.class) public void save(User user){ if("".equals(user.getId())){ user.setId(String.valueOf(System.currentTimeMillis())); } userRepository.save(user); } @Transactional(rollbackFor = Exception.class) public void init(){ userRepository.save(new User("20","ryz201",20)); userRepository.save(new User("21","ryz211",20)); userRepository.save(new User("22","ryz221",20)); userRepository.save(new User("22","ryz222",20)); userRepository.save(new User("23","ryz231",20)); } public User findUserById(String id){ return userRepository.findUserById(id); } // 给该查询方法增加缓存 //@Cacheable(value="user", keyGenerator = "keyGenerator") @Cacheable(value="user", key = "#id") public User findById(String id){ return userRepository.findUserById(id); } @Transactional(rollbackFor = Exception.class) @CacheEvict(value="user",key = "#id" ) public int deleteById(String id){ return userRepository.deleteById(id); } public String findName(String id){ return userRepository.findName(id); } }
5.1 这里需要注意redis缓存的注解写法
@Cacheable(value="user", key = "#id") value指的是缓存域,key是 就是数据的key 呗,
可以值一种自定义的规则,也可以是直接用入参作为key
@CacheEvict(value="user",key = "#id" ) 是根据key在value域中清除缓存
6 UserRepository类
@Repository @Table(name="user") public interface UserRepository extends CrudRepository<User,Long>{ public User findUserById(String id); @Override List<User> findAll(); User findByName(String name); int deleteById(String id); @Query("select u.name from User u where u.id= ?1") String findName(String id); }
6.1
继承的 CrudRepository 类以及帮我们实现了一些常用的方法,比如findByXX ,XX与实体类中的属性对应
7 启动类
@ComponentScan(basePackages="com.ryz.cn.springbootvuemvc") @EntityScan(basePackages="com.ryz.cn.springbootvuemvc.pojo") @EnableJpaRepositories(basePackages="com.ryz.cn.springbootvuemvc.repository") @SpringBootApplication @EnableCaching public class SpringbootvuemvcApplication { public static void main(String[] args) { SpringApplication.run(SpringbootvuemvcApplication.class, args); } }
7.1 注意实体类的扫描路径@EntityScan(basePackages="com.ryz.cn.springbootvuemvc.pojo")和 @EnableCaching 开启缓存
8 redis配置类
@Configuration @EnableCaching public class RedisConfig extends CachingConfigurerSupport { @Bean @Override public KeyGenerator keyGenerator() { return new KeyGenerator() { @Override public Object generate(Object target, Method method, Object... params) { StringBuilder sb = new StringBuilder(); sb.append(target.getClass().getName()); sb.append(method.getName()); for (Object obj : params) { sb.append(obj.toString()); } return sb.toString(); } }; } @Bean public CacheManager cacheManager(RedisTemplate<Object, Object> redisTemplate) { RedisCacheManager cacheManager = new RedisCacheManager(redisTemplate); // cacheManager.setCacheNames(Arrays.asList("users", "emptyUsers")); cacheManager.setUsePrefix(true); // Number of seconds before expiration. Defaults to unlimited (0) cacheManager.setDefaultExpiration(1800L); return cacheManager; } @Bean public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory connectionFactory){ RedisTemplate<Object, Object> template=new RedisTemplate<Object, Object>(); template.setConnectionFactory(connectionFactory); //实现序列化和反序列化redis的key值 template.setKeySerializer(new StringRedisSerializer()); //实现序列化和反序列化redis的value值,默认使用JdkSerializationRedisSerializer //template.setValueSerializer(new RedisObjectSerializer()); //template.setValueSerializer(); return template; } }8.1 这里主要方法,
keyGenerator() 键的生成规则,自定义规则
cacheManager() 缓存管理器,这里
RedisCacheManager cacheManager = new RedisCacheManager(redisTemplate);
需要注意下,根据不同的redis版本不同,构造方法一不一样,我遇到了很多坑
9 在resources 下面的templates 下创建index.html文件,结合了vuejs 和 Element ui 代码如下
<!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org"> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <title>用户管理</title> <link rel="stylesheet" href="//cdn.bootcss.com/element-ui/1.1.2/theme-default/index.css"> <script src="//cdn.bootcss.com/vue/2.1.8/vue.min.js"></script> <script src="//cdn.bootcss.com/element-ui/1.1.2/index.js"></script> <script src="//cdn.bootcss.com/vue-resource/1.0.3/vue-resource.min.js"></script> </head> <body> <div id="vm"> <el-row :gutter="20"> <el-col :span="6"> <div class="grid-content bg-purple"> <el-input placeholder="请输入姓名查询" v-model="searchName" clearable> </el-input> </div> </el-col> <el-col :span="6"> <div class="grid-content bg-purple"> <el-button type="primary" icon="el-icon-search" v-on:click="search()">搜索</el-button> </div> </el-col> <el-col :span="6"> <div class="grid-content bg-purple"> <el-form :model="user"> <el-form-item label="姓名" :label-width="formLabelWidth"> <el-input v-model="user.name" auto-complete="off"></el-input> </el-form-item> <el-form-item label="年龄" :label-width="formLabelWidth"> <el-input-number v-model="user.age" :min="1" :max="120" label="输入年龄"></el-input-number> </el-form-item> </el-form> </div> </el-col> <el-col :span="6"> <div class="grid-content bg-purple"> <el-button type="success" @click="addNew()">新增用户</el-button> </div> </el-col> </el-row> <el-table :data="tableData" stripe style="width: 100%"> <el-table-column prop="id" label="ID" width="180"> </el-table-column> <el-table-column prop="name" label="姓名" width="180"> </el-table-column> <el-table-column prop="age" label="年龄"> </el-table-column> <el-table-column inline-template fixed="right" label="操作" width="200"> <div> <el-button v-on:click="editH(row)" type="text" size="small">编辑</el-button> <el-button v-on:click="deleteH(row)" type="text" size="small">删除</el-button> </div> </el-table-column> </el-table> </div> <script> Vue.http.options.emulateHTTP = true; var vm = new Vue({ el: '#vm', data: { tableData: [], searchName: '', searchId:'', dialogFormVisible: false, user:{id:"",name:'',age:''}, formLabelWidth: '120px', }, methods:{ getData:function(){ this.$http.get("/sh/user/getUsers") .then(function (response) { console.log(response); this.tableData = response.body; }) .catch(function (response) { console.error(response); }); }, search:function(){ if(this.searchName==''){ return; } this.$http.get("/sh/user/getUserByOneId",{params: {id:this.searchId}}) .then(function (response) { console.log(response); this.tableData = []; if(response.body!=''){ this.tableData.push(response.body); } }) .catch(function (response) { console.error(response); }); }, deleteH:function(row){ this.$confirm('此操作将永久删除该'+row+', 是否继续?', '提示', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' }).then(() => { this.$http.get("/sh/user/deleteById",{params: {id:row.id}}) .then(function (response) { this.$message({ type: 'success', message: '删除成功!' }); this.getData(); }) .catch(function (response) { console.error(response); }); }).catch(() => { this.$message({ type: 'info', message: '已取消删除' }); }); console.log(row); }, addNew:function(){ this.$http.post("/sh/user/addOne",this.user) .then(function (response) { this.$message({ type: 'success', message: '添加成功!' }); this.getData(); this.user.id = ''; }) .catch(function (response) { console.error(response); }); }, editH:function(row){ this.user = row; } }, mounted: function () { this.getData(); }, watch:{ searchName(nv,ov){ for(var i=0;i<this.tableData.length;i++){ if(this.tableData[i].name == nv){ this.searchId = this.tableData[i].id; } } } } }) </script> </body> </html>
10 数据库user表DDL
CREATE TABLE `user` ( `id` varchar(255) NOT NULL, `name` varchar(10) DEFAULT NULL, `age` int(11) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
11 页面展示:
删除用户
12 看一下在查询用户后的缓存
13 总结
本着练习的心态,做完了这个小demo,其实有很多没有完善,比如不能把js和css 都写在一个html文件中,最好分开来,Element ui 真的很强大,只是用了其中的冰山一角,业务太简单了,没有结合消息中间件和其他的项目通信。demo实在太简单了,没啥说的,只做学习吧。
14 github 地址: https://github.com/ryz-13997318136/springbootvuemvc.git
更多推荐
所有评论(0)