Use hibernate in eclipse

Source: Internet
Author: User
Tags xml attribute

Recently, I began to use eclipse as my development environment. This is because it supports many of the platforms I used during development, and partly because eclipse is an outstanding representative of an open and scalable environment, everyone can contribute their own strength to its development. I am investigating some extensions that people have proposed. For example, I used a small plug-in named xmlbuddy to process XML files, which is very useful. Therefore, I began to wonder if someone has compiled a plug-in that uses hibernate. Recently, I did a lot of work in writing developer's notebook. As a result, I have learned that some work is in progress. This article will discuss one of them, Hibernate synchronizer.

Hibernate Synchronizer
So far, among the plug-ins I have found, Hibernate synchronizer is of the greatest interest to me because it seems to provide the best support for ing-centric workflows, while myDeveloper's notebookThis type of workflow is used in this book. (Hibernate can be used for multiple purposes, so please check other available plug-ins. If your environment requires other methods, these plug-ins will be more helpful .) In fact, The Hibernate synchronizer plug-in allows you to update Java code without having to consider when modifying the ing document. It automatically updates Java code in a way similar to eclipse during editing. By creating a pair of classes for each mapped object, it is more advanced than the built-in hibernate code generation tool. It "owns" a base class. When you modify the ing, it can override this base class at will. It also provides a subclass that extends the base class. You can add business logic and other code to this subclass without worrying that it will disappear under your eyes.

Hibernate synchronizer also includes a new editor component for Eclipse, which provides intelligent assistance and Automatic Code Completion functions. An excellent DTD-driven XML editor (such as the xmlbuddy mentioned earlier) can implement some of the functions, but hibernate synchronizer can better understand the semantics of the document. It also provides a graphical view of attributes and relationships in the ing, a "Wizard" interface for creating new elements, and other similar advantages. As mentioned above, in its default configuration, the editor will automatically generate the data category when you edit the ing document.

Hibernate synchronizer has other functions. It adds a region to the new menu of Eclipse, provides a wizard for creating hibernate configuration and ing files, and adds context menu items to the package's resource manager and other appropriate locations, allows you to easily access related hibernate operations.

Now we have enough abstract descriptions. It's time to practice them! After all, you may be interested in this, or you will not read this article. So how to install and use hibernate synchronizer?

Install
You can use eclipse's built-in update manager to install hibernate synchronizer. This plug-in provides independent update sites for users of eclipse 2.1 and eclipse 3 to be released. Because I use eclipse for task-critical work, I still use the production version, that is, 2.1. At the time of writing this article, eclipse 3 has entered the "Release Candidate" stage. At the end of the summer, when I came back from the javaone conference, I very much hoped to upgrade to production version 3. (The main reason I mentioned this is to emphasize that the following guidance is written based on Eclipse 2. In eclipse 3, some commands and interfaces will undoubtedly be different, so if you want to use it, make sure you follow these steps and add your own judgment! My impression is that hibernate synchronizer's own Installation Guide is for eclipse 3, which may be helpful to you .)

Start eclipse and choose help> Software Updates> Update manager to open update manager. After the install/update perspective is enabled, right-click the feature updates view (or control-click the control). If you are using a single-button mouse, select new-> site bookmark, 1.


Figure 1. Add the hibernate synchronizer plug-in site to update Manager

In the displayed dialog box, enter the URL of the required plug-in version. The entered URL depends on your eclipse version:

  • Eclipse 2.1: http://www.binamics.com/hibernatesync/eclipse2.1
  • Eclipse 3: http://www.binamics.com/hibernatesync

You also need to specify a name for the new bookmarks. "hibernate synchronizer" is good. The dialog box shown in Figure 2 contains all the required information in my eclipse 2.1.2 environment.


Figure 2. hibernate synchronizer plug-in updates site bookmarks

After you click Finish, the new bookmarks will appear in the feature updates view, as shown in 3.


Figure 3. The Hibernate synchronizer site is now available

To install the plug-in, click the triangle extension symbol on the left of the bookmarks, and then click the next triangle extension symbol to repeat the process until the plug-in icon appears. Click the icon to update the preview. a page that allows you to install plug-ins is displayed, as shown in figure 4.


