输入映射和输出映射
了解概念
EJB是sun的JavaEE服务器端组件模型,设计目标与核心应用是部署分布式应用程序。简单来说就是把已经编写好的程序(即:类)打包放在服务器上执行。凭借java跨平台的优势,用EJB技术部署的分布式系统可以不限于特定的平台。EJB (Enterprise JavaBean)是J2EE(javaEE)的一部分,定义了一个用于开发基于组件的企业多重应用程序的标准。其特点包括网络服务支持和核心开发工具(SDK)。 在J2EE里,Enterprise Java Beans(EJB)称为Java 企业Bean,是Java的核心代码,分别是会话Bean(Session Bean),实体Bean(Entity Bean)和消息驱动Bean(MessageDriven Bean)。在EJB3.0推出以后,实体Bean被单独分了出来,形成了新的规范JPA。
输入参数值POJO包装类
java 序列化的概念
什么是序列化, ? 在java中,如果我在我自己的电脑上封装一个对象,然后存入内存中,这个过程叫做对象的序列化
如果我把对象发送给了张三,然后对象通过网路,存入了张三的内存中,如果张三使用和调用这个对象,就要实现java的反序列化
远程OBC调用,就要用到序列化, 牵扯到集群(多台电脑),
包装类必须实现 序列化接口
去都被隐藏在函数参数的背后了。这样子,任何类型只要实现了Serializable接口,就可以被保存到文件中,或者作为数据流通过网络发送
到别的地方。也可以用管道来传输到系统的其他程序中。这样子极大的简化了类的设计。只要设计一个保存一个读取功能就能解决上面说得
所有问题。
java的"对象序列化"能让你将一个实现了Serializable接口的对象转换成一组byte,这样日后要用这个对象时候,你就能把这些byte数
据恢复出来,并据此重新构建那个对象了。
工作流当中流程变量的几种数据类型:string integer short long double boolean date binary serializable,这就是为什么要将
javabean实现序列化的原因,因为你将对象设置到流程变量中必须要实现序列化,否则会在设置流程变量的时候报错找不到该类型
java对象序列化机制就是把内存中的Java对象(User之类的JavaBean)转换成二进制流。java对象序列化后可以很方便的存储或者在网络
中传输。Java的序列化机制是通过运行时判断类的序列化ID(serialVersionUID)来判定版本的一致性。在反序列化时,java虚拟机会通过二
进制流中的serialVersionUID与本地的对应的实体类进行比较,如果相同就认为是一致的,可以进行反序列化,正确获得信息,否则抛出序列
化版本不一致的异常。所以涉及到数据传输或者存储的类,严格意义上来说都要加上序列化ID,这也是一种良好的编程习惯。
序列号的意义 : private static final long serialVersionUID = 1L;
serialVersionUID适用于Java的序列化机制。简单来说,Java的序列化机制是通过判断类的serialVersionUID来验证版本一致性的。在进行反序列化时,JVM会把传来的字节流中的serialVersionUID与本地相应实体类的serialVersionUID进行比较,如果相同就认为是一致的,可以进行反序列化,否则就会出现序列化版本不一致的异常,即是InvalidCastException。
代码
创建包装类
package com.itheima.mybatis.pojo;
import java.io.Serializable;
public class QueryVo implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
private User user ;
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public static long getSerialversionuid() {
return serialVersionUID;
}
}
配置sqlmap .xml 配置文件
<!-- 通过包装类进行模糊查询 这里的参数用ogl 表达式-->
<select id="findUserByQueryVo" parameterType="com.itheima.mybatis.pojo.QueryVo" resultType="com.itheima.mybatis.pojo.User">
select * from user where username like "%"#{user.username}"%"
</select>
junit 测试
@Test
public void testfindUserByQueryVo(){
// 0. 记载配置文件
InputStream in = MybatisTest.class.getClassLoader().getResourceAsStream("sqlMapConfig.xml");
// 1. 创建sessionFactory 工厂类
SqlSessionFactory sf = new SqlSessionFactoryBuilder().build(in);
// 打开session
SqlSession session = sf.openSession();
// 执行sql 语句
Usermapper mapper = session.getMapper(Usermapper.class);
QueryVo queryVo = new QueryVo() ;
User user = new User() ;
user.setUsername("五");
queryVo.setUser(user);
List<User> list = mapper.findUserByQueryVo(queryVo) ;
System.out.println(list);
}
输出参数之简单类型
接口中定义
public Integer findCount();
写sqlmap.xml 配置文件
<select id="findCount" resultType="Integer">
select count(*) from user;
</select>
测试
@Test
public void testfindCount(){
// 0. 记载配置文件
InputStream in = MybatisTest.class.getClassLoader().getResourceAsStream("sqlMapConfig.xml");
// 1. 创建sessionFactory 工厂类
SqlSessionFactory sf = new SqlSessionFactoryBuilder().build(in);
// 打开session
SqlSession session = sf.openSession();
// 执行sql 语句
Usermapper mapper = session.getMapper(Usermapper.class);
Integer jj = mapper.findCount() ;
System.out.println(jj);
}
输出类型resultMap
<resultMap type="Orders" id="orders">
<!-- 只配置不一样的就行了 -->
<result column="user_id" property="userId"/>
</resultMap>
<select id="selectOrdersList" resultMap="orders">
SELECT id, user_id, number, createtime, note FROM orders
</select>
动态sql
if where
<select id="findUserBySexAndUsername" parameterType="User" resultType="User">
select * from user
<where>
<if test="sex!=null and sex!=''">
and sex=#{sex}
</if>
<if test="username != null and username != ''">
and username=#{username}
</if>
</where>
</select>
@Test
public void testfindUserBySexAndUsername(){
// 0. 记载配置文件
InputStream in = MybatisTest.class.getClassLoader().getResourceAsStream("sqlMapConfig.xml");
// 1. 创建sessionFactory 工厂类
SqlSessionFactory sf = new SqlSessionFactoryBuilder().build(in);
// 打开session
SqlSession session = sf.openSession();
// 执行sql 语句
Usermapper mapper = session.getMapper(Usermapper.class);
User u = new User() ;
u.setSex("1");
u.setUsername("eric");
List<User> users = mapper.findUserBySexAndUsername(u);
for (User user : users) {
System.out.println(user);
}
}
where 标签取出前边的and
sql片段
多吃出现相同的sql 标签片段, 使用这个方法
<!-- sql片段 -->
<sql id="selectto">
select * from user
</sql>
<!-- 根据性别和名字查询用户 where 可以去掉第一个前ANd -->
<select id="findUserBySexAndUsername" parameterType="User" resultType="User">
<include refid="selectto"></include>
<where>
<if test="sex!=null and sex!=''">
and sex=#{sex}
</if>
<if test="username != null and username != ''">
and username=#{username}
</if>
</where>
</select>
Foreach
list
<!-- 通过id 查询多个用户 -->
<select id="findUserByIDs" parameterType="QueryVo" resultType="User">
<include refid="selectto"></include>
<where>
<foreach collection="idList" item="id" open="id in(" close=")" separator="," >
#{id}
</foreach>
</where>
</select>
public List<User> findUserByIDs(QueryVo v);
@Test
public void testfindByDIs(){
// 0. 记载配置文件
InputStream in = MybatisTest.class.getClassLoader().getResourceAsStream("sqlMapConfig.xml");
// 1. 创建sessionFactory 工厂类
SqlSessionFactory sf = new SqlSessionFactoryBuilder().build(in);
// 打开session
SqlSession session = sf.openSession();
// 执行sql 语句
Usermapper mapper = session.getMapper(Usermapper.class);
List<Integer> list = new ArrayList<Integer>() ;
list.add(1);
list.add(16);
list.add(26);
QueryVo vo = new QueryVo();
vo.setIdList(list);
List<User> users = mapper.findUserByIDs(vo);
for (User user : users) {
System.out.println(user);
}
Array
<!-- 通过id 查询多个用户 -->
<select id="findUserByIDs" parameterType="QueryVo" resultType="User">
<include refid="selectto"></include>
<where>
<foreach collection="array" item="id" open="id in(" close=")" separator="," >
#{id}
</foreach>
</where>
</select>
这里的 Collection 一定要用array
一对一关联
这里我们拿 user 和order 表进行举例说明 :
一个用户可以又多个订单 many-to-many
但是一个订单只能是一个人 one-to-one
xml result 不可以省略在多表查询中,
//一对一关联 查询 以订单为中心 关联用户
public List<Orders> selectOrders();
-->
<resultMap type="Orders" id="order">
<result column="id" property="id"/>
<result column="user_id" property="userId"/>
<result column="number" property="number"/>
<result column="createtime" property="createtime"/>
<result column="note" property="note"/>
<!-- 一对一 -->
<association property="user" javaType="User">
<id column="user_id" property="id"/>
<result column="username" property="username"/>
</association>
</resultMap>
<select id="selectOrders" resultMap="order">
SELECT
o.id,
o.user_id,
o.number,
o.createtime,
u.username
FROM orders o
left join user u
on o.user_id = u.id
</select>
多对多 (one-to-many)
xml配置文件如下
<resultMap type="User" id="user">
<id column="user_id" property="id"/>
<result column="username" property="username"/>
<collection property="ordersList" ofType="Orders">
<id column="user_id" property="id"/>
<result column="number" property="number"/>
</collection>
</resultMap>
<!-- 一对多查询 -->
<select id="selectUserList" resultMap="user">
SELECT
u.id,u.address,u.birthday,u.sex,u.username,o.createtime,o.user_id
FROM USER u LEFT JOIN orders o
ON o.user_id= u.id;
</select>
一对一的话, 直接引用对方的 对象
如果是many-to-one 的话,用带有对方泛型的 集合引用
多的一方用集合
Mybatis 整合Spring
这里我们要明白, 不管是 hibernate 还是mybatis 中的sessionFactory 都是单实例 的,也就是说只有一个工厂, 但是session不能是但实例的, session 要多实例, 与线程绑定
我们整合就是让sessionFactory 交给spring 进行创建session 管理 维护session 对象 ,所谓的dao层的框架和spring 结合其实都是把ssessionFactory 和session 的创建交给spring 容器管理 ,
整合思想
1 .sqlsessionFactory 对象,应该放在spring 容器中作为单实例存在
2. 从spring 中获取多实例的 sqlsession 对象
3 .mapper 代理形式中,应该从spring 容器中获取mapper 对象,
4.数据库的链接以及事务的管理都交给spring 容器完成
Mybatis Mapper 动态代理开发
mapper 工厂创建 接口的实现类, 在spring 中,
<!-- Mapper动态代理开发 -->
<bean id="userMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">
<property name="sqlSessionFactory" ref="sqlSessionFactoryBean"/>
<property name="mapperInterface" value="com.itheima.mybatis.mapper.UserMapper"/>
</bean>
需要传递session 工厂和,接口
配置文件的书写和之前的mybatis 一样
@Test
public void test() {
// 加载spring 容器配置文件
ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
UserMapper uMapper = ac.getBean(UserMapper.class);
User user= uMapper.findUserById(29);
System.out.println(user);
}
直接扫描包
<!-- 上面的是要一个一个接口 -->
<bean id="mapperScannerConfigurer" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!-- 会自动扫面mapper包下的接口和子 包下的接口 -->
<property name="basePackage" value="com.itheima.mybatis.mapper"></property>
</bean>
Mybatis 逆向工程
1. 下载逆向工程软件, 直接从网上下载就行了, generatorSqlmapCustom 这是这个名字,
2. 配置文件配置 注意 :
这里配置文件的路径一定要写对, 不然麻烦很大
3. 直接把生成的代码 进行cope 就行了
4.书写test测试类进行测试
/**
* 用带条件的 bean 进行操作数据库
*/
@Test
public void test2(){
ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
UserMapper uMapper = ac.getBean(UserMapper.class);
// 创建 OrderExample
UserExample example = new UserExample();
// 创建条件
example.createCriteria().andSexEqualTo("1");
int co = uMapper.countByExample(example);
System.out.println("报告大王一共有:"+co);
}
/**
* 多个条件的
*/
@Test
public void test3(){
ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
UserMapper uMapper = ac.getBean(UserMapper.class);
// 创建 OrderExample
UserExample example = new UserExample();
// 创建条件
String username= "明";
example.createCriteria().andSexEqualTo("1").andUsernameLike("%"+username+"%");
example.setOrderByClause("id desc"); /*排序 */
int co = uMapper.countByExample(example);
System.out.println("报告大王一共有:"+co);
/*通过条件*/
List<User> users = uMapper.selectByExample(example);
for (User user : users) {
System.out.println(user.getId());
}
生成的 user 和 userExample userExample 就是添加条件的pojo 对象, 具体的操纵方法很简单, 自己想想就知道了, 参考上文