Mainstream Framework Learning - mybatis (java review day21)

Keywords: xml Mybatis JDBC SQL

I. mybatis Foundation

1. Analysis of Starter Case Design Mode

 	public static void main(String[] args) throws Exception{
		//Read Configuration File
		InputStream in = Resources.getResourceAsStream("SqlMapConfig.xml");
		
		//Create SqlSessionFactory Factory
		/*
			Creating factory mybatis uses builder mode
			Use SqlSessionFactoryBuilder to build a factory 
			Advantage: Hide the creation details of the object so that the user can get it by calling the method directly
		*/
		SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
		//Deliver the required resource in to the builder builder to build the factory
		SqlSessionFactory factory = builder.build(in);
		
		//Use factory to produce SqlSession object
		/*
			Production SqlSession uses factory mode
			Advantage: decoupling
			
		*/
		SqlSession session = factory.openSession();
		//Use SqlSession to create proxy object for Dao layer interface
		
		IUserDao userDao = session.getMapper(IUserDao.class);
		
		//Executing methods using proxy objects
		/*
			Creating a Dao interface implementation class uses proxy mode
			Advantage: Enhance existing methods without modifying source code
		*/
		List<User> users = userDao.findAll();
		for(User user : users){
			System.out.println(user);
		}
		
		//Release Resources
		session.close();
		in.close();
	}

2. Note Development

	/*
		Comments define the Sql statement for findAll()
	*/
	public interface IuserDao{
		@Select("select * from user")
		List<User> findAll();
	}

	/*
		SqlMapConfig.xml Configure Class Properties for Annotations
	*/
	<mappers>
		<mapper class = "com.learn.dao.IUserDao"/>
	</mappers>
	

3. Set up Mybatis environment
a. Steps
1, Import dependencies in a pom file

	<dependencies>
		<dependencie>
		<dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.4.5</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.6</version>
        </dependency>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.12</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.10</version>
        </dependency>
	</dependencies>

2, Configuration SqlMapConfig.xml, CreateJdbcConfig.propertiesResources

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/text?useUnicode=true&amp;characterEncoding=utf-8
jdbc.username=root
jdbc.password=123456

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <!-- Introducing external profiles-->
    <properties resource="jdbcConfig.properties"></properties>
    <!--Configure Alias-->
    <typeAliases>
        <package name="com.learn.domain"></package>
    </typeAliases>
    <!-- Configuration environment-->
    <environments default="mysql">
        <environment id="mysql">
            <transactionManager type="JDBC"></transactionManager>
            <dataSource type="POOLED">
                <property name="driver" value="${jdbc.driver}"></property>
                <property name="url" value="${jdbc.url}"></property>
                <property name="username" value="${jdbc.username}"></property>
                <property name="password" value="${jdbc.password}"></property>
            </dataSource>
        </environment>
    </environments>
    <!-- Specify annotated dao Location of interface -->
    <mappers>
    	//Package used to specify where the dao interface is located, and when specified, mapper and resource or class are not required
        <package name="com.learn.dao"></package>
    </mappers>
</configuration>

4,CRUD
a, dao layer

	public interface IUserdao{
		
		//Search
		List<User> findAll();
	
		//Preservation
		void saveUser(User user);

		//To update
		void updateUser(User user);
		
		//delete
		void deleteUser(Integer userId);
		
	}

b, sql statement configuration (IUserDao.xml)

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<mapper namespace= "com.learn.dao.IUserDao">
	
	<select id = "findAll" resuleType="user">
		select * from user;
	</select>
	
	<update id = "updateUser" resuleType="user">
		update user set username=#{username},address=#{address},sex=#{sex} where id=#{id} ;
	</update>
	
	<delete id ="deleteUser" resuleType="java.lang.Integer">
		delete from user where id = #{id};
	</delete>
</mapper>