Figure 4. Prepare to install the plug-in

Click Install now to install the plug-in. eclipse will take you through the entire process (Figure 5-10 ).


Figure 5. Install hibernate Synchronizer


Figure 6. Plug-in License Agreement

See the following trade-offs for some discussions about the license agreement. Before deciding to use hibernate Synchronizer in your project, you may want to read it carefully. I think this is a good practice, but it is confusing that it is based on GPL and is not actually open source.


Figure 7. Select the plug-in installation location and use the default one.


Figure 8. Standard warnings for plug-ins without signatures


Figure 9. Installing


Figure 10. Installation Complete

Now that the plug-in has been installed, You need to exit and re-run eclipse to make it take effect. The dialog box appears to imply that eclipse will be restarted automatically, but in my experience, clicking yes will only exit the environment and must be restarted manually. This may be a limitation of Mac OS x Implementation of eclipse 2.1; eclipse 3 will be the first version that promises to provide first-class support for OS X. In any case, this is a small problem. If you need to restart eclipse, restart it now, because you should configure the plug-in!

Configuration
After eclipse is restarted, you can disable the install/update perspective. Open a Java project using hibernate. If you have read the examples in developer's notebook, there are several directories to choose from. I will use the example in Chapter 1 as this chapter can be read online. You can also download the source code of all examples from the book's site.

If you want to create a new Eclipse project to use one of the sample Source Code Directories, select File> New> project. Select to create a Java project, click Next, and name it ("hibernate CH3", as shown in 11). deselect the use default check box, in this way, you can tell eclipse the location of the existing project directory, and then click the Browse button to locate its location on the drive. Now you can click Finish to create the project, but I generally like to click Next and check the eclipse selection again. (Of course, if there are any errors, you can always return and modify the project properties, but I found that if there are errors such as library loss, a large number of errors and warnings will be immediately faced, this is really troublesome .)


Figure 11. Create a new project using hibernate

