mybatis


mybatis

我们要知道mybatis是用来处理程序连接数据库以及对数据库进行操作的组件。
消除了几乎所有jdbc代码和参数的手工设置以及结果集的检索。
思考下如何连接使用数据库呢,

以查询数据为例
	1.首先加载驱动
	private static final String DRIVER = "com.mysql.cj.jdbc.Driver";
	private static final String URL = "jdbc:mysql://localhost:3306/hrm?useSSL=false&&characterEncoding=utf-8";
	private static final String USERNAME = "root";
	private static final String PASSWORD = "123";

	private static DruidDataSource ds = null;

	// 加载驱动(加载一次就够了)
	static {
		ds = new DruidDataSource();
		ds.setDriverClassName(DRIVER);
		ds.setUrl(URL);
		ds.setUsername(USERNAME);
		ds.setPassword(PASSWORD);

		ds.setMaxActive(100);// 最多能够开多少个连接
		ds.setMinIdle(2);// 最少允许多少个连接处于闲置
		ds.setInitialSize(2);// 初始创建多少个连接
		ds.setMaxWait(10000);// 最长的等待时间
	}
	2.然后获取连接
	 Connection conn = DriverManager.getConnection();
	3.开始查询
	 String sql ="select * from xxx where id=? and name=?";
	 PreparedStatement pstm= conn.prepareStatement(sql);
	 //防止sql注入 使用填充?的形式
	 for (int i = 1; i <= 2; i++) {
				if (args[i - 1].getClass().getName().equals("java.util.Date"))
					// 如果别人偷懒,直接传日期进来,默认按Timestamp来处理
					pstm.setTimestamp(i, new java.sql.Timestamp(((java.util.Date) args[i - 1]).getTime()));
				else
					pstm.setObject(i, args[i - 1]);
			}
	List<Dept> list = new ArrayList<>();		
	ResultSet rs =pstm.executeQuery();
	while (rs.next()) {
				Dept d=new Dept();
				d.setId(rs.getInt(1));
				d.setName(rs.getString(2));
				d.setRemark(rs.getString(3));
				list.add(d);
			}
	4.关闭通道
	Exception ex1 = null, ex2 = null, ex3 = null;
		if (conn != null) {
			try {
				if (!conn.isClosed())
					conn.close();// 在使用连接池的情形先,这个关闭是假的
			} catch (Exception e) {
				ex3 = null;
				throw new RuntimeException("conn关闭异常", e);
			}
		}
		if (pst != null) {
			try {
				pst.close();
			} catch (Exception e) {
				ex2 = e;
				throw new RuntimeException("pst关闭异常", e);
			}
		}
		if (rst != null) {
			try {
				rst.close();
			} catch (Exception e) {
				ex1 = e;
				throw new RuntimeException("rst关闭异常", e);
			}
		}
		if (ex1 != null || ex2 != null || ex3 != null) {
			throw new RuntimeException("数据库关闭环节失败" + (ex1 != null ? ex1.getMessage() : "")
					+ (ex2 != null ? ex2.getMessage() : "") + (ex3 != null ? ex3.getMessage() : ""));

		}

这种操作具有很大的不便性,

  1. 数据库的频繁连接
  2. 查询时result对对象的获取
  3. PreparedStatement时sql语句的填充硬编码

主要使用了sqlSession来解决事务处理(statement),使用mapper.xml来解决dao对象和sql对象关系以及,增删改查时对象的注入以及获取的数据处理。最后知道mybatis是总处理文件其中有< environments >可以用来解决数据库连接问题。

