Handson
1. A company wants to send notifications via Email, SMS, and Push Notifications.
-Create an interface MessageService and three implementations (EmailService, SMSService, PushNotificationService).
-Autowire one of them into NotificationManager.
-Resolve the ambiguity by using @Qualifier.
Task: Configure so that only PushNotificationService is injected by default.
2. Your app should support sending all available notifications at once (Email + SMS + Push).
Task:
a. Modify NotificationManager to accept List<MessageService> or Map<String, MessageService>.
b. Autowire all beans and iterate to send multiple notifications.
@Autowired
- used to inject one bean into an another bean automatically, always perform based on byType
- used only above setter methods or constructor or fields(variables)
public class Venue {
private String venueId;
private String name;
private String location;
public Venue(String venueId, String name, String location) {
super();
this.venueId = venueId;
this.name = name;
this.location = location;
}
public Venue() {
super();
// TODO Auto-generated constructor stub
}
@Override
public String toString() {
return "Venue [venueId=" + venueId + ", name=" + name + ", location=" + location + "]";
}
}
public class Event {
private Integer eid;
private String name;
@Autowired
private Venue venue;
//@Autowired
public Event(Integer eid, String name, Venue venue) {
super();
this.eid = eid;
this.name = name;
this.venue = venue;
}
public Event() {
super();
// TODO Auto-generated constructor stub
}
public Event(Integer eid, String name) {
super();
this.eid = eid;
this.name = name;
}
@Override
public String toString() {
return "Event [eid=" + eid + ", name=" + name + ", venue=" + venue + "]";
}
}
@Bean
public Venue venue() {
return new Venue("100","Nehru Stadium","Chennai");
}
@Bean
public Event event() {
return new Event(1000,"Cricket");
}
public class Main {
public static void main(String[] args) {
ApplicationContext ctx=new AnnotationConfigApplicationContext(BeanConfiguration.class);
Event e=(Event)ctx.getBean(Event.class);
System.out.println(e);
}
}
@Qualifier
- If same bean is configured multiple times, which bean class has to be injected while using @Autowired is decided using @Qualifier
@Bean
public Venue venue() {
return new Venue("100","Nehru Stadium","Chennai");
}
@Bean
public Venue venue1() {
return new Venue("101","Nehru Stadium","Delhi");
}
@Bean
public Event event() {
return new Event(1000,"Cricket");
}
public class Event {
private Integer eid;
private String name;
@Autowired
@Qualifier("venue1")
private Venue venue;
//@Autowired
public Event(Integer eid, String name, Venue venue) {
super();
this.eid = eid;
this.name = name;
this.venue = venue;
}
public Event() {
super();
// TODO Auto-generated constructor stub
}
public Event(Integer eid, String name) {
super();
this.eid = eid;
this.name = name;
}
@Override
public String toString() {
return "Event [eid=" + eid + ", name=" + name + ", venue=" + venue + "]";
}
}
MVC architecture
client request - Controller prg(used to handle request and response) - Service prg(write business logic) - Repository - Database
Sterotype annotations
1. @Controller - it indicate it is a controller prg
2. @Service - it indicate it is a service prg
3. @Repository - it indicate it is a repository prg
4. @Component - used to refer single bean prg so that it can be injected into other prg using @Autowired
BeanFactory is lazy loading - it creates the bean only when we call getBean()
ApplicationContext is eager loading - preloads all the bean at the time of startup itself, so we have to convert ApplicationContext to lazy loading - 2 ways
1. by lazy-init="true" in xml file
2. @Lazy annotation
public class Sample1 {
public Sample1() {
System.out.println("Sample1 bean created");
}
}
public class Sample2 {
private Sample1 sample1; //referring another bean
public Sample1 getSample1() {
return sample1;
}
public void setSample1(Sample1 sample1) {
this.sample1 = sample1;
}
public Sample2() {
System.out.println("Sample2 bean created");
}
}
<bean id="sample1" class="com.pack.Sample1" lazy-init="true"/>
<bean id="sample2" class="com.pack.Sample2" lazy-init="true">
<property name="sample1" ref="sample1"/>
</bean>
@Configuration
@Lazy
public class BeanConfiguration {
@Bean
public Sample1 sample1() {
return new Sample1();
}
@Bean
public Sample2 sample2() {
return new Sample2();
}
}
public class Main {
public static void main(String[] args) {
/*Resource res=new FileSystemResource("hello.xml");
BeanFactory bf=new XmlBeanFactory(res);
Sample2 s=(Sample2)bf.getBean("sample2");*/
/*ApplicationContext ctx=new FileSystemXmlApplicationContext("hello.xml");
Sample2 s=(Sample2)ctx.getBean("sample2");*/
ApplicationContext ctx=new AnnotationConfigApplicationContext(BeanConfiguration.class);
Sample2 s=(Sample2)ctx.getBean(Sample2.class);
}
}
JPA(Java Persistence API)
- used to persist data into db
- It is a specification(inbuilt annotation, interface, classes etc) to persist the data into db
ORM(Object Relational Mapping framework)
- It is a provider or vendor who provides implementation for JPA using ORM tools like Hibernate, iBatis, JDO, Toplink etc
- used to map pojo class(entity/persistent class) with the columns of the database table
Features
1. open source framework, light weight
2. Database independent query
JPAQL(JPA Query Language) - query the entity class
SQL - query the table directly
3. Automatic table creation based on properties of entity class
4. Generate sql queries automatically
5. Faster in performance - using caching framework
client appl - JPA - Hibernate - Database
1. Configure db info and Hibernate properties in separate xml file
<!--Database information-->
<property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/dbname"/>
<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/>
<property name="javax.persistence.jdbc.user" value="root"/>
<property name="javax.persistence.jdbc.password" value="root"/>
<!--Hibernate properties-->
<property name="hbm2ddl.auto" value="create/update/create-drop/validate"/> --used to automatically create the table
1. create - create new schema,if the table already present it will recreate it
2. update - update the schema with given values with old values
3. create-drop - create the schema with destroying data previously present only on closing SessionFactory
4. validate - validate the schema by checking the table, if table not present it will throw an error
<property name="show-sql">true/false</property>
- used to display generated sql query in the console in single line
<property name="format-sql">true/false</property>
- used to display generated sql query in the console in formatted manner
<property name="use-sql-comments">true/false</property>
- used to display comments for the generated sql query in the console
<property name="dialect">org.hibernate.dialect.MySQL8Dialect</property>
- Hibernate will generate sql query based on particular db, on which db the sql query should be generated is decided based on dialect property
JPA - javax.persistence.* package - (inbuilt annotation, interface, classes etc)
1. EntityManagerFactory interface - used to create EntityManager interface and it brings all info from xml file
2. EntityManager interface - core interface used to persist data into db
Methods
1. void persist(Object o) - used to insert single object into db if PK is not present, if PK is already present then it will perform an update operation - generate insert or update query
2. Object find(Serializable s, Object pk) - used to select single data from db - generate select query
3. void remove(Object o)- remove single object from db table - generate delete query
4. void close()
5. boolean contains(Object o)
6. EntityTransaction getTransaction()
7. Query createQuery(String query) - write JPAQL
8. Query createNativeQuery(String query)- write SQL
9. Query createNamedQuery(String name) - identify query based on their name
3. EntityTransaction interface - create a transaction
- void begin()
- void commit()
- void rollback()
4. Query interface - used to write database independent query
1. Create maven java project with 2 dependency(hibernate-core, mysql driver)
<dependencies>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.4.24.Final</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.19</version>
</dependency>
</dependencies>
2. In mysql db , we create a database
mysql> create database aspirejava;
Query OK, 1 row affected (0.04 sec)
3. Configure db info and hibernate properties in persistence.xml inside resources/META-INF folder
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns=http://java.sun.com/xml/ns/persistence version="2.0">
<persistence-unit name="student-info" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<properties>
<!-- Database information -->
<property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/aspirejava"/>
<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/>
<property name="javax.persistence.jdbc.user" value="root"/>
<property name="javax.persistence.jdbc.password" value="root"/>
<!-- Hibernate properties -->
<property name="hibernate.hbm2ddl.auto">update</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</property>
</properties>
</persistence-unit>
</persistence>
4. Create entity/persistent class using JPA annotation - Simple POJO class which contains getter and setter method based on the columns of the database table
import javax.persistence.*;
@Entity - indicate it is a entity class so that these properties are mapped to columns of db table
@Table(name="stud100") - optional - used to map entity class properties to the columns of the table, if it is not given then by default it will create the table in the name of entity class itself
public class Student {
@Id - indicate it is a primary key(no duplication, no null value)
@GeneratedValue(strategy=GenerationType.AUTO(entire db)/IDENTITY(particular table)/SEQUENCE(only in oracle)/TABLE) - To indicate PK value to be autogenerated, in case if we not provide @GeneratedValue then we have to provide the value PK column
@Column(name="stud_id",length=20,nullable="true/false",unique="true/false",insertable="true/false",updatable="true/false",scale=7,precision=2) 12345.67
private Integer studentId;
@Column(name="sname")
private String name;
private Integer age;
@Temporal(TemporalType.DATE/TIME/TIMESTAMP) - used to map java util date to sql date
private Date dob;
private LocalDate doj;
//private String gender;
@Enumerated(EnumType.STRING/ORDINAL(0,1,2...))
private Gender gender;
@Lob - used to map large objects to db table like image, audio, video file
@Column(name="myPicture",columnDefination="BLOB")
private byte[] image;
@Column(name="stumark",scale="5",precision="2") //100.00
private Double mark;
@Transient - used to ignore the field at time of persisting
private String status;
}
public enum Gender {
MALE, FEMALE, OTHERS
}
No comments:
Post a Comment