c. Testing

	public static void main(String[] args){

		private InputStream in;
		private SqlSession sqlSession;
		private IUserDao userDao;

		@Before
		public void init() throws Exception{
			//Read Configuration File
			in = Resources.getResourceAsStream("SqlMapConfig.xml");
			//Get SqlSession object
			SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
			SqlSessionFactory factory = builder.build(in);
			//Get SqlSession object parameter true to turn on autocommit
			sqlSession = factory.openSession(true); 
			//Use SqlSession to create proxy object for Dao layer interface
			IUserDao userDao = sqlSession.getMapper(IUserDao.class);
		}
		
		@After
		public void destroy() throws Exception{
			//Release Resources
			sqlSession.close();
			in.close();
		}

	
		
		@Test
		public void testFindAll(){
			List<User> users = userDao.findAll();
			for(User user : users){
				System.out.println(user);
			}
		}
		
		@Test
		public void testSaveUser(){
			User user = new User();
			user.setUsername("zhangsan");
			user.setAddress("Beijing China");
			user.setSex("male");
			userDao.saveUser(user);
		}

		@Test
		public void testUpdateUser(){
			User user = new User();
			user.setId(1); //Original zhansan
			user.setUsername("lisi");
			user.setAddress("Shanghai China");
			user.setSex("female");
			userDao.updateUser(user);
		}

		@Test
		public void testDeleteUser(){
			userDao.deleteUser(1); //lisi
		}
	}	

4. Label details
a. Properrties tags: Configuration SqlMapConfig.xml Location of resources in

b, typeAliases tag: only aliases of classes in the domain can be configured, less package names and class names
1, Package tag: A package used to configure aliases. When specified, entity classes under the package register aliases, and class names are aliases and are no longer case sensitive

5. Connection pools and transactions
A. can reduce the time it takes us to get a connection

b, mybatis connection pool provides three configurations (in SqlMapConfig.xml DataSource, type property is the selected method)
1. POOLED uses traditionalJavax.sql.DataSourceConnection pool in specification, implementation in mybatis for specification

1. Get connections from the pool and return them when used up

2. UNPOOLED has no idea of using pools and uses traditional connections

1. Create new connections each time

3. JNDI uses server-provided JNDI technology to obtain DataSource objects. Different servers can get different connection pools (web or maven war)

2. mybaits Advanced

1. Dynamic SQL
a, if tags

	<select id = "findUserByCondition" resuleType="user">
		select * from user where 1=1
		<if test="username != null">
			username = #{username}
		</if>
		<if test="usersex !=null">
			usersex = #{usersex}
		</if>
	</select>

b. where label

	<select id = "findUserByCondition" resuleType="user">
		select * from user
		 <where>
			<if test="username != null">
				username = #{username}
			</if>
			<if test="usersex !=null">
				usersex = #{usersex}
			</if>
		</where>
	</select>

c, foreach tags (traversal)

d, sql Tags

	<sql id = "defaultUser">
		select * from user
	</sql>

	<select id = "findUserByCondition" resuleType="user">
		<include refid="defaultUser"></include> 
		where 1=1
		<if test="username != null">
			username = #{username}
		</if>
		<if test="usersex !=null">
			usersex = #{usersex}
		</if>
	</select>

2. One-to-many, many-to-many queries
1. One-to-many

	/*
		One-to-many relationship mapping
		Suppose you have two tables, User, Account
		A collection reference from a table entity should be included in the primary table entity
	*/
	//User entity class table defines the account list and generates get, set methods:
	private List<Account> accounts;
	
	/*
		stay IUserDao.xml Configure Mapping in File
	*/
	//resultMap Defining User
	<resultMap id ="userAccountMap" type="user">
		<id property="id" column="id"></id>
		<result property="username" column="username"></result>
		<result property="address" column="adderss"></result>
		<result property="sex" column="sex"></result>
		//Configure mapping of accounts collection in user object
		<collection property="accounts" ofType="account">
			<id column="aid" property="id"></id>
			<result column="uid" property="uid"></result>
			<result column="money" property="money"></result>
	</resultMap>

	<select id = "findAll" resuleMap="userAccountMap">
		select * from user u left outer join account a on u.id=a.uid 
	</select>

2. Many-to-many

	/*
		Many-to-many relationship mapping
		Suppose you have three tables User, Role, and intermediate table user_role
		A collection reference from a table entity should be included in the primary table entity
	*/
	//The Role entity class table defines the User list and generates get, set methods:
	private List<User> users;
	
	/*
		stay Dao.xml Configure Mapping in File
	*/
	//ResultMap defining role table
	<resultMap id="roleMap" type="role">
        <id property="roleId" column="rid"></id>
        <result property="roleName" column="role_name"></result>
        <result property="roleDesc" column="role_desc"></result>
        <collection property="users" ofType="user">
            <id column="id" property="id"></id>
            <result column="username" property="username"></result>
            <result column="address" property="address"></result>
            <result column="sex" property="sex"></result>
        </collection>
    </resultMap>

    <select id="findAll" resultMap="userMap">
        select u.*,r.id as rid,r.role_name,r.role_desc from user u
         left outer join user_role ur  on u.id = ur.uid
         left outer join role r on r.id = ur.rid
    </select>

