• 35648

    文章

  • 23

    评论

  • 20

    友链

  • 最近新加了很多技术文章,大家多来逛逛吧~~~~
  • 喜欢这个网站的朋友可以加一下QQ群,我们一起交流技术。

【开课吧javaEE每日一学190803】mybatis开发DAO层与SqlMapConfig.xml配置文件 原

欢迎来到阿八个人博客网站。本 阿八个人博客 网站提供最新的站长新闻,各种互联网资讯。 喜欢本站的朋友可以收藏本站,或者加QQ:我们大家一起来交流技术! URL链接:https://www.abboke.com/jsh/2019/0805/103566.html

撸了今年阿里、头条和美团的面试,我有一个重要发现.......>>>

原始开发方式

实现流程

  • 编写SqlMapConfig.xml配置文件和mapper.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">
    	<configuration>
    		<!--加载配置文件-->
    		<properties resource="db.properties"></properties>
    		<environments default="development">
    			<environment id="development">
    				<transactionManager type="JDBC"/>
    				<dataSource type="POOLED">
    					<property name="driver" value="${db.driver}"/>
    					<property name="url" value="${db.url}"/>
    					<property name="username" value="${db.username}"/>
    					<property name="password" value="${db.password}"/>
    				</dataSource>
    			</environment>
    		</environments>
    		<mappers>
    			<mapper resource="UserMapper.xml"/>
    		</mappers>
    	</configuration>
    
    数据库配置文件
    	db.driver=com.mysql.jdbc.Driver
    	db.url=jdbc:mysql://localhost:3306/ssm
    	db.username=root
    	db.password=admin
    
    UserMapper.xml
    	<?xml version="1.0" encoding="UTF-8" ?>
    	<!DOCTYPE mapper
    			PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN "
    			"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    	<!--namespace作用是为了分类管理映射文件中的MapperdStatement对象-->
    	<mapper namespace="test">
    		<select id="findUserById" parameterType="int" resultType="test.User">
    		select * from User where id = #{hello}
    	  </select>
    
    		<!--${value}表示输入参数将${value}替换,直接做字符串的拼接,如果是取简单数量类型的参数,括号中的参数名必须是value-->
    		<select id="findUserByUsername" parameterType="java.lang.String" resultType="test.User">
    		  select * from user where username like '%${value}%'
    		</select>
    
    		<insert id="insertUser" parameterType="test.User">
    			<selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer">
    				select LAST_INSERT_ID()
    			</selectKey>
    			insert into user(username, birthday, sex, address)
    			values (#{username}, #{birthday}, #{sex}, #{address})
    		</insert>
    	</mapper>
    
    上面使用like的时候用的是$而不是#,至于$和#的区别看$和#的区别
  • 开发接口(DAO层接口)
    	package top.dao;
    
    	import test.User;
    
    	public interface UserDao {
    		User findUserById(int id) throws Exception;
    		void insertUser(User user) throws Exception;
    	}
    
  • 实现接口(DAO实现类,在实现类中通过sqlsesion与数据库打交道)
    	package top.dao.impl;
    
    	import org.apache.ibatis.session.SqlSession;
    	import org.apache.ibatis.session.SqlSessionFactory;
    	import test.User;
    	import top.dao.UserDao;
    
    	public class UserDaoImpl implements UserDao {
    
    		private SqlSessionFactory sqlSessionFactory;
    
    	//    注入sqlsessionFactory
    		public UserDaoImpl(SqlSessionFactory sqlSessionFactory) {
    			this.sqlSessionFactory = sqlSessionFactory;
    		}
    
    		@Override
    		public User findUserById(int id) throws Exception {
    			SqlSession sqlSession = sqlSessionFactory.openSession();
    			User user = sqlSession.selectOne("test.findUserById", id);
    			sqlSession.close();
    			return user;
    		}
    
    		@Override
    		public void insertUser(User user) throws Exception {
    			SqlSession sqlSession = sqlSessionFactory.openSession();
    			sqlSession.insert("test.insertUser", user);
    			sqlSession.commit();
    			sqlSession.close();
    		}
    	}
    
  • 测试类
    	@Test
    		public void testFindById() throws Exception {
    			UserDao userDao = new UserDaoImpl(sqlSessionFactory);
    			User user = userDao.findUserById(1);
    			System.out.println(user);
    		}
    

几个对象的生命周期

  • sqlSession: 方法级别

    所谓的方法级别就是需要在方法里面创建的对象

  • sqlSessionFactory: 全局范围,是应用级别

  • sqlSessionFactoryBuilder: 方法级别

mapper代理开发方式(xml配置文件)

mapper代理开发方式就是使用接口开发方式,上面使用原始的dao进行开发的时候不仅仅建立了dao接口,还有dao的实现类,我们是在实现类里面去建立sqlsession对象来操作数据库的,现在所谓的mapper代理开发方式就是去掉dao的实现类,只需要保留接口即可,但是使用mapper代理方式开发是有前置条件的。具体条件如下:

  • mapper接口的类路径需要与mapper.xml文件中的namespace相同 这里需要注意的是类路径而不是包路径,如果是写的包路径就会出现下面的错误 org.apache.ibatis.binding.BindingException: Type interface top.mapper.UserMapper is not known to the MapperRegistry.
  • mapper接口的方法名称需要和mapper.xml中定义的每一个statement的id相同
  • mapper接口的方法输入参数类型需要和mapper.xml中定义的每一个sql的parameterType的类型相同
  • mapper接口的方法的输出参数类型和mapper.xml中定义的每一个sql的resultType的类型相同 依然是上面的案例进行修改:

mapper文件

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN "
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--namespace作用是为了分类管理映射文件中的MapperdStatement对象-->
<mapper namespace="top.mapper.UserMapper">
    <select id="findUserById" parameterType="int" resultType="test.User">
    select * from User where id = #{hello}
  </select>

    <!--${value}表示输入参数将${value}替换,直接做字符串的拼接,如果是取简单数量类型的参数,括号中的参数名必须是value-->
    <select id="findUserByUsername" parameterType="java.lang.String" resultType="test.User">
      select * from user where username like '%${value}%'
    </select>

    <insert id="insertUser" parameterType="test.User">
        <selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer">
            select LAST_INSERT_ID()
        </selectKey>
        insert into user(username, birthday, sex, address)
        values (#{username}, #{birthday}, #{sex}, #{address})
    </insert>
</mapper>

这里可以看到mapper文件中namespace已经改了,是mapper接口的类路径。

mapper接口

package top.mapper;

import test.User;

public interface UserMapper {
    User findUserById(int id) throws Exception;
    void insertUser(User user) throws Exception;
}

测试代码

package test;


import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Before;
import org.junit.Test;
import top.mapper.UserMapper;
import top.mapper.impl.UserMapperImpl;

import java.io.IOException;
import java.io.InputStream;
import java.util.Date;
import java.util.List;

public class TestUser {

    // 会话工厂
    private SqlSessionFactory sqlSessionFactory;

    // 该注解可以在@test注解之前执行
    @Before
    public void createSqlSessionFactory() throws IOException {
        // 加载配置文件
        String resource = "SqlMapConfig.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        // 使用sqlSessionFactoryBuilder从xml中创建sqlsessionfactory
        sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
    }
    @Test
    public void testMapperFind() throws Exception {
        SqlSession sqlSession = sqlSessionFactory.openSession();
//        获取mapper接口的代理对象
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        // 调用代理对象方法
        User user = userMapper.findUserById(1);
        System.out.println(user);
        sqlSession.close();
    }
}

SqlMapperConfig.xml配置文件常用的标签

mybatis的主配置文件可以配置如下所示的标签:

  • properties(属性,可以将外部的属性文件加载进来。比如数据库的配置文件)
    • <!--加载配置文件--> <properties resource="db.properties"></properties>

    • 除了使用resource属性之外还可以使用properties标签中定义property子标签来定义数据可属性值

      	<properties>
      	<property name="driver" value="com.mysql.jdbc.Driver"/>
      	</properties>
      
    • mybatis是先读取properties元素体内的属性,然后再去读取url或者resource加载的属性,此时会覆盖已读取的同名的属性。

  • settings(全局配置参数)
  • typeAlias标签,定义别名的
    • 批量或者单个定义别名
      	<typeAliases>
      <!--定个定义别名-->
      <!--<typeAlias type="test.User" alias="user"/>-->
      <!--批量定义别名.扫描整个包下面的类,别名为类名(首字母大小或小写都可以)-->
      <package name="test"/>
      	</typeAliases>
      
  • mappers标签
    • <mapper resource=" " />(单个)
      • 使用相对于类路径的资源
      • 案例: <mapper resource="sqlmap/User.xml" />
    • <mapper class=" " />(单个)
      • 使用的是接口类路径
      • 案例: <mapper class="com.kkb.mybatis.mapper.UserMapper"/>
      • 此时需要注意的是要求mapper接口名称和mapper映射文件名称相同,并且应该放在同一个目录中
    • <package name=""/>(批量)
      • 注册指定包下的所有mapper接口,来加载映射文件
      • 案例:<package name="com.kkb.mybatis.mapper"/>
      • 使用批量的方式要求mapper接口名称和mapper映射文件的名称相同,并且放在同一个目录中

相关文章

暂住......别动,不想说点什么吗?
  • 全部评论(0
    还没有评论,快来抢沙发吧!