一、mybatis?

	<?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>
    <!-- 全局参数设置 -->
    <settings>
   	 	<!-- 开启全局的懒(延迟)加载   !!!延迟加载最好不要与缓存共存 -->
		<setting name="lazyLoadingEnabled" value="true" />
		<!-- 关闭立即加载,其实不用配置,默认为false -->
		<setting name="aggressiveLazyLoading" value="false" />
		<!-- 打开二级缓存  需要基础类继承Serializable达成可序列化 和 mapper中建立标签cache  -->
    	<setting name="cacheEnabled" value="true"/>
	    <setting name="logImpl" value="LOG4J"/>
	</settings>
	
	<!-- 类处理器   加载数据库所要要类属性信息 -->
	<typeAliases>
	   <package name="com.study.it.entity"/>
	</typeAliases>
	
	<!--插件 -->
	<!-- 配置数据库切面拦截器 ,用来做分页语句 -->
	<plugins>
        <plugin interceptor="com.github.pagehelper.PageInterceptor">
        <!-- 设置数据库类型 Oracle,Mysql,MariaDB,SQLite,Hsqldb,PostgreSQL六种数据库-->
            <property name="helperDialect" value="mysql"/>
        </plugin>
	</plugins>
	
	<!-- 环境信息 -->
	<environments default="development">
		<environment id="development">
			<!-- 配置JDBC事务控制,由mybatis进行管理 -->
			<transactionManager type="JDBC" />
			<!-- 配置数据源,采用dbcp连接池 -->
			<dataSource type="POOLED">
				<property name="driver" value="com.mysql.cj.jdbc.Driver" />
				<property name="url" value="jdbc:mysql://localhost:3306/shop?characterEncoding=utf8&amp;useSSL=false&amp;serverTimezone=Asia/Shanghai&amp;allowPublicKeyRetrieval=true" />
				<property name="username" value="root" />
				<property name="password" value="123456" />
			</dataSource>
		</environment>
	</environments>
	
	<!-- 映射器 -->
	<mappers>
		<mapper resource="mapper/TypeDaoMapper.xml" />
		<mapper resource="mapper/EmpDaoMapper.xml" />
		<mapper resource="mapper/GoodDaoMapper.xml" />
	</mappers>
</configuration>

二、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">
<mapper namespace="com.study.it.dao.GoodDao">
	<!-- 设置缓存刷新的时间 -->
	<cache flushInterval="60000" />
	
   <resultMap type="com.study.it.entity.Good" id="basemap">
     <id column="sql名称" property="实例类名称"/>
     <result column="sql名称" property="实例类名称"/>
     <result column="sql名称" property="实例类名称" javaType="java.sql.Date"/>
     
     <association property="实例类名称" javaType="com.study.it.entity.实例类">
        <id column="sql名称" property="实例类名称"/>
        <result column="sql名称" property="实例类名称"/>
        <!-- 设置懒加载查询 -->
        <association property="实例类名称rec" javaType="com.study.it.entity.实例类" select="com.study.it.dao.RecDao.selectById(获取方法)" column="sql关联键名"/>
        
     </association>
   	 <!-- 获取外键集合,不知道什么时间用,所以用延迟加载来缓解内存 -->
   	 <collection property="entityName" ofType="com.study.it.entity.Type" select="com.study.it.xxxDao.selectListByUser" column="sql关联键名" />
   </resultMap>
   	<sql id="basesql">select * from xxx </sql>
	<insert id="insert" useGeneratedKeys="true" keyProperty="xxx">
   		insert into  XXX values()
   	</insert>
   	<delete id="delete">
   		delete from XXX where xx_id=#{id}
   	</delete>
   	<update id="update">
   		update XXX set xx=xx where xx_id =#{id}
   	</update>
	<select id="selectById" resultMap="basemap">
	</select>
	<select id="selectOne" resultMap="basemap">
	</select>
	<select id="selectAll" resultMap="basemap">
		<include id="basesql"/><!-- 导入前面的sql语句 -->
	</select>
	<select id="selectList" resultMap="basemap">
	</select>
	

</mapper>

三、sqlSession

public void add(Type t) {
		TypeDao.insertType(t);
		MyBatisUtil.getSession().commit();
		
	}
	
	
	InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
	SqlSessionFactory sqlSessionFactory= new SqlSessionFactoryBuilder().build(inputStream);
	
	ThreadLocal<SqlSession> th=new ThreadLocal<SqlSession>();//等效于是Map<线程编号,SqlSession>
	public static SqlSession getSession() {
		SqlSession session=th.get();
	
		if(session==null) {
			session =sqlSessionFactory.openSession();
			th.set(session);
		}
		return session;
	}
	public static void closeSession() {
		SqlSession session=th.get();
		if(session!=null) {
			session.close();
			th.remove();
		}
	}
  

同一个servlet可能会进行多次数据库操作,如:客户转账过程中,一个账号减钱,一个增钱、在这时若已经完成一步后出现错误,那么数据库操作不能够撤回就会导致严重的错误。这是sqlSession就提供了回滚的方法。而sqlSessionFactory也提供了多线程互不干涉的效果。

总结

我着这里还是非常浅显的理解的mybatis的过程。要深入的理解mybatis就需要去深入的了解java的反射机制。后续深入学习了反射机制后可能会过来再次加工文章。还有哪里写的不对的地方,各位大佬多多担待一些,顺便给我指出来、谢谢

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值