7.1 உங்கள் சொந்த வகை மாற்றியை உருவாக்குதல்

ஒரு அட்டவணையின் ஒரு நெடுவரிசையில் மிகவும் சிக்கலான தரவு வகையைச் சேமிக்க விரும்பும்போது சில நேரங்களில் சூழ்நிலைகள் எழுகின்றன. அதை ஒரு சரமாக (மற்றும் பின்) மாற்றுவது எப்படி என்பதை Hibernate அறிந்திருந்தால், எல்லாம் நன்றாக இருக்கும். இல்லையெனில், நீங்கள் உங்கள் சொந்த தரவு மாற்றி எழுத வேண்டும்.

ஒரு பயனரின் பிறந்த ஆண்டை தரவுத்தளத்தில் சேமிக்க யாரோ ஒருவர் முடிவு செய்கிறார் என்று வைத்துக் கொள்வோம் YY.MM.DD, எடுத்துக்காட்டாக: 98.12.15. நீங்கள் அதை வழக்கமான தேதியாக மாற்ற வேண்டும்: 15/12/1998. பின்னர் நீங்கள் உங்கள் சொந்த மாற்றி எழுத வேண்டும்.

இதைச் செய்ய, நீங்கள் ஒரு இடைமுகத்தை செயல்படுத்த வேண்டும் AttributeConverter<EntityType, DbType>.


@Converter(autoApply = true)
public class DateConverter implements AttributeConverter<java.time.LocalDate, String> {
 
    public String convertToDatabaseColumn(java.time.LocalDate date) {
    	return date.format("YY.MM.DD");
    }
 
    public java.time.LocalDate convertToEntityAttribute(String dbData) {
    	String[] data = dbData.split(".");
    	return LocalDate.of(data[2], data[1], "19"+data[0]);
    }
}

மற்றும், நிச்சயமாக, இந்த மாற்றியை எந்தப் புலத்திலும் சேர்க்கலாம் (வகைகள் பொருந்தினால்):


@Entity
@Table(name="user")
class User {
   @Id
   @Column(name="id")
   public Integer id;
 
   @Column(name="join_date")
   @Convert(converter = DateConverter.class)
   public java.time.LocalDate date;
}

நீங்கள் தரவுத்தளத்தை வடிவமைக்கவில்லை என்றால் மாற்றிகள் அடிக்கடி பயன்படுத்தப்பட வேண்டும். அங்குள்ள தரவு "விசித்திர வடிவங்களில்" இருக்கலாம். தேதிகளை சரங்களாகவும், பூலியன்களை Y மற்றும் N மதிப்புகள் கொண்ட CHARகளாகவும், மற்றும் பலவற்றையும் சேமிக்கலாம்.

7.2 எங்கள் சொந்த தரவு வகையை உருவாக்குதல்

ஹைபர்னேட் அறியப்பட்ட வகைகளின் பட்டியல் கொண்ட அட்டவணையை நினைவில் கொள்கிறீர்களா? சிறுகுறிப்புடன் குறிப்பிடப்பட்ட வகைகளைப் பற்றி நான் பேசுகிறேன் @Type. உங்கள் சொந்த தரவு வகையை நீங்கள் எழுதலாம், இது ஹைபர்னேட்டில் உள்ள மற்ற உள்ளமைக்கப்பட்ட வகைகளைப் போலவே பயன்படுத்தப்படலாம்.

எடுத்துக்காட்டாக, நாங்கள் LocalTime வகையை வைத்திருக்க விரும்புகிறோம், இது தரவுத்தளத்தில் TIME ஆக அல்ல, VARCHAR ஆக சேமிக்கப்படும். மேலும், எடுத்துக்காட்டாக, அத்தகைய தரவுத்தளத்திற்கான அணுகல் எங்களிடம் உள்ளது, மேலும் அதன் நெடுவரிசைகளில் தரவு வகைகளை மாற்ற எங்களுக்கு அனுமதி இல்லை. பிறகு நாம் நமது சொந்த Hibernate வகையை எழுதலாம். அதை LocalTimeString என்று அழைப்போம்.

முதலில், எங்கள் புதிய வகையை விவரிக்கும் ஒரு சிறிய வகுப்பு தேவை:

public class LocalTimeStringType extends AbstractSingleColumnStandardBasicType<<LocalTime> {

