什么是mybatis
mybatis原本是apache的一个开源项目,后来被谷歌收购了,是一个基于java的持久层框架
ORM(Object-Relationship-Mapping) 对象关系映射,编程思想的一种,将数据库中的字段用对象的形式表现出来
JPA(Java-Persistence-API):是java持久化接口的意思,基于ORM思想的一套接口,不是具体实现
API(Application Programming Interface):应用程序编程接口,类似工具类,是已经定义好的类,由应用层程序员使用。
Mybatis配置
配置文件:用来连接数据库 以及引用映射文件
<configuration>
<environments default="mysql">
<environment id="mysql">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/jdbc"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="com/oracle/mapper/UserMapper.xml"/>
</mappers>
</configuration>
映射文件:用来映射数据库的实体类 这里的映射文件直接代替了dao
<mapper namespace="com.oracle.mapper.UserMapper">
<select id="findUserById" resultType="com.oracle.beans.User" parameterType="Integer">
select * from user where id =#{id}
</select>
</mapper>
namespace是工作空间 session使用的时候要写namespace+id (是绝对命名)
但是没有重名ID的情况下,可以直接使用Id(端命名)
持久化层执行操作:
用配置文件创建sqlSessionFactory工厂
String resource=”mybatisConfig.xml”;
InputStream ins = Resources.getResourceAsStream(resource);
SqlSessionFactory sessionFactory = New SqlSessionFactoryBuilder().build(ins);
SqlSession session = sessionFactory.openSession();
用session执行操作
User user = Session.selectOne(“findUserById”,2);
Syso(user);
但是这样写有缺陷,就是在执行selectOne()方法时,编译器不确定你要传值的类型
于是就用到了通过接口代理
写一个接口,然后把工作空间改成这个接口
public interface UserMapper {
public User findById(int id);
}
<mapper namespace="com.oracle.mapper.UserMapper">
<select id="findUserById" resultType="com.oracle.beans.User" parameterType="Integer">
select * from user where id =#{id}
</select>
</mapper>
然后用session获取这个映射,获取映射需要反射这个接口代理
UserMapper mapper = Session.getMapper(UserMapper.class);
User user = Mapper.findById(1);
这就避免了传异常类型的
还有更简单的方法,那就是使用注释
@Select(“select * from user);
Public List<User> allUser();
在代理接口方法上写注释,直接写sql语句
映射里面什么都不用写,加上命名空间就可以
配置文件中的标签:
setting标签:可以设置很多东西
比如说数据为空的时候显示的什么
<settings>
<setting name="jdbcTypeForNull" value="NULL"/>
还有很多
</settings>
详情看文档
一个配置完整的 settings 元素的示例如下:
<settings>
<setting name="cacheEnabled" value="true"/>
<setting name="lazyLoadingEnabled" value="true"/>
<setting name="multipleResultSetsEnabled" value="true"/>
<setting name="useColumnLabel" value="true"/>
<setting name="useGeneratedKeys" value="false"/>
<setting name="autoMappingBehavior" value="PARTIAL"/>
<setting name="autoMappingUnknownColumnBehavior" value="WARNING"/>
<setting name="defaultExecutorType" value="SIMPLE"/>
<setting name="defaultStatementTimeout" value="25"/>
<setting name="defaultFetchSize" value="100"/>
<setting name="safeRowBoundsEnabled" value="false"/>
<setting name="mapUnderscoreToCamelCase" value="false"/>
<setting name="localCacheScope" value="SESSION"/>
<setting name="jdbcTypeForNull" value="OTHER"/>
<setting name="lazyLoadTriggerMethods" value="equals,clone,hashCode,toString"/></settings>
还有typeAliases ,这个很重要,比较常用,起别名用的
<typeAliases>
<typeAlias type="com.oracle.beans.User" alias="user"/> 写完这个映射文件里面就不用写user的全类名了,别名就可以了
<package name="com.oracle.beans"/> 这是注解起别名,扫描范围
注解起别名默认不写就是类名首字母小写,写了就是@Aliases(“别名”)
</typeAliases>
映射文件也可以不用挨个写,加个扫描就行了
<package name="com.oracle.mappers"/>
Update
添加
Public int addUser(User user);
映射文件: 添加用insert标签
<insert id="addUser" parameterType="com.oracle.beans.User" >
insert into user (name,password) values (#{name},#{password})
</insert>
删除和修改
public boolean updateUser(User user);
映射文件:删除用delete标签
<delete id="deleteById" parameterType="Integer">
delete from user where id = #{id}
</delete>
修改也是一样的道理:update操作的返回值类型不用在标签中定义,使用默认的三种。
Boolean、int、long。
主键自动添加:
主键正常就已经能自动添加了,但是还是要在values前面写没有id属性的那几个字段,如果字段多的话就会很麻烦。
所以我们使用主键自增
public boolean addUserGeneral(User user);
<insert id="addUserGeneral" parameterType="com.oracle.beans.User" useGeneratedKeys="true" keyProperty="id">
原来的; insert into user (name,password) values (#{name},#{password})
设置之后:insert into user values (#{id},#{name},#{password})
</insert>
设置useGeneratedKeys=”true” KeyProperty设置主键
多参数:
写多参数需要在参数前面加上@Param(“参数名”)
public List<User> findByNameAndTable(@Param("table")String table,@Param("name")String name);
配置文件不需要写参数,其他正常写。
<select id="findByNameAndTable" resultType="user">
select * from ${table} where name= #{name}
</select>
键值对参数:
public List<User> findByMap(Map<String,Object> user);
<select id="findMapResult" resultType="map"> map有框架自带的别名,不用自己写
select id,name,password from user where id= #{id}
</select>
返回值是map类型的:
public Map<String,Object> findMapResult(int id);
<select id="findMapResult" resultType="map">
select id,name,password from user where id= #{id}
</select>
查询出来的结果:{ name=寡姐1, password=12345}
但是呢,你不知道查出来的这个是哪条,因为不显示
要在接口方法上加@MapKey("id")
输出结果:{9={id=9, name=寡姐1, password=12345}}
${} 用来写类名之类的,就是那种正常写了会报错的,用处类似与拼接字符串
还有
比较符转义
select * from user where id < #{id} and name=#{name}
在配置文件中写这句话运行会报错,因为< 和标签的左括号冲突了,要转义才行。
select * from user where id > #{id} and name=#{name}
转义符:
< < 小于号
> > 大于号
& & 和
' ' 单引号
" " 双引号
Mybatis 表关联查询
表关联查询通过设置结果集:
这是一个普通的bean
<select id="findStudentById" resultType="student">
select * from student where id=#{id}
</select>
改成一对一关联查询:
在结果集里面配置返回的类型:
<resultMap type="student" id="studentAddClass">
<id column="id" property="id"/>
<result column="name" property="name"/>
<result column="password" property="password"/>
配置一对一的对象
<association property="clazz"
select="com.oracle.mappers.ClassMapper.findClassById" 获取对象执行的方法
column="cid">参数
<id column="cid" property="cid"></id>
<result column="teacher" property="teacher"/>
<result column="score" property="score"/>
</association>
</resultMap>
一对多关联查询:
<resultMap type="clazz" id="clazzAndStudent">
<id column="cid" property="cid"/>
<result column="teacher" property="teacher"/>
<result column="score" property="score"/>
一对多里面的集合属性用conllection,类型用ofType
<collection property="stu" ofType="student" column="cid" select="com.oracle.mappers.StudentMapper.findStudentsByClass">
<id column="id" property="id"/>
<result column="name" property="name"/>
<result column="password" property="password"/>
</collection>
</resultMap>
<select id="findClassById" resultMap="clazzAndStudent">
select * from class where cid=#{cid}
</select>