preface

When explaining the Web development pattern, I have written the XML version of the user login registration case! Now on the original project, using the database version to complete the user login registration! If you do not know the friends, you can see my Web development mode blog!

How much do I need to change my code from using XML files as a small database to using Mysql? We’ll see!

Use the C3P0 database connection pool

Import the C3P0 development package and configuration file

The development package imports this: c3P0-0.9.2-pre1 and McHange-commons-0.2.jar.

C3P0 not only performs well, but the configuration files can be configured using XML documents!

Similar configuration files can be found in the official documentation!

Let’s change it:



<?xml version="1.0" encoding="UTF-8"? >
<c3p0-config>
	<default-config>
		<property name="driverClass">com.mysql.jdbc.Driver</property>
		<property name="jdbcUrl">jdbc:mysql://localhost:3306/zhongfucheng</property>
		<property name="user">root</property>
		<property name="password">root</property>
	
		<property name="acquireIncrement">5</property>
		<property name="initialPoolSize">10</property>
		<property name="minPoolSize">5</property>
		<property name="maxPoolSize">20</property>
	</default-config>
	
	<named-config name="mysql">
		<property name="driverClass">com.mysql.jdbc.Driver</property>
		<property name="jdbcUrl">jdbc:mysql://localhost:3306/zhongfucheng</property>
		<property name="user">root</property>
		<property name="password">root</property>
	
		<property name="acquireIncrement">5</property>
		<property name="initialPoolSize">10</property>
		<property name="minPoolSize">5</property>
		<property name="maxPoolSize">20</property>
	</named-config>
	
	
	<named-config name="oracle">
		<property name="driverClass">oracle.jdbc.driver.OracleDriver</property>
		<property name="jdbcUrl">JDBC: Oracle :thin:@//localhost:1521</property>
		<property name="user">The user name</property>
		<property name="password">password</property>
	
		<property name="acquireIncrement">5</property>
		<property name="initialPoolSize">10</property>
		<property name="minPoolSize">5</property>
		<property name="maxPoolSize">20</property>
	</named-config>
</c3p0-config>

Copy the code

Write the utility class that gets the connection



	public class DBUtils {
	
	    private static ComboPooledDataSource comboPooledDataSource = null;
	
	    static {
	
	        // It will automatically find the configuration file, the node is mysql database (if not specified, use the default!)
	        comboPooledDataSource = new ComboPooledDataSource("mysql");
	    }
	

	    public static DataSource getDataSource(a) {
	        return comboPooledDataSource ;
	    }

		
	    public static Connection getConnection(a) {
	        try {
	            return comboPooledDataSource.getConnection();
	        } catch (SQLException e) {
	            e.printStackTrace();
	            throw new RuntimeException("Database initialization failed!"); }}}Copy the code

Designing database tables

Very simple, according to the entity table to design!



	CREATE TABLE user (
	  id       VARCHAR(20) PRIMARY KEY,
	  username VARCHAR(20) UNIQUE NOT NULL.password VARCHAR(20)        NOT NULL,
	  email    VARCHAR(20),
	  birthday DATE
	
	);



Copy the code

Write a Dao implementation that operates on a database



	public class UserImplDataBase implements UserDao {
	
	
	    @Override
	    public User find(String username, String password) {
	        
	        return null;
	    }
	
	    @Override
	    public void register(User user) {}}Copy the code

Let’s go straight to the DBUtils framework

  • Import the DBUtils development package

  • The specific code is as follows

    @Override
    public User find(String username, String password) {

        QueryRunner queryRunner = new QueryRunner(Utils2DB.getDataSource());

        String sql = "SELECT * FROM user WHERE username=? AND password=?";

        try {
            User user = (User) queryRunner.query(sql, new BeanHandler(User.class), new Object[]{username, password});

            return user == null ? null : user;
        } catch (SQLException e) {
            e.printStackTrace();
            throw new RuntimeException("Landing failed!"); }}@Override
    public void register(User user) {

        QueryRunner queryRunner = new QueryRunner(Utils2DB.getDataSource());

        String sql = "INSERT INTO user (id, username, password, email,birthday) VALUES (? ,? ,? ,? ,?) ;";

        String id = user.getId();
        String username = user.getUsername();
        String password = user.getPassword();
        String email = user.getEmail();

        Date date = user.getBirthday();


        try {
            queryRunner.update(sql, new Object[]{id, username, password, email,date});

        } catch (SQLException e) {
            e.printStackTrace();
            throw new RuntimeException("Registration failed."); }}}Copy the code

Develop DaoFactory

Our Dao implementation is already available in XML and JDBC versions. When BusinessService calls the Dao layer method, it still needs to new the specific Dao implementation, which is the following code:

		
	UserDao userDao = new UserImplXML();

	/ / or
	UserDao userDao= new UserImplDataBase();

