Loading presentation...

Present Remotely

Send the link below via email or IM

Copy

Present to your audience

Start remote presentation

  • Invited audience members will follow you as you navigate and present
  • People invited to a presentation do not need a Prezi account
  • This link expires 10 minutes after you close the presentation
  • A maximum of 30 users can follow your presentation
  • Learn more about this feature in our knowledge base article

Do you really want to delete this prezi?

Neither you, nor the coeditors you shared it with will be able to recover it again.

DeleteCancel

JDBC Y PATRONES

No description
by

omar lopez

on 5 September 2013

Comments (0)

Please log in to add your comment.

Report abuse

Transcript of JDBC Y PATRONES

CURSO CAPACITACIÓN
JDBC Y PATRONES DE DISEÑO

JDBC
Patrones de Diseño
Introducción
El API JDBC es una API de Java que puede acceder a cualquier tipo de datos tabulares, especialmente datos almacenados en una base de datos relacional.
JDBC le permite escribir aplicaciones Java que manejan estas tres actividades de programación:
Conexión a una fuente de datos, como una base de datos
Enviar consultas e instrucciones de actualización de la base de datos
Recuperar y procesar los resultados recibidos de la base de datos en respuesta a su consulta


El siguiente fragmento de código simple da un ejemplo simple de estos tres pasos:

public void connectToAndQueryDatabase(String username, String password) {
Connection con = DriverManager.getConnection(
"jdbc:myDriver:myDatabase", username, password);
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery("SELECT a, b, c FROM Table1");
while (rs.next()) {
int x = rs.getInt("a");
String s = rs.getString("b");
float f = rs.getFloat("c");
}
}
Singleton
El patrón de diseño singleton está diseñado para restringir la creación de objetos pertenecientes a una clase o el valor de un tipo a un único objeto.
Su intención consiste en garantizar que una clase sólo tenga una instancia y proporcionar un punto de acceso global a ella.
El patrón singleton se implementa creando en nuestra clase un método que crea una instancia del objeto sólo si todavía no existe alguna. Para asegurar que la clase no puede ser instanciada nuevamente se regula el alcance del constructor (con atributos como protegido o privado).
Factory
En diseño de software, el patrón de diseño Factory Method consiste en utilizar una clase constructora abstracta con unos cuantos métodos definidos y otro(s) abstracto(s): el dedicado a la construcción de objetos de un subtipo de un tipo determinado. Es una simplificación del Abstract Factory, en la que la clase abstracta tiene métodos concretos que usan algunos de los abstractos; según usemos una u otra hija de esta clase abstracta, tendremos uno u otro comportamiento.
DAO
Modelo de objetos de acceso a datos o patrón DAO se utiliza para separar los datos de bajo nivel con el acceso API u operaciones de servicios de negocios de alto nivel. Los siguientes son los participantes en el patrón Data Access Object.

Interfaz de objetos de acceso a datos - Esta interfaz define las operaciones normales que se deben realizar en un objeto del modelo.
Los objetos de acceso a datos concretos de la clase -Esta clase implementa la interfaz anterior. Esta clase es responsable de obtener los datos de un origen de datos que puede ser la base de datos / xml o cualquier otro mecanismo de almacenamiento.
Modelo de objetos o de objeto de valor - Este objeto es POJO simple que contiene métodos get / set para almacenar los datos recuperados utilizando la clase DAO.
Ejemplo: Paso 1
import java.util.List;

public interface Dao<Entity,Key> {
Key create(Entity entity);
Entity read(Key key);
void delete(Entity entity);
void deleteByKey(Key key);
List<Entity>readAll();
}
Ejemplo: Paso 2
Crear Interface Dao en particular:
import java.util.List;
import mx.linko.trainee.jun13.mylinkbuster.persistence.hbm.Movie;

public interface MovieDao extends Dao<Movie,Long>{
List<Movie>getNewsWithMax(int max);
List<Object[]>searchByNameAndCategory(String text,Short categoryId);
}
Ejemplo: Paso 3
Crear clase concreta que implemente la interfaz.
import java.util.List;
import mx.linko.trainee.jun13.mylinkbuster.persistence.hbm.Movie;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

