一个移动端开发学习和总结Springboot的使用,并构建项目。为了更好的理解,我会写得很详细,很详细。
我这里学习的项目目标是搭建一个自己app使用的服务端,提供账户管理和个人数据配置的存取修改,后续会一步步记录到blog里。
====补充JPA的ORM方式处理数据(基于SpringBoot)
增加依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
定义repository即可自动生成简单的数据库操作方法
public interface EUserRepository extends JpaRepository<EUser, Long> {
}
配置实体类:其中Entity是标记JPA的model实体关联到hibernate的orm过程用的;Table是标记关联的表名;Builder是提供对象的复杂构建方式,方便构建对象用;Data是Lombok的注解,可以自动补充toString、getter、setter等方法。
@Entity
@Table(name = "user")
@Data
@Builder
public class EUser implements Serializable {
@Id
@GeneratedValue
private Long id;
@Column(name = "username")
private String username;
@Column(name = "binding_phone")
private String bindingPhone;
@Column(name = "password")
private String password;
@Column(name = "project_list")
private String projectList;
}
配置lombok需要在idea中下载插件和在pom中添加依赖,可以自行搜索方法。不用也可以手写补充getter、setter、toString方法
在测试中调试,可以看到repository自带save之类的简单数据操作方法,其中resource是自动注入repository用的注解。在EUser实体类的构建中使用了上面Builder的复杂构建方式,个人感觉比Constructor好用。
@SpringBootTest
public class UserTest {
@Resource
private EUserRepository userRepository;
@Test
public void testInsertUser() {
EUser user = EUser.builder().username("Eugene").bindingPhone("13700000000").password("123").build();
System.out.println(userRepository.save(user));
}
}
如果jpa方式获取数据时候报错could not initialize proxy – no Session
可以在application.properties的配置中增加spring.jpa.properties.hibernate.enable_lazy_load_no_trans=true
yml形式是
spring:
profiles:
active: dev
jpa:
show-sql: true
database-platform: org.hibernate.dialect.MySQL5InnoDBDialect
hibernate:
ddl-auto: update
properties:
hibernate:
enable_lazy_load_no_trans: true
====下面是MyBatis的ORM方式
插入数据到数据库
假设开发环境已经配置好,数据库的表已经设置好,springboot的项目也创建好,开发环境下yml文件也设置好了本地数据库连接。那么我们开始模拟插入数据。
我们需要用到实体类,下面省略getter setter方法和constructer方法:
public class EUser {
private long id;
private String username;
private String bindingPhone;
private String projectList;
...
}
在入口文件注解mapper的扫描目录,@MapperScan("…")中填写mapper的package位置(这个包用于存放mapper,mapper是什么?大概是一个用注解配置过的接口文件,按照注解的规则,springboot可以为我们完成剩下的于数据库交互工作),在项目中app是我的包目录,一般来说包目录是com.xxx.xxx,我这里设置的只有app,而mapper就是创建出来的package目录。后面要创建的mapper类接口也会放到这个目录下。
@SpringBootApplication
@MapperScan("app.mapper")
public class EopswitcherApplication {
public static void main(String[] args) {
SpringApplication.run(EopswitcherApplication.class, args);
}
}
在mapper目录下增加interface类型文件:
package app.mapper;
import app.model.EUser;
import org.apache.ibatis.annotations.*;
import java.util.List;
public interface EUserMapper {
@Insert("INSERT INTO user(username, binding_phone, project_list) VALUES(#{username}, #{bindingPhone}, #{projectList})")
void insert(EUser user);
}
使用@Insert注解直接填写sql,其中第一个括号包含的是数据库的字段名,后面括号是EUser的参数,这里用#{}引用EUser的属性。
接下来就可以调用测试插入数据了,编写单元测试是好习惯,可以更全面的检查我们代码的漏洞,使我们的代码更健全,减少后续修改bug的加班机会。
在项目的Test目录下新建一个UserTest的package,在里面新建一个EUserTest的测试类,增加@RunWith和@SpringBootTest的注解,该类就会自动配置单元测试相关的功能。使用@Autowired注解标记属性引用mapper,mapper会在扫描路径下找到对应的接口。使用@Test注解可以标记测试方法,在@Test方法的左边会出现运行按钮,点击debug模式的运行可以帮助跟踪错误,一般会在sql的编写中产生语法错误,耐心看报错,找出对应的语法错误并了解正确的语法规则,就能正确运行。
@RunWith(SpringRunner.class)
@SpringBootTest
public class EUserTest {
@Autowired
private EUserMapper userMapper;
@Test
public void testInsertUser() {
EUser user = new EUser(0,"Eugene", "13.9...1..1", "");
userMapper.insert(user);
}
}
测试正确后,使用终端连接数据库查看是否插入数据:
连接数据库:mysql -u root -p
显示所有数据库:show databases
连接数据库:use xxx
显示表:show tables
查看表数据:select * from xxx
显示
mysql> select * from user;
+----+----------+---------------+--------------+
| id | username | binding_phone | project_list |
+----+----------+---------------+--------------+
| 1 | Eugene | 13.9...1..1 | |
+----+----------+---------------+--------------+
1 row in set (0.00 sec)
然后我们再类似的在mapper里添加删改查的接口:
public interface EUserMapper {
@Select("SELECT * FROM user")
@Results({
@Result(property = "bindingPhone", column = "binding_phone"),
@Result(property = "projectList", column = "project_list")
})
List<EUser> getAll();
@Select("SELECT * FROM user WHERE id = #{id}")
@Results({
@Result(property = "bindingPhone", column = "binding_phone"),
@Result(property = "projectList", column = "project_list")
})
List<EUser> getOne(long id);
@Insert("INSERT INTO user(username, binding_phone, project_list) VALUES(#{username}, #{bindingPhone}, #{projectList})")
void insert(EUser user);
@Update("UPDATE user SET username=#{username}, binding_phone=#{bindingPhone}, project_list=#{projectList} WHERE id = #{id}")
void update(EUser user);
@Delete("DELETE FROM user WHERE id = #{id}")
void delete(long id);
}
其中@Results({})可以配置多个参数的映射,如果参数名一致就可以忽略,只需要配置不一样的就可以了。
在测试类中添加测试:
@RunWith(SpringRunner.class)
@SpringBootTest
public class EUserTest {
@Autowired
private EUserMapper userMapper;
@Test
public void testInsertUser() {
EUser user = new EUser(0,"Eugene", "00000000000", "");
userMapper.insert(user);
}
@Test
public void testGetUser() {
List<EUser> list = userMapper.getOne(1);
System.out.println(list.get(0).toString());
}
@Test
public void testGetAllUser() {
List<EUser> list = userMapper.getAll();
for (int i = 0; i < list.size(); i ++) {
System.out.println(list.get(i).toString());
}
}
@Test
public void testDeleteUser() {
userMapper.delete(1);
}
@Test
public void testUpdateUser() {
EUser user = new EUser(2,"Eugene3", "13700000000", "");
userMapper.update(user);
}
}
逐个检查是否成功修改数据库内容,mac下开发可以使用workbench图形化软件减少mysql的操作繁琐操作。