一,mybatis简介。
1,mybaits框架,它是一个持久层框架(主要功能是对数据库的数据进行操作)
用反射和xml封装的jdbc的框架,这个框架也是orm映射框架(orm,把数据库的每一行记录转化成一个个对象,)
2,最大的特点:缓存技术和动态sql语句。(hibernate框架)
二,mybaits的 执行过程原理。
1首先加载核心xml的文件。
2,通过记录这个核心xml文件就会得到一个sqlSessionFactroy;
3通过得到这个工厂来产生 sqlSession,这个对象本身不能来操作数据库。
4,这个对象会产生一个解析器(executor),可以得到一个mappedSstamement(是satmement的子类)对象 就可以执行sql
5,最后给我们返回数据(map ,int ,list等常规数据);
三,mybaits入门程序,初级版。
1.建立数据库:
数据库名为:smbms
2.配置xml文件,以及导包,建立pojo类。
3,在src文件中写入xml文件。
配置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">
<!-- 通过这个配置文件完成mybatis与数据库的连接 -->
<configuration>
<!--引入配置文件-->
<properties resource="database.properties"></properties>
<!--配置别名(省略前缀)-->
<typeAliases>
<!--当给你当前包下的所有类取别名,别名的名字就是你的类名-->
<!-- <package name="com.offcn.pojo"></package>-->
<!--给具体的类加上别名,type类型就是你要加完整包名加载类名,alias就是你要的别名 -->
<typeAlias type="com.offcn.pojo.User" alias="user"></typeAlias>
</typeAliases>
<!--开始配置环境,可以配置多个环境包括mysql,oracle-->
<!--default里面任意取,官网是development-->
<environments default="development">
<environment id="development">
<!--事务,用jdbc的事务来进行管理-->
<transactionManager type="JDBC"></transactionManager>
<!--设置数据源(jndi{tomcat容器分配的数据源}jdbc,c3p0都是数据源,pooled{是mybaitis自带的数据源})-->
<dataSource type="POOLED">
<property name="url" value="${url}"></property>
<property name="driver" value="${driver}"></property>
<property name="username" value="${username}" ></property>
<property name="password" value="${password}"></property>
</dataSource>
</environment>
</environments>
<!--与你的userMapper进行关联,resource,这个可以配置多个,resourse代表其多个,这里的.都换成/-->
<mappers>
<!-- //第一版-->
<mapper resource="com/offcn/dao/UserMapper.xml"></mapper>
<mapper resource="com/offcn/dao/AddressMapper.xml"></mapper>
</mappers>
</configuration>
4.建立与数据库对应的pojo,提供get,set方法。有参,无参,toString。
5.在package中写入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 相当于包,包管理器-->
<mapper namespace="com.offcn.dao.UserMapper"></mapper>
在mapper中间,写对应的方法,
此方法是查找对应user的人数。
<!--id都是唯一的,是你访问的一个标识符,查询总记录数-->
<!--resultType 代表返回值类型,后面不要加分号-->
<select id="selectCount" resultType="int">
select count(1) from smbms_user
</select>
6.建立test类。
@Test
public void test1(){
try {
//读取核心文件
String path="mybatis-config.xml";
//得到一个输入流对象
InputStream is=Resources.getResourceAsStream (path);
//得到一个sqlsessionfactroy
SqlSessionFactory ssf=new SqlSessionFactoryBuilder ().build (is) ;
//通过SqlSessionFactory 得到sqlsession
SqlSession sqlSession =ssf.openSession ();
//返回一列,就调用selectOne
int num= sqlSession.selectOne ("com.offcn.dao.UserMapper.selectCount");
System.out.println (num);
} catch (IOException e) {
e.printStackTrace ();
}
}
初级版,并没有对SqlSession进行封装和单例模式运行。
所以可以对此部分进行封装。
7.在util包中写SqlSessionUtils类,进行封装SqlSession。
//得到SqlSession的工具类
public class SqlSessionUtils {
protected static SqlSessionUtils sqlSessionUtils;
public SqlSession sqlSession;
//无参构造读取核心配置文件
private SqlSessionUtils() {
try {
String path="mybatis-config.xml";
InputStream is=Resources.getResourceAsStream (path);
SqlSessionFactory ssf=new SqlSessionFactoryBuilder () .build (is);
sqlSession=ssf.openSession (true);
} catch (IOException e) {
e.printStackTrace ();
}
}
// synchronized 第一个是锁住方法(死锁)保证只有一个线程能进入这个方法
public static synchronized SqlSessionUtils getSqlSessionUtils(){
if(sqlSessionUtils==null){
//锁类的原因:在java jvm实例化 对象(有四个步骤),避免当走到第一个步骤的时候,另外一个线程new新的对像
// 永远保证只有一个这样的类
synchronized (SqlSessionUtils.class){
if(sqlSessionUtils==null){
sqlSessionUtils=new SqlSessionUtils ();
}
}
}
return sqlSessionUtils;
}
}
8.用封装方法测试。
测试模糊查询,在UserMapper.xml.中写一个模糊查询的方法。
<!--模糊查询-->
<!-- parameterType这个表示参数类型,#{userName}这个代表我们以前的?也就是占位符,模糊查询一定要加concat-->
<select id="selectLikeUser" resultType="com.offcn.pojo.User" parameterType="String">
select * from smbms_user where userName like concat('%',#{userName},'%')
</select>
新test:
@Test
public void test3(){
try {
SqlSession sqlSession = SqlSessionUtils.getSqlSessionUtils ().sqlSession;
List<User> list= sqlSession.selectList ("com.offcn.dao.UserMapper.selectLikeUser","张");
for (User u:list
) {
System.out.println (u.getUserName ());
}
} catch (Exception e) {
e.printStackTrace ();
}
}
封装SqlSession保证了单例运行,测试更简洁,安全。
四,mybatis与dao开发之注解版。
注解版需要用到 mybatis-3.4.6.jar
的版本以上
1.先写入dao接口,在接口中通过注解写入对应增删改查方法,从而不通过
UserMapper.xml。
@Mapper
public interface AddressMapper {
/*注解的方法必须要删除对应的xml*/
@Select ("select * from smbms_address where contact like concat('%',#{contact},'%')")
List<Address> selectLikeAddress(String contact);
}
2.在***mybatis-config.xml***中
<!--这里直接点 不需要斜杠、-->
<mapper class="com.offcn.dao.UserMapper"></mapper>
<mapper class="com.offcn.dao.AddressMapper"></mapper>
3.其他在text用法与初级版相同。
五,mybatis与dao开发之最终版。
最终版的核心执行过程:
1.首先加载xml 文件。
2.得到sqlSession
3,通过sqlSession 得到接口类,
4.调用其方法时 会走到相应的usermapper。xml文件里
5.然后执行sql语句,返回结果集
完整步骤:
1.pojo,xml配置不变。
在xml中mapper为这种方式:
<mapper resource="com/offcn/dao/UserMapper.xml"></mapper>
<mapper resource="com/offcn/dao/AddressMapper.xml"></mapper>
</mappers>
2.写对应dao接口。
此例子为address
public interface AddressMapper {
//修改接口
int updateAddress(Address address);
//删除接口
int delectAddress(int id);
//增加信息接口
int insertAddress(Address address);
//模糊查询接口
List<Address> selectLikeAddress(String contact);
}
以上接口中 返回值为int,返回一说明数据库中改变的行数为1,也说明方法使用成功,模糊查询中 返回值为list。
3.dao接口,写对应的Mapper.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 相当于包,包管理器-->
<mapper namespace="com.offcn.dao.AddressMapper">
<!--通过address里id,修改信息-->
<!--id都是唯一的,是你访问的一个标识符,查询总记录数,id要与dao里的接口一一对应-->
<!--resultType 代表返回值类型,后面不要加分号-->
<!--根据id修改名字,返回值类型不需要-->
<!--contact是对应数据库的列,#{contact}对应的是java实体bean,建议与数据库的属性一一对应-->
<update id="updateAddress" parameterType="com.offcn.pojo.Address">
update smbms_address set contact=#{contact},addressDesc=#{addressDesc} where id=#{id}
</update>
<!--通过id删除对应信息-->
<delete id="delectAddress" parameterType="int">
delete from smbms_address where id=#{id}
</delete>
<!--增加信息-->
<insert id="insertAddress" parameterType="com.offcn.pojo.Address">
insert into smbms_address (contact,addressDesc) values (#{contact},#{addressDesc})
</insert>
<!--模糊查询-->
<select id="selectLikeAddress" parameterType="String" resultType="com.offcn.pojo.Address">
select * from smbms_address where contact like concat('%',#{contact},'%')
</select>
</mapper>
4.测试。
修改方法测试:
@Test
public void test12(){
SqlSession sqlSession = SqlSessionUtils.getSqlSessionUtils ().sqlSession;
Address address=new Address ();
address.setId (1);
address.setContact ("王");
address.setAddressDesc ("成都");
sqlSession.getMapper (AddressMapper.class).updateAddress (address);
}
删除方法测试:
@Test
public void test13(){
SqlSession sqlSession = SqlSessionUtils.getSqlSessionUtils ().sqlSession;
sqlSession.getMapper (AddressMapper.class).delectAddress (1);
}
增添方法测试:
@Test
public void test14(){
SqlSession sqlSession = SqlSessionUtils.getSqlSessionUtils ().sqlSession;
Address address=new Address ();
address.setContact ("x");
address.setAddressDesc ("beijing");
int num= sqlSession.getMapper (AddressMapper.class).insertAddress (address);
System.out.println (num);
}
模糊查询测试:
@Test
public void test15(){
SqlSession sqlSession = SqlSessionUtils.getSqlSessionUtils ().sqlSession;
List<Address> list= sqlSession.getMapper (AddressMapper.class).selectLikeAddress ("李");
for (Address a:list
) {
System.out.println (a.getContact ()+"\t"+a.getAddressDesc ());
}
}
小结:
parameterType指指定输入参数的java类型。
resultType指指定输出结果的java的类型。
#{},${}
#{}相当于预处理中的占位符,在#{}里面的参数表示接受java输入参数的名称。
#{}可以接受hashMap,简单类型,pojo类型的参数。
当接受简单类型的参数时,#{}里面可以是value,也可以是其他。
#{}可以防止sql注入。
${}:相当于拼接sql串,对传入的指不做任何解释的原样输出。
${}会引起sql注入,所以要谨慎使用。
${}可以接受hashMap,简单类型,pojo类的参数
当接受简单类型的参数是, ${}里面只能是value。
selectOne 和selectList;
selectOne只能查询0或1条记录,大于1会报错。
六,mybatis-config.xml系统核心配置文件
1.严格按照图中顺序,顺序错会报错。
2.引入配置文件。
<!--引入配置文件-->
<properties resource="database.properties"></properties>
3.配置别名(省略前缀)。
<typeAliases>
<!--当给你当前包下的所有类取别名,别名的名字就是你的类名-->
<package name="com.offcn.pojo"></package>
<!--给具体的类加上别名,type类型就是你要加完整包名加载类名,alias就是你要的别名 此方法与上面二选一,不能同时。-->
<typeAlias type="com.offcn.pojo.User" alias="user"></typeAlias>
</typeAliases>