public class MovieDaoImpl extends HibernateDaoSupport implements MovieDao {

public List<Object[]> searchByNameAndCategory(String text,Short categoryId) {
return (List<Object[]>)this.getSession().createQuery(
"SELECT m.movieId, m.title "FROM Movie m WHERE m.title LIKE CONCAT('%', :text, '%') AND m.category.categoryId = :categoryId")
.setParameter("text", text)
.setParameter("categoryId", categoryId)
.list();
}
public List<Movie> getNewsWithMax(int max) {
return (List<Movie>)this.getSession()
.createQuery("FROM Movie m ORDER BY m.releaseDate DESC")
.setMaxResults(max)
.list();

}


Business
Delegate.
Patrón Business Delegate se utiliza para separar capa de presentación y la capa de negocio. Se utilizan básicamente para reducir la comunicación o la funcionalidad de búsqueda de código remoto entre la capa de negocios y la presentación.
Cliente -Presentación de nivel de codigo puede ser JSP, servlet o código java UI.
Delegado de negocios - Una única clase de punto de entrada para las entidades cliente para proporcionar acceso a los métodos de servicios empresariales.
Servicio de Búsqueda - objeto de servicio de búsqueda se encarga de obtener la ejecución de negocios relativa y proporcionar acceso a objetos de negocio a objeto negocio delegado.
Servicios de Negocio - Las clases concretas implementa este servicio para proporcionar lógica de negocio real aplicación de negocios.
Adapter
Patrón adaptador funciona como un puente entre dos interfaces incompatibles. Este tipo de patrón de diseño viene de Patrones estructurales, este modelo combina la capacidad de dos interfaces independientes.

Este modelo consiste en una sola clase que se encarga de unir las funciones de las interfaces independientes o incompatible.
MVC
Patrón MVC significa patrón Modelo-Vista-Controlador. Este patrón se utiliza para separar las preocupaciones de la aplicación.
Modelo - Modelo representa un objeto o Java POJO transportar datos. También puede tener lógica para actualizar controlador si sus cambios de datos.
Vista - Vista representa la visualización de los datos de modelo que contiene.
Controlador - Controlador de actos tanto en modelo y punto de vista. Controla el flujo de datos en objeto de modelo y actualiza la vista cada vez que cambien los datos. Guarda vista y el modelo independiente.
Value Object
Un objeto de valor es un pequeño objeto que representa una sencilla entidad cuya igualdad no se basa en la identidad: es decir, dos objetos de valor son iguales cuando tienen el mismo valor , no siendo necesariamente el mismo objeto .

Objetos de valor deben ser inmutables, así lo requiere el contrato implícito que dos objetos de valor creados iguales , debe permanecer igual.
Ejemplo
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class DateParser {
public static DateParser getInstance(){
return DateParser.SINGLETON;
}
private SimpleDateFormat yyyyMMdd = new SimpleDateFormat("yyyy-MM-dd");
public String yyyyMMddToString(Date date){
return this.yyyyMMdd.format(date);
}
public Date yyyyyMMddToDate(String date){
try {
return this.yyyyMMdd.parse(date);
} catch (ParseException e) {
throw new RuntimeException(e);
}
}
private DateParser(){}
private static final DateParser SINGLETON = new DateParser();
}

Crear una Interfaz Dao sin estado

public Long create(Movie entity) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}

public Movie read(Long key) {
return (Movie)this.getSession().get(Movie.class, key);
}

public void delete(Movie entity) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}

public void deleteByKey(Long key) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}

public List<Movie> readAll() {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}

}
JDBC
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