    public static final LocalTimeStringType  INSTANCE = new LocalTimeStringType ();

    public LocalTimeStringType () {
    	super(VarcharTypeDescriptor.INSTANCE, LocalTimeStringJavaDescriptor.INSTANCE);
    }

    @Override
    public String getName() {
    	return "LocalTimeString";
    }
}

இது ஒரு மதிப்பைக் கொண்ட Enum வகையைச் சேர்ந்தது. அத்தகைய ஒற்றை ஈனாம்களின் தொகுப்பு ஹைபர்னேட் அறியப்பட்ட அனைத்து வகைகளாகும்.

எங்களுக்கு ஒரு வகுப்பு தேவை - மாற்றியின் அனலாக், இதில் இரண்டு முறைகள் இருக்கும் - wrap()மற்றும் unwrap()லோக்கல் டைம் வகையின் மதிப்புகளை சரமாக மாற்ற.

முறைகளை செயல்படுத்தாமல் இது எப்படி இருக்கும்:

public class LocalTimeStringJavaDescriptor extends AbstractTypeDescriptor<LocalTime> {

    public static final LocalTimeStringJavaDescriptor INSTANCE =  new  LocalTimeStringJavaDescriptor();

    public LocalTimeStringJavaDescriptor() {
    	super(LocalTime.class, ImmutableMutabilityPlan.INSTANCE);
    }

    public <X> X unwrap(LocalTime value, Class<X> type, WrapperOptions options) {

    }

    public <X> LocalTime wrap(X value, WrapperOptions options) {

    }

}

இப்போது முறைகளை செயல்படுத்துவதை எழுதுவோம்:

public <X> X unwrap(LocalTime value, Class<X> type, WrapperOptions options) {

    if (value == null)
    	return null;

    if (String.class.isAssignableFrom(type))
    	return (X) LocalTimeType.FORMATTER.format(value);

    throw unknownUnwrap(type);
}

மற்றும் இரண்டாவது முறை:

@Override
public <X> LocalTime wrap(X value, WrapperOptions options) {
    if (value == null)
    	return null;

    if(String.class.isInstance(value))
    	return LocalTime.from(LocalTimeType.FORMATTER.parse((CharSequence) value));

    throw unknownWrap(value.getClass());
}

தயார். நேரத்தை ஒரு சரமாகச் சேமிக்க இந்த வகுப்பைப் பயன்படுத்தலாம்:


@Entity
@Table(name="user")
class User
{
   @Id
   @Column(name="id")
   public Integer id;
 
   @Column(name="join_time")
   @Type(type = "com.codegym.hibernate.customtypes.LocalTimeStringType")  
   public java.time.LocalTime time;
}

7.3 உங்கள் வகையை பதிவு செய்தல்

ஹைபர்னேட் உள்ளமைவின் போது உங்கள் தரவு வகையையும் பதிவு செய்யலாம். இது சற்றும் அற்பமானதல்ல.


ServiceRegistry serviceRegistry = StandardServiceRegistryBuilder()
    .applySettings(getProperties()).build();
                                                                                                                                                              	                                        	 
    MetadataSources metadataSources = new MetadataSources(serviceRegistry);
    Metadata metadata = metadataSources
  	.addAnnotatedClass(User.class)
  	.getMetadataBuilder()
  	.applyBasicType(LocalTimeStringType.INSTANCE)
  	.build();
                                                                                                                                                              	                                        	 
    SessionFactory factory =  metadata.buildSessionFactory();

நீங்கள் முதலில் மெட்டாடேட்டா ஆதாரங்களைப் பெற வேண்டும், அதிலிருந்து மெட்டாடேட்டா பில்டரைப் பெற வேண்டும், மேலும் உங்கள் வகுப்பைச் சேர்க்க அதைப் பயன்படுத்த வேண்டும். மூலம் இது சாத்தியம் hibernate.cfg.xml, ஆனால் கொஞ்சம் சிரமமானது.

ஆனால் பதிவுசெய்த பிறகு, நீங்கள் இப்படி எழுதலாம்:


@Entity
@Table(name="user")
class User
{
   @Id
   @Column(name="id")
   public Integer id;
 
   @Column(name="join_time")
   @Type(type = "LocalTimeString")  
   public java.time.LocalTime time;
}