Copy the code

It’s a bit inflexible, and therefore a bit unprofessional! Why do you need DaoFactory?

Why do YOU need DaoFactory?

Refer to blog post: blog.sina.com.cn/s/blog_4ca3…

Highlights:

Advantages:

  • Transparency: Business objects can use data sources without knowing exactly how they are implemented. Accessing the data source is transparent because implementation details are hidden into the DAO.
  • Migration simplification: The advent of the DAO layer makes it easier for applications to migrate to different database implementations. Business objects can be ignorant of the underlying data implementation. Thus, the migration only involves changes to the DAO layer. In addition, using a factory policy makes it possible to provide a specific factory implementation for each of the underlying data implementations. In this case, migrating to a different data implementation is essentially providing a new factory implementation for the application.
  • Reduced programming difficulty in business objects: Because daOs manage all the details of data access, it greatly simplifies code in business objects and other data clients that use DAOs. All implementation-specific code such as (SQL statements) is contained in daOs rather than business objects. This makes the code more robust and greatly improves development efficiency.
  • Centralize all data access into a single layer: Because all data access operations are now proxied by daOs, this single data access layer can be thought of as a layer that isolates the data access implementation from the rest of the application. This centralization makes the application easier to maintain and manage.

Disadvantages:

  • Additional layers: Because the DAO creates an additional layer of objects beyond the data client and data source, it needs to be designed and implemented to balance the advantages and disadvantages of this design pattern. However, generally speaking, the advantages of adopting this design pattern outweigh the disadvantages.
  • ** Class inheritance relationships need to be designed: ** When using the factory strategy, the inheritance relationships of concrete factory classes and the products generated by these factory classes need to be designed and implemented. We need to consider carefully whether this extra work will actually result in greater flexibility. Using this strategy can make the design more complex, however, you can start with the factory method pattern to implement this strategy, and then move to abstract factories if necessary

Design DaoFactory

First, we’ll design DaoFactory as a singleton.


	public class DaoFactory {
	
	    private DaoFactory(a) {}private static final DaoFactory DAO_FACTORY = new DaoFactory();
	    
	    // Expose the public method to get the factory object
	    public static DaoFactory newInstance(a) {
	        returnDAO_FACTORY; }}Copy the code

Currently we are operating on User, so the factory makes the UserDao object, and whether the UserDao object is the JDBC version or the XML version is determined by the configuration file (which gives us more flexibility)!

  • Add the configuration file to the SRC directory
  • Note: do not add the “” string symbol !!!!! I have been here for a long time !!!!
# class is needed is a complete object name (including package) # userClass = zhongfucheng. Dao. Impl. UserImplDataBase userClass = zhongfucheng. Dao. Impl. UserImplXMLCopy the code
  • Read the configuration file, create the corresponding UserDao object, and do it directly in the constructor.

    private static UserDao userDao = null;

    private DaoFactory(a) {


        try {

            // Read configuration file information
            InputStream inputStream = DaoFactory.class.getClassLoader().getResourceAsStream("UserDao.properties");
            Properties properties = new Properties();
            properties.load(inputStream);
            String userClass = properties.getProperty("userClass");

            // Use reflection to create the corresponding object
            userDao = (UserDao) Class.forName(userClass).newInstance();

        } catch (IOException e) {
            e.printStackTrace();
            throw new RuntimeException("File reading failed!");
        } catch (IllegalAccessException e) {
            e.printStackTrace();
            throw new RuntimeException("Reflex failed!");
        } catch (InstantiationException e) {
            e.printStackTrace();
            throw new RuntimeException("Reflex failed!");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
            throw new RuntimeException("Reflex failed!"); }}public static UserDao createUserDao(a) {
        return userDao;
    }

Copy the code

Get the UserDao object using DaoFactory in the BusinessService layer


	UserDao userDao = DaoFactory.newInstance().createUserDao();

Copy the code

test

** If the mysql driver version is too low, the following exception occurs! ** We just need to download the new mysql JAR package and import the project!

	java.sql.SQLException: Feature not implemented Query:insert into guestbook (id,name,email,url,title,content,time) value(? ,? ,? ,? ,? ,? ,?) Parameters: [1, qwq,wqwq,qwqw,qw,qw, 2010-09-13]

Copy the code

The successful effects of the JDBC version are as follows:


The successful effects of the XML version are as follows:


conclusion

  1. Since our Service layer may have multiple implementations [JDBC, XML], the coupling would be a bit high if we simply used new concrete services
  2. So we have factories, and the purpose of factories is to decouple, and we create concrete objects through configuration files.

If the article has the wrong place welcome to correct, everybody exchanges with each other. Students who are used to reading technical articles on wechat can follow the wechat public account :Java3y