3. Caching
1. Concepts
a. Temporary data that exists in memory
b. Can be used to reduce the number of interactions with the database and improve execution efficiency
c. Frequently queried and not frequently changed data correctness has little impact on the final result

2. Level 1 Cache
a. Caching of SqlSession objects in Mybatis
b. After the query is executed, the results of the query are simultaneously stored in an area provided by SqlSession (the area is Map)
c. When querying the same data, mybatis will query SqlSession first, and if so, use
d. When the SqlSession object disappears, the cache disappears

	/*
		Related code: Once delayed loading is turned on, it is implemented and cached
	*/
	//This method can be emptied
	sqlSession.clearCache();

3. Secondary Cache
a. Cache of SqlSessionFactory objects, SqlSessionFactory created by the same SqlSessionFactory object shares its cache (secondary cache holds too much data, not objects, objects that use data many times are different)

b. Steps for use
1, in SqlMapConfig.xml Configuration framework in supports secondary caching
2, in IUserDao.xml Configure current mapping file to support secondary caching in
3. Configure the current operation in the select tag to support secondary caching

	//stay SqlMapConfig.xml Configuration framework in supports secondary caching
	<settings>
		<setting name="cacheEnabled" value="true"/>
	</setting>

	//stay IUserDao.xml Configure current mapping file to support secondary caching in
	<cache/>
	
	//Configure the current operation in the select tag to support secondary caching
	<select id = "findAll" resuleType="user" useCache="true">
		select * from user;
	</select>

4. Delayed Loading
a, lazyLoadingEnabled: Global switch for delayed loading, when turned on, all associated objects will be delayed loading

	//configuration parameter
	<settings>
		//Turn on Mybatis to support delayed loading
		<setting name="lazyLoadingEnabled" value="true"/>
	</settings>

b, aggressiveLazyLoading: When turned on, the call to any method loads all the properties of the object; otherwise, each property loads on demand (no action is required by default)

3. Note Development

1. Steps

	/*
		Define the Dao interface
	*/
	public interface IUserDao {
		//Add comments and Sql statements directly to the defined method
	    @Select("select * from User")
	    List<User> findAll();
	}
	
	
	//Definition SqlMapConfig.xml File, specifying where the annotated dao interface is located
    <mappers>
        <mapper class="com.learn.dao.IUserDao"></mapper>
    </mappers>

2. One-to-one, many-to-one annotations

	//Add Note Configuration
	//One-to-one@one, fetchType =FetchType.EAGER(Load now)
	//Define an Account entity class
	@Select("select * from Account")
	@Results(id = "accountMap", value = {
	        @Result(id = true,column = "id",property = "id"),
	        @Result(column = "uid",property = "uid"),
	        @Result(column = "money",property = "money"),
	        @Result(column = "uid",property = "user",
	        one = @One(select ="com.learn.dao.IUserDao.findAll",fetchType = FetchType.EAGER))
	})
	List<Account> findAll();

	//Many-to-many, fetchType =FetchType.LAZY(Delayed Loading)
	//Define the Account collection in the User entity class to generate get, set methods
	private List<Account> accounts;
	
	
	@Select("select * from User")
	@Results(id = "userMap", value = {
	        @Result(id = true,column = "id",property = "userId"),
	        @Result(column = "username",property = "userName"),
	        @Result(column = "address",property = "userAddress"),
	        @Result(column = "sex",property = "userSex"),
	       	@Resule(property = "accounts", column = "id",
	       	many = @Many(select ="com.learn.dao.IUserDao.findAll",fetchType = FetchType.LAZY)) 
	})
	List<User> findAll();

3. Configure xml secondary cache file

	/*
		stay SqlMapConfig.xml Configure settings in file
	*/
	<settings>
	    <setting name="cacheEnabled" value="true"/>
	</settings>

	
	//Add comments to the corresponding Dao
	@CacheNamespace(blocking = true)

Posted by son.of.the.morning on Sat, 20 Jun 2020 19:15:42 -0700