添加Spring boot支持,引入相关包:
1、maven工程,少不了pom.xml,spring boot的引入可参考官网:
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.9.RELEASE</version> </parent> <dependencies> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <scope>provided</scope><!-- 编译需要而发布不需要的jar包 --> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!--jpa的jar包 ,操作数据库的--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <!--mysql驱动--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-core</artifactId> <version>1.2.2</version> </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> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <executions> <execution> <goals> <goal>repackage</goal> </goals> </execution> </executions> </plugin> </plugins> <finalName>name</finalName> </build>
2、以上代码引入了spring boot。spring mvc 和jpa,以及mysql数据库的驱动jar;
编写启动类,并加装配置文件:
1、启动类如下:
import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.data.jpa.repository.config.EnableJpaAuditing; import java.io.IOException; import com.my.config.CommonProperties; @SpringBootApplication @EnableAutoConfiguration @EnableJpaAuditing public class Application { public static void main(String[] args) throws IOException{ String loc = CommonProperties.loadProperties2System(System.getProperty("spring.config.location")); System.getProperties().setProperty("application.version", CommonProperties.getVersion(Application.class)); System.getProperties().setProperty("app.home", loc + "/.."); SpringApplication.run(Application.class, args); } }
2、配置文件的位置放到classpath外边,方便在不重新打包的情况下修改,spring boot工程一般都打成jar包:
import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.util.Properties; import org.springframework.util.StringUtils; public final class CommonProperties { public static final String PPT_KEY_APP_HOME = "app.home"; public static final String DEFAULT_APP_HOME = "./"; public static final String getAppHome() { return System.getProperty("./", "./"); } public static String loadProperties2System(String location) throws IOException { String configLocation = location; File cnf; if (!StringUtils.hasLength(location)) { configLocation = "./config"; cnf = new File(configLocation); if (!cnf.exists() || !cnf.isDirectory()) { configLocation = "../config"; cnf = new File(configLocation); } } else { cnf = new File(location); } File[] arg2 = cnf.listFiles(); int arg3 = arg2.length; for (int arg4 = 0; arg4 < arg3; ++arg4) { File file = arg2[arg4]; if (file.isFile() && file.getName().endsWith(".properties")) { Properties ppt = new Properties(); FileInputStream fi = new FileInputStream(file); Throwable arg8 = null; try { ppt.load(fi); System.getProperties().putAll(ppt); } catch (Throwable arg17) { arg8 = arg17; throw arg17; } finally { if (fi != null) { if (arg8 != null) { try { fi.close(); } catch (Throwable arg16) { arg8.addSuppressed(arg16); } } else { fi.close(); } } } } } return configLocation; } public static String getVersion(Class<?> clazz) { Package pkg = clazz.getPackage(); String ver = pkg != null ? pkg.getImplementationVersion() : "undefined"; return ver == null ? "undefined" : ver; }
将配置文件放到jar包同级目录的config文件夹下,包括日志配置,application.yml文件,其他配置文件等;
编写自动配置类
用于扫描compan* ,代替spring mvc的spring.xml配置文件:
import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; @Configuration @ComponentScan(basePackages = { "com.my.rs", "com.my.service", "com.my.repository"}) public class AppAutoConfiguration { } import org.springframework.boot.autoconfigure.web.HttpMessageConverters; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; /** * 预配置 * */ @Configuration public class MyConfiguration extends WebMvcConfigurerAdapter{ @Bean public HttpMessageConverters customConverters() { return new HttpMessageConverters(); } @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { //registry.addResourceHandler("/**") // .addResourceLocations("classpath:/META-INF/resources/**"); }
编写rs,service,repository
package com.my.rs; import java.util.List; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import com.my.entity.User; @RequestMapping({"/api/user"}) public interface UserRS { @RequestMapping(value="/add",method={RequestMethod.POST}) @ResponseBody public User saveUser(@RequestBody User user); @RequestMapping(value="/update",method={RequestMethod.POST}) @ResponseBody public User updateUser(@RequestBody User user); @RequestMapping(value="/delete",method={RequestMethod.POST,RequestMethod.DELETE}) public void deleteUser(@RequestParam String[] userIds); @RequestMapping(value="/get",method={RequestMethod.GET}) @ResponseBody public User getUser(@RequestParam String userId); @RequestMapping(value="/query/all",method={RequestMethod.GET}) public List<User> queryAll(); @RequestMapping(value="/query/byName",method={RequestMethod.GET}) public List<User> queryByName(@RequestParam String name); @RequestMapping(value="/query/byParentId",method={RequestMethod.GET}) public List<User> queryChildren(@RequestParam String parentId); //无参数分页查询 @RequestMapping(value="/query/page",method={RequestMethod.GET}) public List<User> queryByPage(@RequestParam int pageNo, @RequestParam int pageSize, @RequestBody(required=false) User user); }
package com.my.rs.impl; import java.util.List; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; import com.my.entity.User; import com.my.rs.UserRS; import com.my.service.UserService; @RestController public class UserRSImpl implements UserRS{ public static Logger logger = LoggerFactory.getLogger(UserRSImpl.class); @Autowired UserService _userService; @Override public User saveUser(@RequestBody User user){ try { return _userService.save(user); } catch (Throwable e) { logger.error(e.getMessage(),e); throw e; } } @Override public User updateUser(@RequestBody User user) { return _userService.update(user); } @Override public void deleteUser(String[] userIds) { for (String userId : userIds) { _userService.deleteById(userId); } } @Override public List<User> queryAll() { return _userService.queryAll(); } @Override public List<User> queryByName(String name) { return _userService.findByName(name); } @Override public List<User> queryChildren(String parentId) { return _userService.findByParentId(parentId); } @Override public User getUser(String userId) { return _userService.findById(userId); } @Override public List<User> queryByPage(int pageNo, int pageSize, User user) { return null; } }
package com.my.service; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.my.entity.User; import com.my.repository.UserRepository; @Service public class UserService extends BaseService<User>{ @Autowired UserRepository _userRepository; public List<User> findByName(String name){ return _userRepository.findByName(name); } public List<User> findByParentId(String parentId){ return _userRepository.findByParentId(parentId); } }
package com.my.repository; import java.util.List; import com.my.entity.User; public interface UserRepository extends BaseRepository<User>{ List<User> findByName(String name); List<User> findByParentId(String parentId); }
以上采用了分层模式,有点繁琐,但是对之后修改每层的业务逻辑比较方便
JPA相关的类如下:
package com.my.service; import java.io.Serializable; import javax.persistence.EntityManager; import javax.transaction.Transactional; import org.springframework.beans.factory.annotation.Autowired; import com.my.repository.BaseRepository; /** * 一些共有的方法放这里 * */ @Transactional public class BaseService<E extends Serializable> { @Autowired BaseRepository<E> _baseRepository; @Autowired EntityManager em; public E save(E baseUnit){ return _baseRepository.saveAndFlush(baseUnit); } public E update(E baseUnit){ return _baseRepository.saveAndFlush(baseUnit); } public void deleteById(String id) { _baseRepository.delete(id); } public java.util.List<E> queryAll(){ return _baseRepository.findAll(); } public E findById(String id){ return _baseRepository.getOne(id); } }
package com.my.repository; import java.io.Serializable; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.repository.NoRepositoryBean; @NoRepositoryBean public interface BaseRepository<E> extends JpaRepository<E, Serializable>{ }
实体类:与数据库字段相关,需要注意下父类中的注解@MappedSuperclass
package com.my.entity; import java.util.ArrayList; import java.util.List; import javax.persistence.Entity; import javax.persistence.ManyToMany; import org.hibernate.annotations.DynamicInsert; import org.hibernate.annotations.DynamicUpdate; import org.hibernate.validator.constraints.Email; @Entity(name = "db_user") @DynamicInsert @DynamicUpdate public class User extends BaseUnit { /** * 账户状态 */ public static enum AccountStatus { /** * 正常 */ Enable, // /** * 停用 */ Disable } private static final long serialVersionUID = -3101319619397064425L; private String password; private String salt; /** 账户状态 */ private AccountStatus status; /** 认证邮箱 */ @Email(message = "User.email属性必须符合邮箱格式") private String email; /** 移动电话号码 */ private String mobileNo; /** 身份证号码 */ private String cardId; @ManyToMany(targetEntity=Role.class) private List<String> roleIds; /** 昵称。可选。 */ private String nickName; public String getCardId() { return cardId; } public String getEmail() { return email; } public String getMobileNo() { return mobileNo; } public String getNickName() { return nickName; } public String getPassword() { return password; } public List<String> getRoleIds() { if (roleIds == null) { roleIds = new ArrayList<>(); } return roleIds; } public String getSalt() { return salt; } public AccountStatus getStatus() { return status; } public void setCardId(String cardId) { this.cardId = cardId; } public void setEmail(String email) { this.email = email; } public void setMobileNo(String mobileNo) { this.mobileNo = mobileNo; } public void setNickName(String nickName) { this.nickName = nickName; } public void setPassword(String password) { this.password = password; } public void setRoleIds(List<String> roleIds) { this.roleIds = roleIds; } public void setSalt(String salt) { this.salt = salt; } public void setStatus(AccountStatus status) { this.status = status; } }
package com.my.entity; import java.io.Serializable; import java.util.Date; import javax.persistence.Id; import javax.persistence.MappedSuperclass; import javax.validation.constraints.NotNull; import javax.validation.constraints.Size; import org.springframework.data.annotation.CreatedBy; import org.springframework.data.annotation.CreatedDate; import org.springframework.data.annotation.LastModifiedBy; import org.springframework.data.annotation.LastModifiedDate; @MappedSuperclass public class BaseUnit implements Serializable { @Id @NotNull public String id; /** * 父单元ID */ @Size(max = 32, message = "BaseUnit.parentId属性长度不能大于32") public String parentId; /** 父单元的类型 */ public ParentType parentType; /** * 单元的名称 */ @NotNull(message = "BaseUnit.name属性不能为空") public String name; @CreatedBy public String createBy; @CreatedDate public Date createDate; @LastModifiedBy public String lastModifiedBy; /** * 最后更新日期 */ @LastModifiedDate public Date lastModifiedDate; public String getId() { return id; } public void setId(String id) { this.id = id; } /** * 获取单元的名称 * * @return 必填 */ public String getName() { return name; } /** * * * @return UUID,不含{}和- */ public String getParentId() { return parentId; } public ParentType getParentType() { return parentType; } public String getStationId() { return stationId; } public String getThumbnailId() { return thumbnailId; } public String getCreateBy() { return createBy; } public void setCreateBy(String createBy) { this.createBy = createBy; } public Date getCreateDate() { return createDate; } public void setCreateDate(Date createDate) { this.createDate = createDate; } /** * 设置单元的名称 * * @param name * 必填 */ public void setName(String name) { this.name = name; } /** * 设置父单元ID * * @param parentId * UUID,不含{}和- */ public void setParentId(String parentId) { this.parentId = parentId; } public String getLastModifiedBy() { return lastModifiedBy; } public void setLastModifiedBy(String lastModifiedBy) { this.lastModifiedBy = lastModifiedBy; } public Date getLastModifiedDate() { return lastModifiedDate; } public void setLastModifiedDate(Date lastModifiedDate) { this.lastModifiedDate = lastModifiedDate; } }
配置文件:
server: port: 16800 contextPath: / logging: config: ./config/logback.xml spring: http: multipart: enabled: false datasource: url : jdbc:mysql://127.0.0.1:3306/db?useUnicode=true&characterEncoding=utf-8 username : root password : 123456 driverClassName : com.mysql.jdbc.Driver jpa: database : MYSQL show-sql : true hibernate: ddl-auto : update jackson: serialization: INDENT_OUTPUT : true
#hibernate:配置了实体类维护数据库表结构的具体行为,update表示当实体类的属性发生变化时,表结构跟着更新,
这里我们也可以取值create,这个create表示启动的时候删除上一次生成的表,并根据实体类重新生成表,
这个时候之前表中的数据就会被清空;还可以取值create-drop,这个表示启动时根据实体类生成表,但是当sessionFactory关闭的时候表会被删除;
validate表示启动时验证实体类和数据表是否一致;none表示啥都不做。 #show-sql表示hibernate在操作的时候在控制台打印真实的sql语句 #jackson表示格式化输出的json字符串