技术标签: java mybatis MyBatis mysql SSM
它对jdbc的操作数据库的过程进行封装,使开发者只需要关注 SQL 本身,而不需要花费精力去处理例如注册驱动、创建connection、创建statement、手动设置参数、结果集检索等jdbc繁杂的过程代码。
Mybatis通过xml或注解的方式将要执行的各种statement
(statement、preparedStatemnt、CallableStatement)配置起来,并通过java对象和statement中的sql进行映射生成最终执行的sql语句,最后由mybatis框架执行sql并将结果映射成java对象并返回。
1、 数据库连接创建、释放频繁造成系统资源浪费,从而影响系统性能。如果使用数据库连接池可解决此问题。
2、 Sql语句在代码中硬编码,造成代码不易维护,实际应用中sql变化的可能较大,sql变动需要改变java代码。
3、 使用preparedStatement向占有位符号传参数存在硬编码,因为sql语句的where条件不一定,可能多也可能少,修改sql还要修改代码,系统不易维护。
4、 对结果集解析存在硬编码(查询列名),sql变化导致解析代码变化,系统不易维护,如果能将数据库记录封装成pojo对象解析比较方便。
1) Resources: mybatis中的一个类, 负责读取主配置文件
InputStream in = Resources.getResourceAsStream("mybatis.xml");
2)SqlSessionFactoryBuilder : 创建SqlSessionFactory对象,
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
//创建SqlSessionFactory对象
SqlSessionFactory factory = builder.build(in);
3)SqlSessionFactory : 重量级对象, 程序创建一个对象耗时比较长,使用资源比较多。 在整个项目中,有一个就够用了。
SqlSessionFactory:接口 , 接口实现类: DefaultSqlSessionFactory
SqlSessionFactory作用: 获取SqlSession对象。SqlSession sqlSession = factory.openSession();
openSession()方法说明:
openSession()
:无参数的, 获取是非自动提交事务的SqlSession对象
openSession(boolean)
: openSession(true) 获取自动提交事务的SqlSession.
openSession(false) 非自动提交事务的SqlSession对象
4)SqlSession
SqlSession接口 :定义了操作数据的方法
例如 selectOne() ,selectList() ,insert(),update(), delete(), commit(), rollback()
SqlSession接口的实现类DefaultSqlSession。
使用要求: SqlSession对象不是线程安全的,需要在方法内部使用, 在执行sql语句之前,使用openSession()获取SqlSession对象。
在执行完sql语句后,需要关闭它,执行SqlSession.close(). 这样能保证他的使用是线程安全的。
5)由此引出工具类MyBatisUtils
public class MyBatisUtils {
private static SqlSessionFactory factory =null;
static {
String config="mybatis.xml";
try {
InputStream inputStream = Resources.getResourceAsStream(config);
//创建sqlSessionFactory对象,使用SqlSessionFactoryBuilder
factory = new SqlSessionFactoryBuilder().build(inputStream);
} catch (IOException e) {
e.printStackTrace();
}
}
//获取sqlSession方法
public static SqlSession getSqlSession(){
SqlSession sqlSession =null;
if (factory != null) {
sqlSession =factory.openSession();//非自动提交事务
}
return sqlSession;
}
}
<?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.aiit.dao.StudentDao">
<select id="selectStudents" resultType="com.aiit.domain.Student">
select * from student order by id;
</select>
<!--插入操作-->
<insert id="insertStudent" >
insert into student values (#{id},#{name},#{email},#{age})
</insert>
</mapper>
namespace:叫做命名空间,唯一值的,可以是自定义的字符串
要求使用dao接口的全限定名称
如<select>
,<update>
,<insert>
…
id:你要执行的sql语法的唯一标识,mybatis会使用这个id的值来找到要执行的sql语句
可以自定义,但是建议使用接口的方法名
resultType:表示结果类型的,是sql语句执行后得到Result,遍历这个Result得到的java对象的类型。值表示类的全限定名称
<?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">
<!--环境配置:数据库的连接信息
default:必须和某个environment的id值一样
告诉mybatis使用哪个数据库的连接信息。也就是访问哪个数据库
-->
<configuration>
<!--settings:控制mybatis全局行为-->
<settings>
<!--mybatis输出日志-->
<setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>
<!--environments:一个数据库信息的配置,环境
id:一个唯一值,自定义,表示环境的名称
-->
<environments default="development">
<environment id="development">
<!--
transactionManager:mybatis的事务类型
type:JDBC表示使用jdbc中的Connection中的commit和rollback事务处理
-->
<transactionManager type="JDBC"/>
<!--
dataSource,表示数据源,连接数据库的
type:表示数据源的类型,POOLED表示使用连接池
-->
<!--
也可以表示线上的数据库,是项目真是使用的库
-->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql:///mybatis"/>
<property name="username" value="root"/>
<property name="password" value="123"/>
</dataSource>
</environment>
</environments>
<!--
指定sqlmapper映射文件的位置
-->
<mappers>
<!--一个mapper标签指定一个文件的位置
从类路径开始的路径信息。target/classes信息
-->
<mapper resource="com/aiit/dao/StudentDao.xml"/>
</mappers>
</configuration>
<!--
mybatis的主配置文件:主要定义了数据库的配置信息,sql映射文件的位置
configuration
-->
<mappers>
中也可以使用<package>
如
<mappers>
<!--一个mapper标签指定一个文件的位置
从类路径开始的路径信息。target/classes信息
-->
<package name="com.aiit.dao"/>
</mappers>
此处省去实体类和主配置文件
第一步:写Dao层接口
public interface StudentDao {
List<Student> selectStudents();
}
第二步:书写mapper.xml文件
<mapper namespace="com.aiit.dao.StudentDao">
<select id="selectStudents" resultType="com.aiit.domain.Student">
select id,name,email,age from student order by id;
</select>
</mapper>
第三步:书写Dao层实现类
public class StudentDaoImpl implements StudentDao {
@Override
public List<Student> selectStudents() {
//获取sqlSession对象
SqlSession sqlSession = MyBatisUtils.getSqlSession();
String sqlID="com.aiit.dao.studentDao.selectStudents";
//执行sql语句,使用sqlSession类的方法
List<Student> students = sqlSession.selectList(sqlID);
sqlSession.close();
return students;
}
}
第四步:调用测试方法
public void testSelectStudents(){
StudentDao dao =new StudentDaoImpl();
List<Student> students = dao.selectStudents();
students.forEach(student -> System.out.println(student));
}
}
List<Student> students = dao.selectStudents();
1.dao对象,类型是StudentDao,全限定名称:com.aiit.dao.StudentDao
这个全限定名称和mapper.xml文件中的配置是一模一样的
2.方法名称,selectStudent,这个方法名称和mapper中的xml文件中查询标签的id值是一样的
3.通过dao中的返回值也可以确定Mybatis要调用的sqlSession的方法
如果返回值List,调用sqlSession,SelectList()方法
如果返回值是int,或是非List的,看mapper文件中的标签是<insert><update>就会调用
sqlSession的insert,update等方法
由于代码冗余,由此引出mybatis的动态代理:mybatis根据dao层的方法调用,获取执行sql语句的信息
mybatis根据你的dao接口,创建出一个dao接口实现类,并创建这个类的对象。来完成SqlSession调用方法,访问数据库。所以我们自己并不需要去书写一个dao层实现类/
动态代理: 使用SqlSession.getMapper(dao接口.class) 获取这个dao接口的对象。该方法底层是使用的JDK的动态代理,自动帮我们生成Imp的实现类。而并不需要我们进行手写的方式。
Dao层接口和配置文件与上述一样
public class TestMyBatis {
@Test
public void testSelectStudents(){
SqlSession sqlSession = MyBatisUtils.getSqlSession();
StudentDao dao = sqlSession.getMapper(StudentDao.class);
List<Student> students = dao.selectStudents();
students.forEach(student -> System.out.println(student));
}
}
(转载)http://bachmozart.iteye.com/blog/344172目前网上关于memcached的分析主要是内存管理部分,下面对memcached的线程模型做下简单分析 有不对的地方还请大家指正,对memcahced和libevent不熟悉的请先google之 先看下memcahced启动时线程处理的流程 memcached的多线程主要是通过实例化多个libevent实...
1. BERT微调2. 自然语言推理数据集3. BERT微调代码4. Q&A神经网络可以跨语言,跨领域。比如自然语言,视觉都在用Transformer。5. 目标检测竞赛总结参考https://www.bilibili.com/video/BV15L4y1v7ts/?spm_id_from=autoNext...
P3089 [USACO13NOV]POGO的牛Pogo-Cow题目描述In an ill-conceived attempt to enhance the mobility of his prize cow Bessie, Farmer John has attached a pogo stick to each of Bessie's legs. Bessie can now h...
题目链接bzoj2005: [Noi2010]能量采集题解做不动其他的毒瘤组合数学只能来写点水题了QAQQQQ对于挡住i,j的点数显然是gcd(i,j)那么就是求\(2 \times \sum_i^n \sum_j^m gcd(i,j) -n \times m\)枚举带约数\(p\)令\[ans=\sum_{p=1}^{n}p*\sum_{i=1}^{n}\sum_{j...
关于Python默认参数,假如默认参数是可变(mutable)对象是会有副作用的,一个函数参数的默认值,仅仅在该函数定义的时候,被赋值一次。如此,只有当函数第一次被定义的时候,才将参数的默认值初始化到它的默认值(如一个空的列表)如:&gt;&gt;&gt; def function(data=[]): data.append(1) return data&gt;&gt;&gt; funct...
1.<%=...%>与<%#... %>的区别: 答:<%=...%>是在程序执行时调用,<%#... %>是在DataBind()方法之后被调用2.控件接收哪些类型数据? 答:接收Bind的控件,一般有dropDownList,DataList,DataGrid,ListBox这些集合性质的控件,而被捆绑 ...
用C#实现HTTP协议下的多线程文件传输摘要:本文讲如何利用C#语言编写一个支持多线程下载文件的程序,你会看到利用C#语言编写网络应程序是多么的容易,从中也能体会到C#语言中强大的网络功能。 很多人都有过使用网络蚂蚁或网络快车软件下载互联网文件的经历,这些软件的使用可以大大加速互联网上文件的传输速度,减少文件传输的时间。这些软件为什么有如此大的魔力呢?其主要原因是这些软件...
JUnit单元测试之断言注意:hamcrest-2.1,hamcrest-core-1.3,hamcrest-library 这3个jar包也引入一下,不然有些断言方法找不到一、常用断言(Assert类的assert方法)1、assertArrayEquals([String message],expecteds, actuals)查看两个数组是否相等。2、assertEquals([String message],expected, actual)查看两个对象是否相等。类似于字符串比较使
现在耳机市场的主动式降噪就是ANC、ENC、CVC、DSP等降噪技术。ANC降噪ANC降噪(Active Noise Control,主动降噪)的工作原理是麦克风收集外部的环境噪音,然后系统变换为一个反相的声波加到喇叭端,最终人耳听到的声音是:环境噪音+反相的环境噪音,两种噪音叠加从而实现感官上的噪音降低,受益人是自己。ENC降噪ENC(Environmental Noise Cancellati...
(详情请戳上面图片链接↑↑↑)之前我们学习了怎么做方方正正的网格,但现实的产品总是奇形怪状的,怎么能在这些形体中生成网格呢?其实总体思路是一样的,我们也是要在形体之中生成单元格,然后把结构线对应到单元格里,并阵列出整个网格。生成单元格有两种方式:像素式阵列。这种方式有点像乐高,就是把一个形体里堆满方框:这种方式的优势就是,简单粗暴,任何造型都能搞定。缺点就是...缺少变化,实际使用的情况...
背景python处理大数据性能上不足,所以想着用pyspark来处理,但是前提是要有一个hadoop的分布式环境,没有现成的,那就搭一个。环境mac: 10.15.6docker: 20.10.6hadoop: 3.2.3jdk: 1.8scala: 3.1.1spark: 3.0.3项目说明在docker中集成 hadoop,spark,scala, habse(暂未更新),目前已经完成可以启动1台master,3台slave的hadoop分布式环境,接下来会继续更新安装hbase等;