笔记参考于柏码知识库
JDBC交互框架 导入框架:
1 2 3 4 <dependency > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-starter-jdbc</artifactId > </dependency >
JDBC模板类 配置MySQL数据源:
1 2 3 4 <dependency > <groupId > com.mysql</groupId > <artifactId > mysql-connector-j</artifactId > </dependency >
1 2 3 4 5 6 spring: datasource: url: jdbc:mysql://localhost:3306/test username: root password: 123456 driver-class-name: com.mysql.cj.jdbc.Driver
使用JdbcTemplate完成数据库查询:
1 2 3 4 5 6 7 8 @Resource JdbcTemplate template;@Test void contextLoads () { Map<String, Object> map = template.queryForMap("select * from user where id = ?" , 1 ); System.out.println(map); }
编写自定义Mapper:
1 2 3 4 5 6 @Test void contextLoads () { User user = template.queryForObject("select * from user where id = ?" , (r, i) -> new User (r.getInt(1 ), r.getString(2 ), r.getString(3 ), r.getString(4 )), 1 ); System.out.println(user); }
JDBC简单封装 使用SimpleJdbcInsert工具来进行插入:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 @Configuration public class WebConfiguration { @Resource DataSource source; @Test void contextLoads () { SimpleJdbcInsert simple = new SimpleJdbcInsert (source) .withTableName("user" ) .usingGeneratedKeyColumns("id" ); Map<String, Object> user = new HashMap <>(2 ); user.put("name" , "bob" ); user.put("email" , "112233@qq.com" ); user.put("password" , "123456" ); Number number = simple.executeAndReturnKey(user); System.out.println(number); } }
JPA框架 最常用的JPA规范框架为Hibernate,SpringDataJPA也是采用Hibernate框架实现。
简单使用 导入依赖:
1 2 3 4 <dependency > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-starter-data-jpa</artifactId > </dependency >
使用注解在属性上添加数据库映射关系:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 @Data @Entity @Table(name = "account") public class Account { @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "id") @Id int id; @Column(name = "username") String username; @Column(name = "password") String password; }
开启日志打印:
1 2 3 4 5 6 7 spring: jpa: show-sql: true hibernate: ddl-auto: update
ddl-auto属性用于设置自动表定义,可以自动在数据库中创建表,表结构根据实体类决定,包括以下几种:
none: 不执行任何操作,数据库表结构需要手动创建。
create: 框架在每次运行时都会删除所有表,并重新创建。
create-drop: 框架在每次运行时都会删除所有表,然后再创建,但在程序结束时会再次删除所有表。
update: 框架会检查数据库表结构,如果与实体类定义不匹配,则会做相应的修改,以保持它们的一致性。
validate: 框架会检查数据库表结构与实体类定义是否匹配,如果不匹配,则会抛出异常。
为了访问表,需要创建Repository实现类:
1 2 3 @Repository public interface AccountRepository extends JpaRepository <Account, Integer> { }
插入操作:
1 2 3 4 5 6 7 8 9 10 @Resource AccountRepository repository;@Test void contextLoads () { Account account = new Account (); account.setUsername("小红" ); account.setPassword("1234567" ); System.out.println(repository.save(account).getId()); }
查询:
1 2 3 4 5 @Test void contextLoads () { repository.findById(1 ).ifPresent(System.out::println); }
方法名称拼接自定义SQL 可以通过方法名称拼接来进行条件查询等操作。
例如根据用户名模糊匹配查找:
1 2 3 4 5 @Repository public interface AccountRepository extends JpaRepository <Account, Integer> { List<Account> findAllByUsernameLike (String str) ; }
根据用户名和ID一起查询和判断是否存在某个ID的用户:
1 2 3 4 5 6 7 8 9 10 @Repository public interface AccountRepository extends JpaRepository <Account, Integer> { List<Account> findAllByUsernameLike (String str) ; Account findByIdAndUsername (int id, String username) ; boolean existsAccountById (int id) ; }
关联查询 可以看做对象间的依赖关系。如用户详细信息作为用户信息的外键:
用户详细信息:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 @Data @Entity @Table(name = "users_detail") public class AccountDetail { @Column(name = "id") @GeneratedValue(strategy = GenerationType.IDENTITY) @Id int id; @Column(name = "address") String address; @Column(name = "email") String email; @Column(name = "phone") String phone; @Column(name = "real_name") String realName; }
用户信息:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 @Data @Entity @Table(name = "users") public class Account { @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "id") @Id int id; @Column(name = "username") String username; @Column(name = "password") String password; @JoinColumn(name = "detail_id") @OneToOne AccountDetail detail; }
在数据库表中,是使用详细信息表的主键作为外键:
1 2 3 Hibernate: alter table users add column detail_id integer Hibernate: create table users_detail (id integer not null auto_increment, address varchar (255 ), email varchar (255 ), phone varchar (255 ), real_name varchar (255 ), primary key (id)) engine= InnoDB Hibernate: alter table users add constraint FK7gb021edkxf3mdv5bs75ni6jd foreign key (detail_id) references users_detail (id)
查询结果中也会自动关联数据:
1 2 Hibernate: select account0_.id as id1_0_0_, account0_.detail_id as detail_i4_0_0_, account0_.password as password2_0_0_, account0_.username as username3_0_0_, accountdet1_.id as id1_1_1_, accountdet1_.address as address2_1_1_, accountdet1_.email as email3_1_1_, accountdet1_.phone as phone4_1_1_, accountdet1_.real_name as real_nam5_1_1_ from users account0_ left outer join users_detail accountdet1_ on account0_.detail_id= accountdet1_.id where account0_.id= ? Account(id= 1 , username= Test, password= 123456 , detail= AccountDetail(id= 1 , address= 四川省成都市青羊区, email= 8371289 @qq .com, phone= 1234567890 , realName= 本伟))
添加懒加载标记,可以在需要时才向数据库获取:
1 2 3 @JoinColumn(name = "detail_id") @OneToOne(fetch = FetchType.LAZY) AccountDetail detail;
修改数据也可以进行关联操作:
1 2 3 @JoinColumn(name = "detail_id") @OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL) AccountDetail detail;
关联操作设定包括4种,且可以并存:
ALL:所有操作都进行关联操作
PERSIST:插入操作时才进行关联操作
REMOVE:删除操作时才进行关联操作
MERGE:修改操作时才进行关联操作
对于多对多的关系,可以插入中间表来一一对应:
1 2 3 4 5 6 @ManyToMany(fetch = FetchType.LAZY) @JoinTable(name = "teach_relation", //多对多中间关联表 joinColumns = @JoinColumn(name = "cid"), //当前实体主键在关联表中的字段名称 inverseJoinColumns = @JoinColumn(name = "tid") //教师实体主键在关联表中的字段名称 ) List<Teacher> teacher;
JPQL自定义SQL语句 对于复杂查询,可以使用面向对象的JPQL语言:
1 2 3 4 5 6 7 8 @Repository public interface AccountRepository extends JpaRepository <Account, Integer> { @Transactional @Modifying @Query("update Account set password = ?2 where id = ?1") int updatePasswordById (int id, String newPassword) ; }
也可以使用原生SQL:
1 2 3 4 5 @Transactional @Modifying @Query(value = "update users set password = :pwd where username = :name", nativeQuery = true) int updatePasswordByUsername (@Param("name") String username, //我们可以使用@Param 指定名称 @Param("pwd") String newPassword)
MybatisPlus 和JPA较为相似。支持链式调用:
1 2 3 4 5 6 7 8 @Test void contextLoads () { UpdateWrapper<User> wrapper = new UpdateWrapper <>(); wrapper .set("name" , "lbw" ) .eq("id" , 1 ); System.out.println(mapper.update(null , wrapper)); }
进一步将Service整合成模板,提供CRUD接口:
1 2 3 4 @Service public interface UserService extends IService <User> { }
1 2 3 @Service public class UserServiceImpl extends ServiceImpl <UserMapper, User> implements UserService { }
还可以根据数据库一键生成代码。