Here, my warnings are redundant. Eclipse understands the directory architecture and usage, and finds all third-party libraries I have downloaded and installed so that the Hibernate and HSQLDB database engines can run. (For details about this process, see Chapter 1st in developer's notebook .) This intelligent adaptability is one of the important features of Eclipse. Figure 12 shows that our new project is open and ready for experiment. It also shows that eclipse does not like to scale the window small enough to adapt to the appropriate screen snapshot. From now on, I can only capture part of the window.


Figure 12. Example project in Chapter 3rd

Next, create a hibernate configuration file that can be used by hibernate synchronizer.SRCA hibernate. properties file already exists in the directory, which describes the configuration of the example in the book. However, Hibernate synchronizer can only use hibernate's XML-based configuration method. Therefore, we need to copy the content of the hibernate. properties file to a new hibernate. cfg. xml file. In good terms, this allows us to see a feature of hibernate synchronizer, namely the configuration file wizard. Select File-> New-> Other, click the new available hibernate category, select hibernate configuration file, and click Next.


Figure 13. Start the hibernate configuration file wizard

After the Wizard is started, the directory provided by the wizard for file placement depends on the file selected in eclipse. For consistency considerations, you must put it and the properties version together in the top-levelSRCDirectory. Fill in the remaining information required by the wizard and match the configured properties version, as shown in figure 14. Note: Use ant to control the execution of hibernate (this isDeveloper's notebookThe methods used in this book) are different. When Hibernate is called, we cannot control the current working directory. Therefore, we need to use a fully qualified path to the database file in the URL. The value I used is (a bit ugly): JDBC: HSQLDB:/users/Jim/documents/work/oreilly/hibernate/examples/ch03/data/music. (If someone can tell me how to make eclipse or hibernate synchironizer use a specific working directory for a project, I will be very interested. I am a newbie in eclipse, so I will not be surprised if I know that this situation is possible, but I don't know how to do it .)


Figure 14. Fill in the configuration file details

It is a little strange to enter the Driver Class: You need to click the Browse button and enter the driver class name. If you enter "jdbcd", the window will only provide two options, so you can easily find the correct options, as shown in Figure 15.


Figure 15. Specify the HSQLDB Driver Class

After setting the values for your own installation as shown in figure 14, you can click Finish to create the configuration file. Hibernate synchronizer can be used now. It opens the created file, so you can see the structure and details of a hibernate xml configuration file.


Figure 16. generated configuration file

One way to quickly test whether the configuration takes effect is to use other wizard interfaces. Select File-> New-> Other, click the new available hibernate category, select hibernate mapping file, and click Next. When the wizard appears, it should fill in all the settings just entered, you can click the refresh button to confirm that it can communicate with the database, it also shows that a track table is found. For some reason, you may have to confirm the location of the. jar file containing the HSQLDB driver for the first time, but this happens only once. After confirming that everything is normal, click Cancel instead of creating the ing, because we want to manually create an existing ing file.

  Generate code
This is probably part of your expectation. What special things can we do? There is a new context menu item that can be used for hibernate ing.

If you right-click (or control click) Any item, you will see many hibernate-related options (figure 17), including a synchronization option. This is a way to manually allow hibernate synchronizer to generate data access objects related to the ing document.


Figure 17. synchronization options of the ing document

The add mapping reference option is also useful: it adds an item to the main hibernate configuration file to inform you about the ing document, therefore, you do not need to add any content to the source code to configure the corresponding ing. Now let's take a look at the result of selecting Synchronize files.

At this point, things have become interesting. Two new sub-packages, one of which is used to access the "base" data of hibernate synchronizer, can be rewritten at any time, the other business object used to generate subclass for these Dao objects will not be overwritten, which provides us with an opportunity to add business logic to the data class (18 ).


Figure 18. The synchronized Data Access Object shows the Editable subclass.

This generation analogy uses the conventional hibernate code generation tool to generate more classes, which has some advantages and some potential disadvantages. We will discuss these in the weigh-off section later. You can also select which classes are generated and their package structure in the property configuration of the project. I should have demonstrated this, but the current plug-in version has a bug that prevents access to this configuration interface on Mac OS X. The patch has been developed but has not yet been released.

Based on the examples on the hibernate synchronizer page and the following classes, I tried to use these new data access objects to insert some data into the music database. This is very similar to the version using the standard hibernate code generator (on the 39-40 page of hibernate: A developer's notebook), or even simpler, because the classes generated by hibernate synchronizer create and submit a new transaction for each database operation, you do not need to write code to set transactions in a simple environment like this. (Of course, there are many ways to run a group of operations as a single transaction .) The code for the new version is as follows:

package com.oreilly.hh;import java.sql.Time;import java.util.Date;import net.sf.hibernate.HibernateException;import com.oreilly.hh.dao.TrackDAO;import com.oreilly.hh.dao._RootDAO;/** * Try creating some data using the Hibernate Synchronizer approach. */public class CreateTest2 {    public static void main(String[] args) throws HibernateException {        // Load the configuration file        _RootDAO.initialize();                // Create some sample data        TrackDAO dao = new TrackDAO();        Track track = new Track("Russian Trance", "vol2/album610/track02.mp3",            Time.valueOf("00:03:30"), new Date(), (short)0);        dao.save(track);                track = new Track("Video Killed the Radio Star",            "vol2/album611/track12.mp3", Time.valueOf("00:03:49"), new Date(),            (short)0);        dao.save(track);                // We don't even need a track variable, of course:        dao.save(new Track("Gravity's Angel", "/vol2/album175/track03.mp3",            Time.valueOf("00:06:06"), new Date(), (short)0));    }}

When writing these codes, using eclipse is a great pleasure. I have forgotten how much I hope to use smart code to complete the function when I write examples for books, and jdt can also help in other aspects.

To run this simple program in eclipse, we need to set a new run configuration. Select Run> run... and use createtest2.java as the current active editor file. Click new, and eclipse will know that we want to run this class in the current project, because we use the main () method to create it. It specifies the default name createtest2. The page should be 19. Click Run to create some data.


Figure 19. Prepare to run our creation test in eclipse

If you follow these steps, you will find that the first attempt will fail: hibernate complained that the configuration file does not contain ing references, and at least one is required. Aha! Therefore, this is why xmlbuddy at the bottom of Figure 16 has a yellow underline warning. We can easily solve this problem by using the track in the package explorer view. HBM. right-click the XML ing document and select Add mapping reference from the new hibernate synchronizer sub-menu. This is the correct way for xmlbuddy to continue running. Unfortunately, the operation does not continue for long. The next error is that the initial context of JTA usertransaction cannot be found in JNDI. Obviously, I am not the only one who has encountered such a problem. The discussion on the topic of a forum is in full swing, but no one has found a solution.

Because I do not need to use JTA, I want to know why hibernate will try to find JTA. I opened the hibernate configuration file (Figure 16) and looked for any suspicious information in hibernate synchronizer. Undoubtedly, several rows are the most suspect:

<property name="hibernate.transaction.factory_class">        net.sf.hibernate.transaction.JTATransactionFactory  </property>  <property name="jta.UserTransaction">        java:comp/UserTransaction  </property> 

I tried to comment out the above content and run it again. The third operation was successful. No error occurred while running, and my data appeared in the database. Wow! Run a trusted antdb target (Developer's notebookThis is explained in chapter 1 of the book. All the data is displayed, as shown in section 20. To do this, make sure you create a database schema from an antschema, or clear any test data from the previous experiment.


Figure 20. data created by the test program

Note: You can run the ant target in eclipse by right-clicking the build. xml file in package explorer, selecting run an, and selecting the target in the eclipse dialog box. Cool?


Figure 21. Run ant in eclipse

Retrieving data through queries is quite simple, although this code is very similar to the code used by the Common Data Handler class generated by hibernate. Even if hibernate synchronizer generates a large number of helper methods for processing specified queries, I still think none of them are particularly useful because they all stick to running the query and return the result list, instead of providing directly usable query objects. This makes it impossible to use the convenient and type-safe parameter setting method of query. Because of this, I decided to have the rootdao object provide me with a hibernate session to use the old method. I think I can edit any template used by hibernate synchronizer to generate any method I want. If I want to use it to develop a project, I am almost sure I will do this.

In fact, for further consideration, when you get an Active session, you can only process the query, and Dao provides the best method. If you want to process the query as I did in this example, you must always manage your session. You can embed session management into the business logic provided by Dao, the half of your own, so that you can take advantage of both. This is another reason why the split classification model provided by hibernate synchronizer is so useful. I will discuss this in depth below.

In any case, the following code is basically the same as the Code on pages 48-49 in the book:

package com.oreilly.hh;import java.sql.Time;import java.util.ListIterator;import net.sf.hibernate.HibernateException;import net.sf.hibernate.Query;import net.sf.hibernate.Session;import com.oreilly.hh.dao.TrackDAO;import com.oreilly.hh.dao._RootDAO;/** * Use Hibernate Synchronizer's DAOs to run a query */public class QueryTest3 {    public static void main(String[] args) throws HibernateException {        // Load the configuration file and get a session        _RootDAO.initialize();        Session session = _RootDAO.createSession();        try {            // Print the tracks that will fit in five minutes            Query query = session.getNamedQuery(                TrackDAO.QUERY_COM_OREILLY_HH_TRACKS_NO_LONGER_THAN);            query.setTime("length", Time.valueOf("00:05:00"));            for (ListIterator iter = query.list().listIterator() ;                 iter.hasNext() ; ) {                Track aTrack = (Track)iter.next();                System.out.println("Track: /"" + aTrack.getTitle() +                                   "/", " + aTrack.getPlayTime());            }        } finally {            // No matter what, close the session            session.close();        }    }}

A good feature provided by trackdao is static constants. With this feature, we can request a specified query to eliminate any possibility of running errors caused by incorrect string input. I like this! Setting and executing the run configuration for this test class will generate the expected output, as shown in 22.


Figure 22. query results in the eclipse console View

As I mentioned earlier, after running this class, I realized that the model provided by hibernate synchronizer can be implemented in a better way. Because the specified query is a feature of the ing file related to the data access object, if we put the query into the trackdao object (this is where it actually belongs ), the object looks like the following:

package com.oreilly.hh.dao;import java.sql.Time;import java.util.List;import net.sf.hibernate.HibernateException;import net.sf.hibernate.Query;import net.sf.hibernate.Session;import com.oreilly.hh.base.BaseTrackDAO;/** * This class has been automatically generated by Hibernate Synchronizer. * For more information or documentation, visit The Hibernate Synchronizer page * at http://www.binamics.com/hibernatesync or contact Joe Hudson at joe@binamics.com. * * This is the object class that relates to the TRACK table. * Any customizations belong here. */public class TrackDAO extends BaseTrackDAO {    // Return the tracks that fit within a particular length of time    public static List getTracksNoLongerThan(Time time)        throws HibernateException    {        Session session = _RootDAO.createSession();        try {            // Print the tracks that will fit in five minutes            Query query = session.getNamedQuery(                QUERY_COM_OREILLY_HH_TRACKS_NO_LONGER_THAN);            query.setTime("length", time);            return query.list();        } finally {            // No matter what, close the session            session.close();        }    }}

This makes it clearer and further simplifies the main () method in querytest3:

    public static void main(String[] args) throws HibernateException {        // Load the configuration file and get a session        _RootDAO.initialize();        // Print the tracks that fit in five minutes        List tracks = TrackDAO.getTracksNoLongerThan(Time.valueOf("00:05:00"));        for (ListIterator iter = tracks.listIterator() ;             iter.hasNext() ; ) {            Track aTrack = (Track)iter.next();            System.out.println("Track: /"" + aTrack.getTitle() +                               "/", " + aTrack.getPlayTime());        }    }

Obviously, this is a method for processing the specified Query when hibernate synchronizer is used. After a quick test, you can confirm that it generates the same output, and its code is much better.

Whether you want to use hibernate synchronizer to generate its own data access object type is temporarily put down, and we have another important feature to explore.

Edit ing
A major attraction of hibernate synchronizer is its professional editor for the ing documentation. You can configure this editor to automatically regenerate relevant data objects as long as you save the file, but this is just a icing on the cake. Even if you do not plan to use the code generator of this plug-in, you may also want to use this editor. It provides you with the smart completion function for ing document elements, as well as a graphical outline view that can manipulate these elements.

HoweverDeveloper's notebookWhen downloading source code in a book starts, you must have at least one skill to make the editor work. In the downloaded file, the ing file extension is ". HBM. xml", and only files ending with ". HBM" can call the editor. Theoretically, you can configure extension ing in eclipse so that all files with these two extensions can use the ing document editor of the plug-in, but I cannot make it take effect, I also noticed that some people on the support forum are facing the same problems as me. Therefore, at least the best practice at present is to rename the file. (If you insist on using ant-based standard code generation, make sure to update the codegen target in build. XML to use the new extension .)

After I rename track. HBM. XML to track. HBM, the icon in package explorer is updated to the hibernate logo, and the default editor is changed to the plug-in Editor, as shown in Figure 23. For some reason, other hibernate synchronizer options (17) are available for any of these extensions, but the editor is only available for shorter versions.


Figure 23.HibernateContext menu of the ing document (with the extension ". HBM ")

The editor provides context-related Automatic completion support for all elements added to the ing document. Figure 24 shows some examples, but the screen cannot really capture the depth and validity of this feature. I strongly recommend that you install and use the plug-in. You will soon see how useful it is in processing ing documents.


Figure 24 and 25. Complete the auxiliary functions in the ing document Editor

As shown in Figure 26, the outline view provides a graphical view of the class hierarchy, mapped elements, specified queries, and various elements in the ing document. It also provides a menu, some wizard can help you create new properties.

  

  

Figure 26 and 27. Map the editor's Outline View and add property wizard

The context menu in the editor also provides a format source code option that can be used to organize and reconstruct documents. This editor already has many smart and useful features. It is also interesting to see how they develop. The only thing I'm not satisfied with is that when the XML Attribute is completed, this editor is used to help you manage quotation marks in a completely different way than that used by jdt in Java code. Switching between them will confuse people. (It takes some time for you to adapt to the jdt method of work, but once you trust it, it becomes magic .)

Generate database mode
Although my first impression is that everything comes from the ing document, Hibernate synchronizer currently does not support creating or updating the database mode from the ing document. The support forum has already submitted related requests, so I will not be surprised to see these features in the future, because it is not very difficult to provide such support. Currently, to develop a database from a ing document, you must use methods such as ant driver in hibernate: A developer's notebook. In addition, the hibernator plug-in described below supports pattern update in eclipse. I may want to check whether these two plug-ins can be installed at the same time.

I hope this article will give you a clear understanding of the functions provided by the plug-in. In any case, I do not cover all its functions, so if you are interested, you can download it and explore it on your own.

Trade-offs
Without a doubt, you can use hibernate synchronizer to do some clever work. Do you want to use it in my own hibernate project? This method has advantages and disadvantages. It is likely that, when Hibernate is used instead of the lightweight o/R tool we are using (and too simple, I will make a decision. This is a significant change, and we have postponed this change to another reason for architecture change. The following are some factors that play an important role in my decision.

As we mentioned in the installation section, there are still some problems with licenses. This discussion is available in the plug-in forum. The current license is based on custom modifications to gnu gpl. This modification deletes all source code sharing terms, but attempts to retain other aspects of "copyleft" protection. There are still some problems about the legitimacy of this operation, and the author is looking for another solution. It is clear that the purpose is to protect the plug-in, rather than prevent any other project from using the plug-in to generate code, but it is necessary to carefully read the current license to see if the purpose has been achieved, or are you still at great risk.

The same discussion showed that the author originally released the plug-in the form of open source, but temporarily withdrew the decision because he thought it was not perfect enough to serve as an excellent example. Next, he and some reckless people sent some unpleasant emails, which made him reluctant to share the source code. Of course, he has the right to decide whether to share the source code with us. This plug-in is a great gift for the whole world, and the author does not owe us anything. But I hope he can have enough positive communication with other users, so that he can firmly grasp his original idea of sharing source code. I really think it is very valuable to see the source code of the tool I am using, not only because it is a good learning opportunity, but also because it means that, if necessary, I can fix some minor problems immediately. The author is always enthusiastic and responsive in solving user problems, but one person cannot maintain a community because we are busy, exhausted, and upset.

Hibernate synchronizer uses its own template and mechanism to generate the data handler class, which has both advantages and disadvantages. The advantage is that it provides more functions than hibernate's "standard" code generation tool. You can use an automatically generated subclass of a Data Object and embed the business logic in the data object without worrying that the business logic will be rewritten when the access code is re-generated, this is also a good feature. The generation of plug-ins makes many simple scenarios simpler. Classes also provide other advantages.

On the other hand, this also means that the code generated by hibernate synchronizer lags behind hibernate after some new features or modifications are added to the hibernate platform. Plug-in Code also has bugs in support for patterns that are not commonly used by hibernate: it has a small user base and can be updated by one person. You can find evidence of this phenomenon on the forum.

Like many things, whether the potential advantages exceed the risk is determined by you. Even if you do not use the code generator, you will find the ing editor very useful. If you only want to use the editor's Automatic completion and auxiliary functions, you can turn off the automatic synchronization option.

If you have used this plug-in and find it useful, I suggest you contact the author to express your gratitude and to donate some funds to help you support its future development.

Other plug-ins
So far, I have found two plug-ins that also support hibernate in eclipse. (If you still know other plug-ins, or you may encounter such plug-ins in the future, I would like to know them .) Maybe I will write more articles about these plug-ins in the future.

Hiberclipse
The hiberclipse plug-in seems to be a very useful tool. It seems to be applicable to database-driven workflows. In this workflow, there is a database mode, and you want to build a hibernate ing file and Java class to use this mode. This is a very common scenario. If you find yourself facing such a problem, I strongly recommend you use this plug-in. It provides a very cool feature: In eclipse, it provides a graphical "relationship View" for the databases used ". (I should point out that if you want to start with an existing database mode, Hibernate synchronizer will also be helpful. Its new Mapping File wizard can connect to your database and build a ing File Based on the detected content .)


Figure 28. hibernate synchronizer ing wizard

Hibernator
Last, hibernator seems to be in another direction, that is, to generate a simple hibernate ing document from the Java code, and then let you build (or update) The database mode from the ing document. It also provides the ability to run database queries in eclipse. Among the three plug-ins, the development phase seems to be the earliest, but it is worth noting, especially because its developers are members of The Hibernate development team.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.