public class JdbcUtils {
private String driverClassName;
private String url;
private String user;
private String password;
private boolean driverLoaded;

public String getDriverClassName() {
return driverClassName;
}

public void setDriverClassName(String driverClassName) {
this.driverClassName = driverClassName;
}

public String getUrl() {
return url;
}


public void setUrl(String url) {
this.url = url;
}

public String getUser() {
return user;
}

public void setUser(String user) {
this.user = user;
}

public String getPassword() {
return password;
}

public void setPassword(String password) {
this.password = password;
}

public Connection getConnection()throws SQLException{
if(!driverLoaded){
try {
Class.forName(this.driverClassName).newInstance();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
return DriverManager.getConnection(this.url, this.user, this.password);
}
}
Crear una clase
import java.util.Date;
public class Person {
private Long personId;
private String personName;
private Date birthday;
private String email;
private char gender;
private String phone;
private String profilePicture;

public Long getPersonId() {
return personId;
}
public void setPersonId(Long personId) {
this.personId = personId;
}
public String getPersonName() {
return personName;
}
public void setPersonName(String personName) {
this.personName = personName;
}
public Date getBirthday() {
return birthday;
}

public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public char getGender() {
return gender;
}
public void setGender(char gender) {
this.gender = gender;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String getProfilePicture() {
return profilePicture;
}
public void setProfilePicture(String profilePicture) {
this.profilePicture = profilePicture;
}
@Override
public String toString() {
}
Crear Dao
public interface Dao <Entity,Key>{
Key create(Entity entity);
Entity read(Key key);
int update(Entity entity);
int delete(Key key);
}

Crear Interfaz para el Dao
import mx.linko.trainee.jun13.linkbook.persistence.vo.Person;

public interface PersonDao extends Dao<Person,Long>{

}

Implementación de la clase Dao
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import mx.linko.trainee.jun13.linkbook.persistence.dao.utils.JdbcUtils;
import mx.linko.trainee.jun13.linkbook.persistence.vo.Person;

public class PersonDaoImpl implements PersonDao {
public Long create(Person entity) {
Connection connection = null;
try {
connection = this.jdbcUtils.getConnection();

PreparedStatement ps1 = connection.prepareStatement(MAX);
ResultSet resultSet = ps1.executeQuery();

if(resultSet.next()){
Long maxId = resultSet.getLong("MAXID");
entity.setPersonId(maxId+1);
}

PreparedStatement ps = connection.prepareStatement(CREATE);
ps.setLong(1, entity.getPersonId());
ps.setString(2, entity.getPersonName());
ps.setDate(3, new java.sql.Date(entity.getBirthday().getTime()));
ps.setString(4, entity.getEmail());
ps.setString(5, Character.valueOf(entity.getGender()).toString());
ps.setString(6, entity.getPhone());
ps.setString(7, entity.getProfilePicture());
ps.executeUpdate();
return entity.getPersonId();
} catch (SQLException e) {
throw new RuntimeException(e);
}finally{
if(connection != null){
try {
connection.close();
} catch (Exception e) {}
}
}
}
public Person read(Long key) {
Connection connection = null;
try {
connection = this.jdbcUtils.getConnection();

PreparedStatement ps1 = connection.prepareStatement(READ);
ps1.setLong(1, key);

ResultSet resultSet = ps1.executeQuery();

Person person = null;
if(resultSet.next()){
person = new Person();
person.setBirthday(resultSet.getDate("BIRTHDAY"));
person.setEmail(resultSet.getString("EMAIL"));
person.setGender(
resultSet.getString("GENDER") == null ?
' ' :
resultSet.getString("GENDER").charAt(0));
person.setPersonId(resultSet.getLong("PERSON_ID"));
person.setPersonName(resultSet.getString("PERSON_NAME"));
person.setPhone(resultSet.getString("PHONE"));
person.setProfilePicture(resultSet.getString("PROFILE_PICTURE"));
}
return person;
} catch (SQLException e) {
throw new RuntimeException(e);
}finally{
if(connection != null){
try {
connection.close();
} catch (Exception e) {}
}
}
}

public int update(Person entity) {
Connection connection = null;
try {
connection = this.jdbcUtils.getConnection();

PreparedStatement ps = connection.prepareStatement(UPDATE);
ps.setLong(7, entity.getPersonId());
ps.setString(1, entity.getPersonName());
ps.setDate(2, new java.sql.Date(entity.getBirthday().getTime()));
ps.setString(3, entity.getEmail());
ps.setString(4, Character.valueOf(entity.getGender()).toString());
ps.setString(5, entity.getPhone());
ps.setString(6, entity.getProfilePicture());

return ps.executeUpdate();
} catch (SQLException e) {
throw new RuntimeException(e);
}finally{
if(connection != null){
try {
connection.close();
} catch (Exception e) {}
}
}
}
public int delete(Long key) {
Connection connection = null;
try {
connection = this.jdbcUtils.getConnection();

PreparedStatement ps = connection.prepareStatement(DELETE);
ps.setLong(1, key);

return ps.executeUpdate();
} catch (SQLException e) {
throw new RuntimeException(e);
}finally{
if(connection != null){
try {
connection.close();
} catch (Exception e) {}
}
}
}
private JdbcUtils jdbcUtils;

public JdbcUtils getJdbcUtils() {
return jdbcUtils;
}

public void setJdbcUtils(JdbcUtils jdbcUtils) {
this.jdbcUtils = jdbcUtils;
}
private static final String MAX = "SELECT MAX(PERSON_ID) AS MAXID FROM PERSON";
private static final String CREATE = "INSERT INTO PERSON(PERSON_ID,PERSON_NAME,BIRTHDAY,EMAIL,GENDER,PHONE,PROFILE_PICTURE) VALUES(?,?,?,?,?,?,?)";
private static final String READ = "SELECT * FROM PERSON WHERE PERSON_ID = ?";
private static final String UPDATE = "UPDATE PERSON SET PERSON_NAME=?,BIRTHDAY=?,EMAIL=?,GENDER=?,PHONE=?,PROFILE_PICTURE=? WHERE PERSON_ID=?";
private static final String DELETE = "DELETE FROM PERSON WHERE PERSON_ID = ?";
}
Capa de Servicio
Capa de Transacciones
import mx.linko.trainee.jun13.linkbook.persistence.vo.Person;

public interface PersonAbcService {
public Long save(Person entity) ;
public Person read(Long key) ;
public int delete(Long key);
}
Crear interfaz de Service:
package mx.linko.trainee.jun13.linkbook.service;

import java.util.Calendar;
import java.util.Date;
import mx.linko.trainee.jun13.linkbook.persistence.dao.PersonDao;
import mx.linko.trainee.jun13.linkbook.persistence.vo.Person;

public class PersonAbcServiceImpl implements PersonAbcService {
public Long save(Person entity) {
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.YEAR, -18);
Date date18YearsBefore = calendar.getTime();
if(date18YearsBefore.before(entity.getBirthday())){
throw new IllegalArgumentException("Too young");
}
if(entity.getPersonId() == null){//create
return this.personDao.create(entity);
}
this.personDao.update(entity);
return entity.getPersonId();
}
public Person read(Long key) {
return this.personDao.read(key);
}
public int delete(Long key) {
return this.personDao.delete(key);
}
private PersonDao personDao;
public PersonDao getPersonDao() {
return personDao;
}
public void setPersonDao(PersonDao personDao) {
this.personDao = personDao;
}
}

Crear la Implementación:
Crear un Servlet:
<%@page contentType="text/html" pageEncoding="windows-1252"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<jsp:useBean id="person" scope="request" class="mx.linko.trainee.jun13.linkbook.persistence.vo.Person"/>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
<title>Person form</title>
</head>

<body>
<form action="<c:url value="/person"/>" method="POST">
<label for="personId">Person id</label>
<input type="text" name="personId" id="personId" value="${person.personId}"/>
<button value="search" name="action" type="submit">Search</button>
<br/>
<label for="name">Name</label>
<input type="text" name="personName" id="name" value="${person.personName}"/>
<br/>
<label for="birthday">Birthday</label>
<input type="date" name="birthday" id="birthday" value="${person.birthday}"/>
<br/>

<label for="email">email</label>
<input type="email" name="email" id="email" value="${person.email}"/>
<br/>
<label for="gender">gender</label>
<input type="radio" name="gender" id="emailM" <c:if test="${person.gender == 'M'.charAt(0)}">checked="checked"</c:if> />M
<input type="radio" name="gender" id="emailF" <c:if test="${person.gender == 'F'.charAt(0)}">checked="checked"</c:if>/>F
<br/>
<label>Phone</label>
<input type="tel" name="phone" id="phone" value="${person.phone}"/>
<br/>
<button type="submit" name="action" value="delete">Delete</button>
<button type="submit" name="action" value="save">Save</button>
</form>
</body>
</html>
Vista
<!DOCTYPE html>
<html>
<head>
<title>Linkbuster</title>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
<link href="css/bootstrap/bootstrap/bootstrap.min.css" rel="stylesheet"/>
<script src="js/lib/jquery.js" type="text/javascript"></script>
<script type="text/javascript" src="js/lib/bootstrap.js"></script>
<script src="js/lib/underscore.js" type="text/javascript"></script>
<script src="js/lib/backbone.js" type="text/javascript"></script>
<script src="js/lib/require.js" type="text/javascript" data-main="js/main.js"></script>
</head>
<body>
<div class="navbar">
<div class="navbar-inner">
<ul class="nav">
<li class="active" id="movie-news-menu"><a href="#">News</a></li>
<li id="movie-categories-menu"><a href="#categories">Categories</a></li>
</ul>
</div>
</div>
<div class="container"></div>
</body>
</html>
Controlador
import mx.linko.trainee.jun13.mylinkbuster.api.controller.vo.catalog.CategoryVoList;
import mx.linko.trainee.jun13.mylinkbuster.api.controller.vo.catalog.MovieVoList;
import mx.linko.trainee.jun13.mylinkbuster.service.CatalogService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;


@Controller
@RequestMapping("/catalog")
public class CatalogController {
@RequestMapping(method = RequestMethod.GET,
value = "/movie/news")


@ResponseBody
public MovieVoList getMovieNews(
@RequestHeader(value = "mylinkbuster-max-movies",required = false, defaultValue = "5")int maxMoviews){
return this.catalogService.getNewMoviews(maxMoviews);
}

@RequestMapping(method = RequestMethod.GET,
value = "/category")
@ResponseBody
public CategoryVoList getCategories(){
return this.catalogService.getCategories();
}

@Autowired
private CatalogService catalogService;
}
Ejemplo
Crear Interfaz con los objetos de valor
import mx.linko.trainee.jun13.mylinkbuster.api.controller.vo.catalog.CategoryVoList;
import mx.linko.trainee.jun13.mylinkbuster.api.controller.vo.catalog.MovieVo;
import mx.linko.trainee.jun13.mylinkbuster.api.controller.vo.catalog.MovieVoList;
import mx.linko.trainee.jun13.mylinkbuster.persistence.hbm.Movie;
import mx.linko.trainee.jun13.mylinkbuster.persistence.hbm.MovieScreenshot;
import mx.linko.trainee.jun13.mylinkbuster.utils.DateParser;

public interface CatalogService {
MovieVoList getNewMoviews(int max);
CategoryVoList getCategories();
public static class Utils{
public static MovieVo parseMovieVo(Movie movie){
MovieVo vo = new MovieVo();
vo.setCategory(movie.getCategory().getCategoryName());
for(MovieScreenshot movieScreenshot : movie.getMovieScreenshots()){
vo.getImages().add(movieScreenshot.getUrl());
}
vo.setReleaseDate(
DateParser.getInstance().yyyyMMddToString(
movie.getReleaseDate()));
vo.setName(movie.getTitle());
vo.setId(movie.getMovieId());
return vo;
}
}

}
Implementar la Interfaz
import java.util.List;
import mx.linko.trainee.jun13.mylinkbuster.api.controller.vo.catalog.CategoryVo;
import mx.linko.trainee.jun13.mylinkbuster.api.controller.vo.catalog.CategoryVoList;
import mx.linko.trainee.jun13.mylinkbuster.api.controller.vo.catalog.MovieVoList;
import mx.linko.trainee.jun13.mylinkbuster.persistence.dao.CategoryDao;
import mx.linko.trainee.jun13.mylinkbuster.persistence.dao.MovieDao;
import mx.linko.trainee.jun13.mylinkbuster.persistence.hbm.Category;
import mx.linko.trainee.jun13.mylinkbuster.persistence.hbm.Movie;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

@Component
public class CatalogServiceImpl implements CatalogService {
@Transactional
public CategoryVoList getCategories() {
List<Category>categories = this.categoryDao.readAll();
CategoryVoList list = new CategoryVoList();
for(Category category : categories){
CategoryVo vo = new CategoryVo();
vo.setId(Long.valueOf(category.getCategoryId()));
vo.setName(category.getCategoryName());
list.add(vo);
}

List<Object[]>idsAndTotals=this.categoryDao.readAllWithTotal();
for(Object[]idAndTotal : idsAndTotals){
Short id = ((Number)idAndTotal[0]).shortValue();
Long total = ((Number)idAndTotal[1]).longValue();
for(CategoryVo aux : list){
if(aux.getId() == id.longValue()){
aux.setTotal(total);
break;
}
}
}
return list;
}

@Transactional
public MovieVoList getNewMoviews(int max) {
logger.info("Getting new moviews, max: "+max);
List<Movie>movies = this.movieDao.getNewsWithMax(max);
MovieVoList list = new MovieVoList();
for(Movie movie : movies){
list.add(CatalogService.Utils.parseMovieVo(movie));
}
if(logger.isTraceEnabled()){
logger.trace("Movies retrieved: "+list);
}
return list;
}
private static final Logger logger = Logger.getLogger(CatalogServiceImpl.class);
@Autowired
private MovieDao movieDao;
@Autowired
private CategoryDao categoryDao;
}
Full transcript